# Infra register — CI / build-pipeline debt

Operator-ruled 2026-08-02: infrastructure and CI-pipeline work items live HERE, not on the
`spt-bs-releases` board. The board carries product surface the operator triages; this register
carries what the gater triages. **Mandate: doyle sweeps this file at every milestone intake and
every release close, and composes ripe entries into waves/milestone riders.** An entry leaves
this file only by being built (link the lane) or being retired with a stated reason.

Entry format: status · origin · what/why · trigger condition (what makes it ripe) · size guess.

Last sweep: 2026-08-03, LOCKSMITH (#132) intake — composed IR-16 (product lane) + CI-rider
cluster (IR-1/IR-4/IR-9; IR-5/IR-6 conditional on gate-script touch) + the IR-19 gate-read;
IR-18's acceptance carrier named (#132 Phase A golden). All other entries reviewed; triggers
unmet (IR-2 needs a quiet between-milestone window, IR-14 an idle window, IR-17 its next
signature, IR-3/IR-7/IR-8/IR-10/IR-11/IR-12/IR-13/IR-20 their named waves).

---

## OPEN

### IR-1 — Quiet predicate needs a network axis (tailscale RTT probe)
- **Status:** open · **Origin:** golden/bench-wiring red triage 2026-08-02 (ex releases#126)
- **What/why:** the shared-runner quiet predicate (zero non-terminal runs + no local
  cargo/rustc/nextest by parent chain) is process-shaped; both axes passed on a box whose only
  link was degrading (321s for a 1s checkout, bidirectional 10s QUIC dial timeouts). A tailscale
  RTT probe to the peer box before two-host rendezvous, carried in the bench ledger, would have
  called run 30771155390's red in seconds. Evidence: the arm-1 count table (PUMP_PEER_FAIL
  a 0→3→0, b 8→22→8 across green/red/rerun).
- **Permanent, not stopgap:** operator-confirmed 2026-08-02 that kitsubito cannot be provided
  ethernet — wifi-only indefinitely, so the link cannot be hardened and the predicate must see
  link health.
- **Ripe when:** next CI-touching wave, or the next network-shaped golden red — whichever first.
- **Size:** small (one probe step + ledger row + predicate doc).
- **Composed:** LOCKSMITH (#132) CI-rider cluster, hertz thin lane — 2026-08-03. GREENLIT with
  #132 and **DISPATCHED to hertz 2026-08-03** (direct brief; the register is the spec, there is no
  board issue). Leaves the register only when the lane lands or the entry is retired.

### IR-2 — Settle the warm-runner CARGO_INCREMENTAL delta
- **Status:** open · **Origin:** #103/#108 bench-wiring lane 2026-08-02 (ex releases#127)
- **What/why:** the #103 measurement (−29.8% wall, −5.65 GB/target, n=3) is COLD-build only.
  Golden's runner `_work` target persists warm, where incremental is exactly what keeps it cheap;
  CARGO_INCREMENTAL=0 was applied only to the genuine cold build (n1-gate pinned old-broker
  cache) + local rig recipes (docs/GOLDEN-CI.md). Open question: does incremental still pay on
  the warm runner, weighed against 5.65 GB/target on a box with LNK1318 free-space history?
- **Method (hertz):** one full golden each way on a quiet box, outside a milestone, compared
  per-step from the bench ledger.
- **Ripe when:** a quiet between-milestone window with no queued lanes (the measurement burns
  two golden windows).
- **Size:** medium (two proving runs + verdict + possible leg flips).

### IR-3 — Daemon-level guard: broker-net wakeup rate bounded across endpoint churn
- **Status:** open · **Origin:** releases#125 remediation, todlando REQ call 1 (ex releases#128)
- **What/why:** the swarm-discovery GC-spin burned two cores for two weeks visible only in a
  process table — no suite assertion sees the class. Wanted: a daemon-level assertion that
  broker-net workers stay quiescent across repeated endpoint create/destroy churn.
- **Design constraint (pre-ruled):** assert on WAKEUP RATE / voluntary ctxt-switch delta over
  the churn window, NOT %CPU — CPU thresholds flake under CI load; the defect signature
  (~100 Hz per orphan loop) is load-independent. Mint the REQ at activation.
- **Near-product:** this is runtime-defect visibility, the most product-adjacent entry here —
  a candidate rider on any daemon-lifecycle milestone.
- **Ripe when:** the next milestone touching spt-net endpoint lifecycle or daemon supervision.
- **Size:** medium (churn harness + counter plumbing + flake-safe assertion).

### IR-4 — Lock-pin guard + lock-procedure rule + toolchain print (three riders, one lane)
- **Status:** open · **Origin:** releases#125 fix-lane intake hold (ex releases#129 + riders)
- **What/why, three parts that land together:**
  1. **xtask check leg:** assert Cargo.lock resolves swarm-discovery to git rev
     `89a2200d54a4e3cab2f46cc75ebff49a1fb07614` while the patch is load-bearing; the check's
     message states its own drop condition (upstream ships a post-PR#27 release AND iroh's pin
     reaches it). Without it, stanza removal or a routine iroh bump silently returns the lock to
     the spinning crate and nothing reds.
  2. **Procedure rule for lock-touching lanes** (docs): targeted `cargo update -p <crate>` only,
     never full re-resolve; count changed `[[package]]` blocks AND diff per-block edges (set-identical
     hid 8 windows-sys edge movers at acaaa4f); two resolutions disagreeing = toolchain drift —
     stop and compare against CI before shipping either lock; hand-edited lock acceptable iff
     `cargo check --workspace --locked` passes.
  3. **Toolchain-version print step in golden** (cargo/rustc versions, both OS legs): the acaaa4f
     comparison against CI was impossible because no run log prints a version. One-grep audit.
- **Ripe when:** next CI-touching wave; part 1 sooner if any iroh bump is proposed.
- **Size:** small-medium (one xtask leg, one docs section, one workflow step).
- **Composed:** LOCKSMITH (#132) CI-rider cluster, hertz thin lane — 2026-08-03. GREENLIT with
  #132 and **DISPATCHED to hertz 2026-08-03** (all three parts land together).

### IR-5 — Shared nextest summary parser
- **Status:** open · **Origin:** BAROMETER triage (standing recommendation, pre-register)
- **What/why:** two agents in one day wrote `[0-9]+ tests run` parsers that read "1 test run"
  (singular) as zero — a guard fed by a broken parser condemns valid rounds. One shared,
  singular-aware parser (single-source discriminant) for every consumer of nextest summaries.
- **Ripe when:** next wave touching any gate script that reads nextest output.
- **Size:** small.
- **Composed:** LOCKSMITH (#132) CI-rider cluster, CONDITIONAL — lands iff the hertz thin lane
  touches gate scripts; otherwise stays open here. 2026-08-03. Carried in hertz's 2026-08-03
  dispatch brief as a **conditional** rider; hertz reports whether the condition fired. **Not yet
  known to be building** — an unreported condition leaves this entry open, not landed.

### IR-6 — Membership logging on subnet gates
- **Status:** open · **Origin:** BAROMETER triage (standing recommendation, pre-register)
- **What/why:** counts beside results, membership beside counts — gate logs that state a count
  without naming the population keep producing unreadable reds. Standardize membership
  enumeration in gate output.
- **Ripe when:** next wave touching gate scripts / CI legs that report counts.
- **Size:** small.
- **Composed:** LOCKSMITH (#132) CI-rider cluster, CONDITIONAL — lands iff the hertz thin lane
  touches gate scripts; otherwise stays open here. 2026-08-03. Carried in hertz's 2026-08-03
  dispatch brief as a **conditional** rider; hertz reports whether the condition fired. **Not yet
  known to be building** — an unreported condition leaves this entry open, not landed.

### IR-7 — Phase A rigs leak a daemon+brain pair on Windows (exe-lock kills notify relink)
- **Status:** open · **Origin:** BAROMETER post-publish triage (ex releases#124 — full mechanism on the closed issue)
- **What/why:** two Phase A rigs launch daemons that escape the job object via WMI-rung autostart
  (double-space unquoted cmdline fingerprint; SPT_HOME in the wrapper cmdline is the attribution
  key); the leaked pair holds target/debug/spt.exe and kills every golden job reaching the notify
  relink. CI reaps as tourniquet (fa6e597); in-job test launch is the fix.
- **Ripe when:** next wave touching the Phase A rigs or daemon autostart path.
- **Size:** medium.

### IR-8 — reap-census scoped_survivors=0 is blind to unreadable-path holders
- **Status:** open · **Origin:** BAROMETER triage (ex releases#122)
- **What/why:** a zero that cannot see is not a zero — census scoping skips procs whose exe path is
  unreadable, so the survivors count can report clean while a holder lives. Needs a positive control
  / explicit unreadable bucket in the verdict line (unreadable_path count exists; the ZERO must
  refuse when it is nonzero).
- **Defining specimen (golden 30782259675, hfenduleam test job, 2026-08-03):**
  `CI-REAP summary: killed=5 kill_failed=1 scoped_survivors=0` — an admitted kill failure printed
  beside a zero-survivors claim on the same verdict line. The held image surfaced one step later:
  run-scoped tmp cleanup denied 5/5 attempts on `...\relshell\svcmock.exe` (2nd appearance of the
  svcmock hold; 1st @7a3c08c, pre-kill-auth). hertz's addendum: an image-held survivor also blocks
  WRITES to the exe path — the same class manufactures build/relink access-denied reds that mask as
  build problems, not just cleanup warnings. Not per-run: the same-sha green rerun's leg read
  `kill_failed=0 scoped_survivors=0` throughout (hertz, 30784469908) — intermittent sighting,
  second of its class, not a deterministic fixture property.
- **Ripe when:** next census/reap script wave (natural pair with IR-7's lane).
- **Size:** small.

### IR-9 — Golden boxes run different clippy versions
- **Status:** open · **Origin:** BAROMETER (ex releases#121); re-confirmed on the #125 fix lane
  (builder's Windows clippy vs kitsubito's rust-1.96.0 lints)
- **What/why:** a Windows-clean lane can land a lint that only reds on the Linux leg — toolchain
  skew makes local clippy evidence non-transferable. Align versions or declare the authoritative
  leg. Natural companion to IR-4's toolchain-version print step.
- **Ripe when:** with IR-4, or the next toolchain bump.
- **Size:** small.
- **Composed:** LOCKSMITH (#132) CI-rider cluster (rides IR-4's toolchain-version print step) —
  2026-08-03. GREENLIT with #132 and **DISPATCHED to hertz 2026-08-03**.

### IR-10 — Wave gate runs the CONSUMERS of any predicate it changes
- **Status:** open · **Origin:** BAROMETER gate craft (ex releases#119)
- **What/why:** legs chosen from changed crates miss the predicate's callers; a composed red is
  triaged at the wave's own tip first. This is the gate-population rule made binding in the gate
  runbook + scripts rather than living in memory.
- **Ripe when:** next gate-runbook/docs wave.
- **Size:** small (docs + gate-script checklist).

### IR-11 — find-cwd-holders.ps1: --headless discriminator as a column
- **Status:** open · **Origin:** worktree-pin triage tooling (ex releases#118)
- **What/why:** the holder-triage script buries the headless-vs-interactive discriminator in prose;
  as a column it makes the orphan-vs-own-shell call one glance.
- **Ripe when:** any rig-tooling wave; trivial rider.
- **Size:** tiny.

### IR-12 — xtask contract-drift gate misses a stale manifest.schema.json
- **Status:** open · **Origin:** ex releases#116
- **What/why:** xtask check passes while the checked-in schema artifact is stale — the drift gate
  covers generated docs but not the schema. Adapters consume that artifact blind (DRI protocol),
  so staleness ships a wrong public contract silently. Gate must regenerate-and-compare the schema
  like the docs bundle.
- **Ripe when:** next xtask/docs-gate wave; elevated if any manifest change is proposed.
- **Size:** small.

### IR-13 — Test-soundness follow-ups from the uniform-table sweep
- **Status:** open · **Origin:** ex releases#58
- **What/why:** candidate unsound tests found by the uniform-table sweep, UNVERIFIED — each must be
  mutation-proofed (break the code, watch the test) before any fix, else we "fix" tests that were
  sound. List on the closed issue.
- **Ripe when:** a hertz test-hardening wave.
- **Size:** medium (per-test verification loop).

### IR-14 — .worktrees audit: "how many worktrees are there" has four defensible answers, and the difference is not junk
- **Status:** open · **Origin:** ex releases#56 (was flag: NEEDS-OPERATOR in eval — operator input
  now sought directly when the entry ripens, not via board flag)
- **What/why:** the project `.worktrees/` dir accumulates content beyond what git tracks; audit +
  reap recipe + a hygiene rule for lane close-out. Teardown discipline per docs and memory (classify
  before delete, outbound links first).
- ⚠ **The header of this entry previously read "14 untracked orphan dirs vs 25 git-tracked". Both
  numbers were stale AND UNDATED**, so nobody could tell drift from error. Every count below is dated
  and carries its command.

#### THE COUNT DISAGREEMENT IS THE FINDING (measured 2026-08-03, todlando + doyle, main @`3efd7e6`)

Three people measuring "the worktrees" got three answers. None was wrong; they answered three
different questions, and nothing in the tree states which one is meant:

| answer | question it actually answers | command |
|---|---|---|
| **73** | all ENTRIES under `.worktrees/` | `ls -A .worktrees \| wc -l` |
| **52** | DIRECTORIES under `.worktrees/` | `ls -dA .worktrees/*/` |
| **38** | registered worktrees INCLUDING the root checkout | `git worktree list` |
| **37** | registered worktrees under `.worktrees/` | above, minus the root |

**52 − 37 = 15 unregistered directories.** The 73 − 52 = **21 loose FILES** are covered below.

**A count is only as good as its question.** Treat "how many worktrees" as under-specified until the
answer names its population — the same defect that made a naive `grep -rn` from the project root
inflate a code count by **34.9×** (426 tracked `.rs` vs 14865 on disk excluding all `target/`), and
made that grep run past 120s while `git ls-files | xargs grep` returned instantly. **Scan roots and
population definitions are the same class of error.** Use `git grep` / `git ls-files` for tracked
content and `git worktree list --porcelain` for worktrees.

#### THE 15 UNREGISTERED DIRECTORIES ARE FOUR DIFFERENT KINDS OF THING

⛔ **CLASS A — LIVE BUILD POOLS, NOT ORPHANS. DO NOT DELETE.** 3 dirs, 13.2 GB. Each is the TARGET of
a junction that a REGISTERED worktree uses as its `target/`:

| dir | inbound junction from | size | claim |
|---|---|---|---|
| `gate-target` | assembly-doorbell, doorbell-w1, doorbell-w2, doorbell-w3 | EMPTY | none |
| `gate-target-render` | golden-render | 5.84 GB | `POOL-OWNER.json` → golden-render |
| `gate-target-w4doc` | w4-cli-doc | 7.36 GB | none |

**These are exactly the directories that read as obviously junk** — no `.git`, no source, leftover
names — and deleting one destroys a registered worktree's build pool and leaves a dangling junction.
**Polarity was checked BEFORE classification, which is what caught it:** all 15 top-level dirs are
REAL directories, none is itself a reparse point; the six junctions are **INBOUND**, at
`<registered-worktree>/target`. See [[worktree-target-junction]], [[gate-worktree-target-disk]].

Two findings inside class A, neither of them a deletion question:
- **`gate-target` has FOUR registered trees junctioned into ONE pool, with no `POOL-OWNER.json` at
  all** — so nothing would refuse a second LIVE lane there. That is releases#103's exact hazard
  sitting armed. The pool is also empty: someone reclaimed it and left four junctions aimed at a hole.
- **`gate-target-render`'s `POOL-OWNER.json` carries only `owner_tree` and `written_by` — no pid and
  no birth stamp.** A claim that cannot distinguish a live lane from a finished one is missing the one
  property the claim mechanism exists to provide.

**CLASS B — EMPTIED SKELETONS, ONE UNIFORM SHAPE.** 8 dirs, **0 files**: `acl-core`, `engine-room`,
`ff-fastfollow`, `gate-23d5ceb`, `gate-ff`, `golden-a`, `golden-b`, `w2b-sender-stamp`. Every one is
exactly `crates/spt-daemon/` and nothing else. **Eight independent removals stopping at the SAME
relative path is a mechanism, not litter.**

**MECHANISM CORROBORATED LIVE, 2026-08-03:** a read-only PEB sweep of process CWDs during a running
`spt-daemon` suite found ~20 processes — `spt_daemon-<hash>` test harnesses, `PING`, `cmd` — whose
CWD was **exactly `<worktree>/crates/spt-daemon/`**, the precise path all eight skeletons froze at. A
`git worktree remove` racing a straggler there deletes everything else and leaves that chain pinned.
The processes churn fast (all 17 sampled pids were gone within 30s, one already showing **pid reuse**
— see [[pid-reuse-across-reboot]] for why a pid alone is never an identity), so the pin is a race, not
a steady state, and it recurs on every daemon-suite worktree.

**CLASS C — FULLY EMPTY, no inbound junction.** 3 dirs, 0 bytes: `gate-41`, `gate-559632e`,
`release-runbook-main-advance`. Class B with even the chain gone.

**CLASS D — DELIBERATE SCRATCH, NOT RESIDUE.** 1 dir, 12 files, 50 KB: `_patches` — three `.patch`
files with their `.untracked` manifests, plus `ir18-gate-logs/`. Modified the day before the audit,
i.e. someone's working state.

3 + 8 + 3 + 1 = 15.

#### PIN STATE: NO SKELETON IS HELD TODAY (with a stated blind spot)

Read-only PEB CWD sweep, 2026-08-03: **zero processes hold a CWD in any class-B or class-C
directory** — every live pin was in `gate-ec5f38a` and `gate-main`, both REGISTERED and both running
rigs at the time. So removal of B and C would succeed today; nothing is retrying it.

⚠ **The sweep read 412 of 593 processes; 181 were unreadable** (elevated/system, no
`PROCESS_VM_READ`). The no-pin result therefore holds over the READABLE population only. Cheap to
re-run elevated before acting — [[absence-needs-sibling-probe]].

#### THE LOOSE FILES: A SHARED LOCATION WITH NO STATED CONTRACT

**21 loose files sit in `.worktrees/`** — gate logs (`gate-*.log`, `gate-559632e-log.txt`), rig
scripts (`g6-curve.ps1`, `g6-postbounce.ps1`, `gate-w5-*.ps1`), and `gate-w5-notes.md`. **Nobody
declared `.worktrees/` a log drop; it became one.** Same class as the memory index: a shared location
with no stated contract accumulates whatever anyone puts there, and **the first person to tidy it
cannot tell residue from someone's working state** — class D is that risk already realised. The
hygiene rule this entry owes should name where gate logs and rig scripts belong, not only how to reap
worktrees.

#### RECLAIM ARITHMETIC — AND WHY THIS ENTRY IS NOT THE DISK FIX

Classes B, C and D together are **under 51 KB**. All 13.2 GB of the unregistered population is class
A, behind live junctions. **An orphan sweep is not a disk-space remedy**, and reading it as one sends
you at the wrong target: on the audit date, free space was **12.5 GB against the 32 GB golden floor**
([[free-space-floor-blocks-golden]]) while the two largest pools on the box were `gate-ec5f38a/target`
(14.33 GB) and `gate-main/target` (28.12 GB) — **both REGISTERED, so both outside the orphan
population entirely.** The disk question and the orphan question have different populations; answering
one correctly says nothing about the other.

- **Ripe when:** between-milestone idle window (it is a dev-box chore, zero product risk) — but the
  class-A pool findings are armed hazards and do not wait for it.
- **Size:** small for the sweep; the hygiene rule and the pool-claim gaps are separate small items.

### IR-17 — Deadline-burn bring-up family: a test burns its full window while the daemon/brain never comes up
- **Status:** open · **Origin:** golden 30782259675 red triage 2026-08-03
- **What/why:** two different tests on two runner hosts now share one signature — bring-up misses
  its ONLINE window under leg load and the test burns its ENTIRE deadline before the PRECONDITION
  panic: `spt::resident_service_e2e::a_declared_service_rises_with_the_daemon_and_reaches_the_cli`
  (hfenduleam, FAIL 123.99s, "PRECONDITION: the daemon never came up", run 30782259675, green on
  same-sha rerun 30784469908) and `spt::activity_link_push_e2e` (kitsubito, full 30s, brain stderr
  EMPTY — broker spawned, brain never emitted, run 30607903133 specimen, green on same-sha rerun;
  **the empty-stderr leg of THIS sighting is UNVERIFIED-BY-NEGATIVE-CONTROL** — nobody has checked
  whether that test's brain writes stderr on a passing run, and the resident_service twin of this
  observation was retracted for exactly that; cheap to settle next time someone has kitsubito).
  Family reading, not one flake: same missed-window shape, host-independent, both mid-leg under
  load. Cross-ref KNOWN-HAZARDS 5.13 — bring-up has a hard ONLINE budget with known sensitivity to
  anything that stalls it (the blanket-fsync canary; `attach_wedge_e2e` guards that budget).
- **State line (the discriminating datum, resident_service red):** `daemon_up=false boot_alive=true
  boot_pid=Some(8920) rel_started=false broker_survived=false` — the boot process was ALIVE at
  panic time and the daemon never reached up. Any characterization run records this line per run,
  not the verdict (hertz protocol 2026-08-03).
- **Read of that line, CORRECTED 2026-08-03 (hertz):** it is NOT "started-but-never-bound" (the
  earlier reading here) and not "never-started" — it is **started, did work, then killed** —
  CANDIDATE via [[IR-18]]. The daemon spawned its boot service and that service reached the CLI
  (the spool holds its message), and `broker_survived=false`. The DISCRIMINATING field is
  `broker_survived`: false in every killed round of the positive control, true in every healthy
  round. **An earlier evidence leg here is RETRACTED (hertz, same night, off the negative arm he
  ran before reporting; deployah, who had carried the leg into four register sites, swept every
  placement): "empty daemon.stderr.log = TerminateProcess signature" was false — the stderr
  block is empty on PASSING runs too, so it carries zero information in either direction; it
  failed the discriminator question and does not support the kill read.** The kill read now rests
  on the control's field-for-field reproduction and the IR-18 mechanism, not on the log.
  Consequences: (a) the bring-up window is **exonerated for this specimen** — measuring it would
  have measured nothing; (b) the candidate mechanism and its evidence now live in [[IR-18]]
  (a sibling test's bare breadcrumb tree-kill), CANDIDATE — not reproduced, not proven;
  (c) **the characterization population changed, and the rate run is CANCELLED** (doyle ruling
  2026-08-03) — `resident_service_e2e` run ALONE has no sibling to collide with, so the mechanism
  predicts 0/N and that number answers no live question; the only sound population was the test
  INSIDE the Phase A parallel pool, which costs a full Phase A leg per sample, and the fix is
  warranted by the source-verified hazard class regardless of the specimen's rate. No rate figure
  will exist for this specimen — do not later read its absence as a low rate; (d) **positive
  control still runs, falling out of the
  hypothesis:** kill the spawned daemon by pid mid-bring-up — after boot-service spawn, before
  ready — and it must reproduce the observed line field for field (`daemon_up=false
  boot_alive=true broker_survived=false`). If the rig cannot make that shape on
  demand, a 0/N from the untouched arm is worth nothing and must be reported as worth nothing.
  The host-INDEPENDENT family claim (kitsubito's `activity_link_push_e2e`) is untouched by this:
  it has no such kill site named, so the family survives even if this specimen leaves it.
- **POSITIVE CONTROL RAN 2026-08-03 (hertz, prebuilt a5042ec binary, box confirmed clear —
  0 open runs, 145.95 GB free): shape reproduced 3/3, deterministic.** Negative arm n=2: 2/2 PASS
  (5.59s, 5.46s), `daemon_up=true boot_alive=true rel_started=true broker_survived=true
  survived_teardown=true`. Positive arm (daemon killed by parent-scoped descent after
  boot-service spawn, before ready) n=3: 3/3 FAIL (93.95/93.25/93.50s), state line identical to
  the CI red in EVERY field except boot_pid (a pid, must differ), same panic, same site
  (resident_service_e2e.rs:382). Structural fact the arm settled, and the refutation risk that
  made it worth running: the boot service rises BEFORE brain.ready becomes readable — had the
  order been reversed the arm would have produced daemon_up=true and refuted the mechanism.
  CEILING MET, NOT EXCEEDED: the control used Stop-Process -Force (TerminateProcess — the same
  primitive as taskkill /F), so it proves a forced daemon kill after breakaway-service spawn
  produces this exact line ON DEMAND; it says nothing about WHO issued one in golden 30782259675.
  Candidate mechanism, shape reproduced on demand — "root caused" written by nobody. Duration
  note, recorded not explained: 93.5s local (idle box) vs 123.99s CI (Phase A parallelism), both
  burning the same three 45s windows — consistent, not verified.
- **Same-host sub-observation (hertz, host-CONSTANT — narrower claim, kept separate):** both
  reds of 2026-08-03 sat on hfenduleam Windows Phase A and burned their full windows:
  `a_tree_teardown_reaches_a_grandchild_the_service_spawned` (run 30776330383, FAIL 10.176s = the
  full poll deadline, vs a 0.19–0.66s pass band — 15–50x out) + the resident_service row above.
  MEMBERSHIP PROVISIONAL for the teardown row: it carries a candidate mechanism the bring-up burn
  does not share — the pid-only oracle IR-15 just replaced. If the oracle caused it, that row
  leaves the family and host-constant collapses to one sighting. The host-INDEPENDENT pair above
  is the claim that survives someone fixing this box; the sub-observation is what is actionable
  about hfenduleam (a live-daemon host) meanwhile.
- **Declared read (2026-08-03, rules the next red):** a same-sha green rerun is protocol-conclusive
  for the GATE, not the class. No third silent sample — the next occurrence of this signature gets
  an instrumented resident-service bring-up investigation (hertz), not a rerun.
- **Ripe when:** next occurrence of the signature (immediate instrumented dispatch), or a hertz
  test-hardening wave (bring-up phase-timing instrumentation, per-phase deadline attribution).
- **Size:** medium (bring-up instrumentation + attribution; the fix depends on what it shows).

### IR-16 — kill_tree discards TerminateJobObject/TerminateProcess returns (silent partial kill)
- **Status:** open · **Origin:** ex releases#130 (golden 30776330383 red triage; deployah's log read
  + todlando's flagged-not-asserted arm). Operator-classified infra 2026-08-02: daemon-kill
  internals are agent-facing, not operator-facing surface.
- **What/why:** `DetachedChild::kill_tree` (daemon.rs:1433 vicinity) calls
  `unsafe { TerminateJobObject(self.job, 1) }` and discards the return; TerminateProcess likewise
  unaudited. A job that was created and assigned at spawn but whose TERMINATION fails at kill time
  yields the grandchild-survives symptom with zero log signal — the spawn-side
  SERVICE_JOB_UNAVAILABLE announcement is correctly absent (that arm is instrumented and was
  refuted for the specimen by a positively-controlled zero). Wanted: (1) check + log both
  termination returns loudly on failure; (2) the degraded-arm decision — fallback process-table
  tree-walk kill or explicit refusal, never a silent partial kill wearing REQ-RESIDENT-SERVICE's
  unconditional promise. Do NOT add self.job==0 instrumentation (already loud; a second weaker
  rule beside a working one). Discrimination pairing with [[IR-15]]: a red whose captured pid is
  still ping.exe with no SERVICE_JOB_UNAVAILABLE in scope = this entry's arm.
- **Ripe when:** RIPE NOW — IR-15 landed BUILT 2026-08-03 (its rig-side half), so this kill-side
  half is the outstanding instrument; land with the next daemon-teardown wave or sooner.
- **Size:** small.
- **Composed:** LOCKSMITH (#132) — todlando product lane, with the `detached_no_inherit_env`
  rename as cosmetic rider (IR-20's load-bearing-pid caution applies to any rig touch) —
  2026-08-03. GREENLIT with #132 and **DISPATCHED to todlando 2026-08-03**, carrying IR-20's
  load-bearing-pid precondition as a stated check (todlando reports whether the rig is touched
  at all rather than silently skipping it).

### IR-18 — resident_service_e2e kills breadcrumb pids BARE (stale-breadcrumb tree-kill; kill-side twin of IR-15)
- **Status:** built, GOLDEN-PENDING (lane merged; BUILT only when the next golden batch's Phase A
  proves the changed test in-pool — that run is the acceptance evidence; a red there returns to
  doyle with the lane's discriminating instruments already in-tree). Acceptance carrier named
  2026-08-03: LOCKSMITH (#132) Phase A golden · **Origin:** hertz
  characterization of the [[IR-17]] resident_service red, 2026-08-03 — CANDIDATE mechanism, NOT a
  reproduction
- **Lane:** hertz `fix/ir18-authenticated-teardown` — MERGED to main @6e1a962 (PR #142; gated at
  b48e35b, rebased 6e1a962 on 1e520b4 with zero code delta — doyle re-derived `git diff -- crates/`
  empty across the rebase, so the gate verdict and local behavioral evidence transfer). Gated by
  doyle: full diff review (one blocking finding — the scope_lost assert condition contradicted its
  own guard ruling — fixed and delta-verified at one line), mutation-proven locally both
  directions (B: forced boot_pid=None → population sweep names the leak no per-pid check sees,
  FAIL 101; A: wrong expected_exe → REFUSED-foreign-image reds loudly on the derivation check).
  EVIDENCE SPLIT, stated so the check marks cannot carry it (hertz's absent-leg callout): lane CI
  30792210008 was 5/5 green per job but ci.yml's test leg is kind(lib)+kind(bin) — the changed
  integration test NEVER RAN there (verified by log grep, 0 hits / 3023 lines); CI proved
  compile-everywhere (clippy all-targets = the pool-population check for a common/ module),
  traceability, lib/bin clean. The BEHAVIORAL evidence is local: three clean runs (all verdicts
  Killed, population empty) + the two mutation reds. reap.rs diff additive-only (zero deleted
  lines, verified) — cross-test risk bounded to compilation, which CI covered. Evidence custody:
  gate + mutation logs at `.worktrees/_patches/ir18-gate-logs/` (5 files); `.worktrees/ir18` is
  KEPT deliberately until the golden verdict (NOT an orphan — do not reap; a Phase A red wants the
  tree and logs in place, not rebuilt); its pool claim is released.
- **What/why:** `crates/spt/tests/resident_service_e2e.rs:46` defines its own reaper —
  `taskkill /PID <pid> /F /T`: bare pid, force, whole TREE, no identity check — and feeds it three
  BREADCRUMB-derived pids in cleanup (`boot_pid`, `rel_service_pid` at :360, and the pid read out
  of `brain.ready` at :363). The suite already ships the authenticated tool other tests use and
  this one does not: `common::reap::authenticated_kill(label, pid, expected_exe, observed)` at
  `crates/spt/tests/common/reap.rs:116`. Inside the Phase A parallel pool on a pid-churning box
  this is the KNOWN-HAZARDS stale-breadcrumb tree-kill class, live and **symmetric**: this test can
  take a sibling's daemon and a sibling can take this test's. Same defect [[IR-15]] just fixed, on
  the other side — IR-15 authenticated the READ (is the thing I pinned gone?), the KILL is still
  bare pid. Kill what you pinned, not the number it happens to hold.
- **Verified at source by deployah 2026-08-03** (relayed claims re-derived, all held): the bare
  kill, its three breadcrumb feeds, the shipped-but-unused authenticated helper, and the
  `CREATE_BREAKAWAY_FROM_JOB` spawn (`daemon.rs:1300`).
- **Evidence rating — why it is a candidate and not a cause:** it predicts every field of the one
  observed state line. The daemon is killed after spawning its boot service and before binding:
  `broker_survived=false` (the discriminating field — false in every killed control round, true in
  every healthy one) + `boot_alive=true boot_pid=Some(8920)` with the service's message in the
  spool. (The "empty stderr = silent death" leg that originally sat here is RETRACTED — see
  [[IR-17]]'s control record; stderr is empty on healthy runs too and discriminates nothing.)
  The service outlives its daemon because `detached_no_inherit_env` spawns it
  `CREATE_BREAKAWAY_FROM_JOB`, so it is NOT in the daemon's job and a daemon kill ORPHANS it
  rather than reaping it — plausibly also the five denied `svcmock.exe` attempts in that job's
  reap summary. **The [[IR-17]] positive control (2026-08-03) reproduced the shape 3/3
  deterministically with a forced kill at that window — establishing the SHAPE on demand, not the
  AGENT: nothing identifies who issued a kill in golden 30782259675.** The bare-pid tree-kill from
  a concurrent test remains the candidate agent, on the source-verified hazard class and reap.rs's
  documented prior casualty. **Not reproduced in the wild. Not proven. "Root caused" is not
  written here by anyone.** The [[IR-17]] rate run is cancelled, so no rate will ever back this —
  the fix stands on the source-verified hazard class alone. THE DEFECT IN MINIATURE, observed as a
  side effect of the control (hertz 2026-08-03): the three killed rounds leaked 12 processes
  (6 svcmock + 6 spt.exe, two services per round) and the test's own teardown reaped NONE — when
  the daemon dies, `rel_pid` is `None` so that service is never even a kill target, and the
  breakaway child outlives everything. A teardown that leaks two processes per round currently
  PASSES: the concrete case for `target_gone` as the gate's positive half. (Leak cleaned scoped,
  each pid re-authenticated by image-path prefix + creation window at kill time, not from the
  minute-old enumeration.) ONE LAYER DEEPER (deployah, same night, at source): the reap loop
  (:359) is `[boot_pid, rel_service_pid].into_iter().flatten()` — `.flatten()` DROPS None, and
  `mock_pid` (:100-106) collapses absent/permission-denied/IO-error/garbage into that None via
  `.ok()?`/`.ok()` — the reap.rs:59-63 collapse in a THIRD location, inside this very test. So the
  leak is both "service never started" AND "pid unreadable, therefore never a kill target":
  absence of knowledge read as absence of target, in a teardown, again.
- **GATE SPEC AMENDED PRE-BUILD (deployah found the hole, doyle-ruled 2026-08-03 — read this
  BEFORE building the lane):** the two halves as first specified (trap-class-absent +
  `target_gone` per pid) both operate on pids we HAVE — a process whose pid is None is invisible
  to BOTH, so the specified gate PASSES hertz's own control-run leak (12 processes, 6+6, 2/round,
  teardown reaped none). A gate its own reproduction case passes is not yet an instrument. THIRD
  HALF, REQUIRED: a POPULATION assertion at teardown — zero surviving staged-service or
  test-owned spt processes, by selectors external to the pid bookkeeping. SELECTOR RESPELLED
  (hertz 2026-08-03, doyle-approved — the first spelling, "parent-pid descent from the test
  process", would have caught ZERO of the 12: teardown kills the daemon before any check runs, the
  BFS over the current (pid,ppid) table breaks at the dead middle hop, and descendants(test_pid)
  returns empty exactly in the leak case — an absence read as a clean, the shape the lane exists
  to kill; the control's own cleanup is the evidence, it had to use image+creation-window because
  descent was already broken). THE TWO SELECTORS AS BUILT: (1) svcmock half by IMAGE PATH —
  stage_adapter copies the service binary under this run's unique tempdir home, so "any pid whose
  exe_path canonicalizes under home" names every staged service this run started and nothing else
  on the box; no bookkeeping, immune to reuse and broken chains. (2) spt.exe half by SEEDED
  descent + image — image alone is forbidden (target/debug/spt.exe is shared with concurrent
  tests and live perches: the machine-wide selector class); seed with the ancestor set captured
  WHILE ALIVE ({test, broker from the Child handle, brain from brain.ready — none via mock_pid}),
  union descendants, keep only exe_path==spt_bin. Reuse exposure on seeds is assertion-only (a
  red, never a kill) and the image filter closes it. Both halves catch the 12-leak conformance
  case; the first spelling caught none of it. PLUS THE [[IR-8]] BUCKET, REQUIRED (deployah,
  same night — the third instance of that sentence tonight, this time inside our own instrument):
  both selectors match on IMAGE PATH, and an exe path that cannot be READ yields no match — a
  leaked svcmock holding an unreadable path is invisible to both halves and the count comes back a
  zero that cannot see. Not hypothetical: IR-8's defining specimen is 5/5-denied on this exact
  image, on this box. So the population assertion counts unreadable-path processes as their OWN
  bucket and the zero-survivors claim REFUSES when that bucket is nonzero — zero seen AND zero
  unseeable, or the assertion states it could not see. Built in from the start, not retrofitted
  (may land in the lane's second commit at hertz's discretion; the requirement is that it lands in
  the lane). This instantiates IR-8's remedy test-side; the CI reap-census script half of IR-8
  stays open.
- **Fix (thin lane, hertz — doyle-ruled 2026-08-03):** adopt `authenticated_kill` at all three
  sites. (Board #131's `CREATE_NO_WINDOW` rider is DROPPED from this lane — hertz falsified the
  filed remedy at source 2026-08-03: daemon.rs has exactly ONE CreateProcessW (:1187) and
  BASE_FLAGS (:1105) already carries 0x0800_0000 = CREATE_NO_WINDOW on both rungs including the
  ACCESS_DENIED fallback (which drops only BREAKAWAY), so the specified edit ORs an already-set
  bit — a bit-for-bit identical flag word that would close a board item while its symptom, if
  real, continues. #131 handed back to board triage with the finding and a candidate direction:
  DETACHED_PROCESS gives the service no console, so a console child the SERVICE spawns flagless
  allocates a NEW visible window — the grandchild, not the daemon's spawn, is the candidate
  surface; wants its own diagnosis from an observed window. ~~The `detached_no_inherit_env` rename
  ("detached" actually means breakaway-from-job) is a candidate cosmetic rider on [[IR-16]]'s
  product lane~~ — **RENAME DROPPED 2026-08-03, ITS PREMISE MEASURED FALSE** (todlando, on the
  IR-16 lane; doyle re-verified at source before ruling). "detached" is ACCURATE: `BASE_FLAGS`
  (daemon.rs:1103-1105) is `DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW`, and
  `0x0000_0008` IS DETACHED_PROCESS — the function sets BOTH postures and the name states one of
  them. The name is not wrong, it is INCOMPLETE (silent about `CREATE_BREAKAWAY_FROM_JOB`, which
  arrives as `extra_flags` at daemon.rs:1506), so renaming on the stated premise would have traded
  an accurate word for one that drops a flag the function really sets. Independently fatal: the
  premise, if true, covers the sibling `detached_no_inherit` equally — 17 references across
  daemon.rs/deelevate.rs/shellhost.rs — and renaming one of two siblings of ONE posture leaves the
  tree MORE inconsistent, not less. **What lands instead:** one doc-comment line on EACH function
  naming the full effective flag word, which fixes the real complaint (neither name says breakaway)
  without touching a call site. Kept here rather than deleted because this entry was the claim's
  only home, and a reader who found the rename gone with no reason would re-derive it.) PER-PID GROUND TRUTH for expected_exe (hertz — SELF-CORRECTED
  at source before it ever landed; his first derivation, "Copy runs from adapters_dir(), Pointer
  runs from srcs/", was WRONG and registration mode is NOT the discriminator): servicehost.rs:1328
  takes `install_dir` from `record.source_dir` on the Started arm for EVERY service, Copy and
  Pointer alike, and Copy copies only the manifest + strings/ (registry.rs:395-404), never a
  binary — `adapters_dir()` holds no executable in either mode. BOTH services run from their OWN
  staged src dir: `staged_bin(<adapter's staged src dir>, "svcmock")`. The trap survives with a
  different mechanism: two adapters staged into two DIFFERENT source dirs are two different files
  on disk, so one expected_exe still cannot serve both. A lane that trusted the mode split would
  derive a path with no binary at it. How it was caught, kept because it is the reusable part: not
  by rereading the mode table but by finding where install_dir is COMPUTED instead of trusting an
  already-published inference — the mode split was true of MANIFESTS and had been generalized to
  BINARIES without checking the consumer; and the derivation-asserted-at-observe() instrument
  would have caught it at runtime regardless — the instrument did its job before it ever ran,
  argued against its own author. SCOPE_LOST RULED A GUARD, NOT A FINDING (hertz design change,
  doyle-approved): a seed pid recycled before the sweep makes the sweep DECLINE that subtree
  loudly, not fail — failing would turn ordinary pid churn on a busy runner into a red against a
  clean teardown (the IR-15 false-red class re-minted inside its own fix); coverage holds without
  it because the staged services are caught by image-path-under-home and the daemon + brain by NEW
  direct per-pid target_gone checks (their pids this test never loses) — the ancestry half is
  reach, not load-bearing. `unreadable` stays FATAL as ruled.
  Sequencing: positive control
  first (it is the instrument that could still refute the mechanism), then the lane. Does NOT ride
  [[IR-16]] (doyle-ruled same day): that is the product-side kill_tree audit and stays a separate
  lane under the dispatch split; the two cross-ref, they do not merge.
- **Lane trap, flagged before build (hertz 2026-08-03 — the false-clean shape):** `expected_exe`
  differs PER PID. `boot_pid` and `rel_service_pid` run the staged svcmock image, NOT spt.exe —
  passing spt_bin for those refuses every kill as foreign-image and LEAKS both services while the
  reap reads hardened. Only `brain.ready`'s pid takes spt_bin. Also: `observe()` boot_pid at :210
  while it is provably ours, so the reuse check has creation-time teeth instead of degrading to
  image+ancestry.
- **Gate the lane on killing, not on refusing (deployah 2026-08-03; REFINED by hertz same night
  from reap.rs's own contract):** the hardened version fails safe in the WRONG direction —
  refuse-everything leaks both services while printing exactly the reap line a reviewer wants to
  see, strictly worse than the bare kill it replaces and invisible in the same log. But a BLANKET
  zero-REFUSED gate is wrong too: reap.rs's module doc (:18–20) states refusal is the CORRECT
  happy-path outcome when the test already stopped its daemon (`Refused("gone")` — leak insurance,
  not primary teardown), so the blanket gate reds healthy runs, someone loosens it to go green, and
  the loosened version is exactly the one blind to foreign-image — the detector dies by
  maintenance, wearing a green. The refusal reasons split, and only one class is a defect:
  SOUND (expected): `gone`, `reused`, `breadcrumb-moved`, `self`, `ancestor` — target provably not
  there. TRAP (the false-clean state): `foreign-image`, `unreadable-image`, `unproven-identity` —
  something WAS there and authentication declined; `foreign-image` is precisely what a wrong
  per-pid expected_exe produces on every pid, every run. THE GATE: in the arm that must kill,
  assert no verdict in the trap class — structurally on the returned `Verdict` (Killed |
  Refused(&'static str), stable tokens by design, reap.rs:48), not by scraping output; the
  `REAP[label]: … verdict=` line stays as CI-log forensics. The gate's comment MUST say
  `Refused("gone")` is expected, or the next reader "fixes" it. Positive counterpart that actually
  proves the reap: assert `target_gone(pid, expected_exe, observed)` (reap.rs:215 — no-knowledge
  never read as death) per service pid; bare-liveness "no survivors" is the false-clean named above.
  TOKEN SET VERIFIED COMPLETE-PLUS-ONE (deployah, refuse() sites enumerated at source): the eight
  tokens above sit at :128 self, :132 ancestor, :136 breadcrumb-moved, :146 gone, :149
  unproven-identity, :155 reused, :166 unreadable-image, :172 foreign-image — each in the right
  class — and there is a NINTH neither list held: `Refused("no-breadcrumb")` at :243, returned
  before authenticated_kill is reached. Doyle-ruled 2026-08-03, both halves: (1) `no-breadcrumb`
  classifies SOUND — **SCOPED (deployah source-read, same night): it is two states wearing one
  name.** `breadcrumb_daemon_pid` (reap.rs:59–63) collapses file-absent, permission-denied, any IO
  error, AND a husked/unparseable partial write into one `None` via two `.ok()`s — so the token is
  ABSENCE OF KNOWLEDGE, not proof of absence, and it is SOUND only because the calling test has
  already asserted its daemon stopped. Every other SOUND token carries positive proof; a LIVE
  daemon whose pid file is unreadable or husked emits the identical token and leaks wearing
  "nothing to reap" — the helper's one fail-open path inside a fail-closed design (its own module
  doc: no-knowledge is never read as death), and the same sentence as [[IR-8]]: a zero that cannot
  see is not a zero. CORRECT REMEDY (doyle-ruled, deferred — not this lane, unreachable from this
  test's pids): split at source into `no-breadcrumb` (absent) vs `unreadable-breadcrumb` (TRAP,
  beside unreadable-image) — IR-8's unreadable-bucket fix in a second location; land the pair in
  the census/reap wave IR-8 already names, one remedy for two entries. Precondition on the split
  (hertz): common/reap.rs compiles into EVERY spt integration test binary, so enumerate the callers
  that actually REACH `reap_breadcrumb_daemon` before the token split lands — those are the tests
  whose teardown semantics change; own lane, not a rider. ENUMERATION DONE (deployah, same night,
  read-only): 21 caller tests, every one passing &spt_bin as expected_exe (the per-pid trap is
  specific to resident_service_e2e's svcmock pids — it does not generalize to this population);
  20 callers fire-and-forget the Verdict; the one value-assertion, reaper_guard.rs:192-196, pins
  `Refused("no-breadcrumb")` for an ABSENT breadcrumb only — absent KEEPS the token under the
  split, so that assertion survives unchanged (:183's stale-pid check is the loose
  `matches!(Refused(_))`). The split is ADDITIVE: one source split, one new token, zero caller
  rewrites. THE GAP THAT LET THE COLLAPSE HIDE: reaper_guard covers eight refusal shapes but has
  NO test for an unreadable or malformed daemon.pid — the one state where absence-of-knowledge
  reads as absence-of-target is the one state without a conformance test; (b) ships with exactly
  that evidence (a garbage daemon.pid and an unreadable one, each asserting the new token).
  ASSIGNED: deployah owns the (b) lane (doyle-ruled 2026-08-03), SEQUENCED AFTER hertz's IR-18
  lane — the exhaustive panic-catch-all lands first, so the new token arrives forced-classified
  per this entry's own design, and the (b) lane classifies it TRAP in the same change. SCOPE
  RE-RULED (2026-08-03, on deployah's third-site find): the collapse now has THREE known sites
  (reap.rs:59-63, resident_service_e2e's mock_pid :100-106, and the shape wherever a test reads a
  self-written pid file) — so (b) lands ONE shared read-a-pid-breadcrumb helper that distinguishes
  absent from unreadable ONCE, adopted at the enumerated sites, not a per-site token split; the
  single-source-discriminant rule, applied before a fourth site mints itself. Still deployah's,
  still after hertz's lane; hertz's lane does NOT wait for it (the population assertion covers the
  leak class independent of pid bookkeeping — that is its virtue). (b) INTAKE ITEM (doyle gate on
  the IR-18 lane, 2026-08-03, deferred there deliberately): the lane's verdict-gate SOUND-arm
  comment reads "provably not there", which overclaims for `no-breadcrumb` (absence-of-knowledge,
  not proof — the scoped reading belongs at that arm); comment-only, and (b) rewrites that arm
  when `unreadable-breadcrumb` splits out, so it lands there rather than costing a solo respin.
  SECOND (b) INTAKE ITEM (hertz self-noted at re-gate, doyle-ruled deferred): cleanliness is
  currently stated at THREE sites (two asserts + `is_clean`) — the drift that produced the
  scope_lost condition bug (a failed edit followed by a narrower successful one replaced the
  message but not the condition; the artifact of that failure mode IS message/code disagreement).
  (b) consolidates to conditions derived from one source, weighing the two-message diagnostic
  split it would cost. The
  exhaustive panic-catch-all match is what makes the split safe to do later: the new token lands
  loud on first fire in every consuming gate, forced to be classified, never silently passed. Until then the scoped reading above is the
  gate's contract — and the LANE BUILDER writes that scoped reading into the match's SOUND-arm
  comment (the sketch's "nothing to read is nothing to kill" is the exact inference the source
  forbids; the comment must not teach the false step); (2) the gate closes over the
  token set — SPELLED BUILDABLY (hertz correction 2026-08-03; the earlier "no wildcard arm" wording
  is an instruction rustc rejects, since the refusal reason is a `&'static str` (:55) and a string
  match always requires a catch-all): the match names the six SOUND tokens as a pass arm, the three
  TRAP tokens as a panic arm, and the REQUIRED catch-all arm is not a wildcard PASS — it panics
  naming the unknown token ("unclassified reap refusal token — classify it in this match"), so
  upstream drift announces itself the first run it fires instead of sliding into a silent pass.
  Runtime fail-closed, not compile-time: compile-time closure needs the reason to become an enum in
  common/reap.rs, an upstream change touching every consumer — ruled NOT smuggled into this lane
  (candidate for its own thin lane if ever wanted; doyle concurs runtime fail-closed is
  proportionate). Direction of the default, kept in the record: a missed trap state is an invisible
  leak wearing the reap line a reviewer wants to see; an unclassified harmless token is a loud red
  costing one edit. Cheap and loud beats silent and wrong. (Count hygiene, hertz self-flagged: a
  single-line grep for the refuse() sites returns five of nine — three wrap across lines; the nine
  stands on reading, not the grep. The sweep-count trap in miniature.)
- **Prior observed instance of the class, in-tree (hertz 2026-08-03 — stated to understate):**
  reap.rs:3–11 documents the measurement and a casualty: pid reuse on the Windows gate box at
  2.2s minimum / p50 11.7s under a Phase-A battery, and a concurrent test process killed by a bare
  kill on a stale breadcrumb pid, dying with bare exit 1 and no panic — the observed
  `worker_lifecycle_e2e` red in golden job 90742055246 (that test's intermittent class is board
  releases#32, still in-flight). Different test, different job — it does NOT reproduce this entry's
  specimen and promotes nothing; what it settles is that the class is real IN THIS SUITE with a
  named victim, and the authenticated reaper is the remedy someone already built for it —
  resident_service_e2e simply never adopted it. Two shape-predictions it supplies, made before this
  specimen existed: the p50 11.7s reuse window is short against this test's 45s waits and ~124s
  runtime (window wide open). (A second claimed match — "bare-exit-1-no-panic matches the empty
  daemon.stderr.log" — is RETRACTED as a category error, hertz+deployah 2026-08-03: reap.rs's
  phrase describes the VICTIM TEST PROCESS dying, not a daemon's log; two processes, two
  artifacts.) Predictions, not proof; the specimen stays CANDIDATE — shape since reproduced on
  demand, agent unidentified (see the control record above).
- **Rig near-miss, caught before first execution (hertz 2026-08-03) — kept as design justification,
  not an anecdote:** the positive-control arm's first draft selected its victim machine-wide
  (`Win32_Process Name='spt.exe'` + cmdline match `daemon run`, then force-kill). hfenduleam is the
  Windows CI runner as well as a dev box, so that filter matches CI's own test daemons: run while a
  leg was live, it would have force-killed a running job's daemon and reported the result as a
  measurement — fabricating a red in someone else's job, the exact class this entry documents.
  Corrected to a parent-scoped selector (daemon = child of the test pid; service = child of that
  daemon); `CREATE_BREAKAWAY_FROM_JOB` does not weaken parent-id attribution, since breakaway leaves
  the JOB, not the parent record — which is also why the orphaned svcmock stays attributable to the
  daemon that spawned it. **The load bought the catch** (blocked on the box ⇒ re-read instead of
  ran). Bearing on the fix: the INSTRUMENT built to study a bare-selector reaper was itself written
  with a bare selector. The remedy therefore cannot be "be careful" — the authenticated path must be
  the only one within reach in this suite.
- **Ripe when:** RIPE NOW, and not gated on the rate run that was cancelled.
- **Size:** small.

### IR-19 — Docs-only pushes to main run full unit legs (classifier is PR-only) — intent unverified
- **Status:** open, QUESTION not finding · **Origin:** hertz observation 2026-08-03 (register-push
  cadence gated his rig behind repeated hfenduleam unit legs); mechanism verified by doyle at
  source same night.
- **What/why:** `ci.yml`'s `changes` job classifies docs-only diffs ONLY for `pull_request` events
  — push events hardcode `code=true` (ci.yml:45–48, an explicit branch, not a fallthrough), so
  every docs-only push to main spins both full unit legs. Tonight: five register docs pushes each
  queued a Windows unit leg on hfenduleam; concurrency kept one running + one pending (main is
  never cancelled in-progress, pending runs supersede — the recorded behavior matches ci.yml:9–13).
  FINDING SETTLED (deployah, same night, from the workflow): this is not intent — it is a scope
  the classifier never had; the `*.md` / `traceable-reqs.toml` case arms are only ever REACHED on
  pull_request (the early-return precedes them), and golden.yml's own hardcoded `code=true` is
  unrelated (golden triggers only on golden/**). REMEDY STILL OPEN on a named tension: extending
  the classifier to pushes leaves a docs-only main TIP with no run of its own — fine if
  tested-sha==merged-sha means "the code at this sha was tested" (it was, at the last code sha),
  not fine if any gate or reader takes "main tip has a green run" as the check. One person reads
  the consuming gates before any remedy (doyle, at the next CI-touching wave) — three assuming is
  how this class ships.
- **Interim rule (doyle, same night):** batch register edits into one push instead of landing them
  as they occur — the cadence is a real gate on whoever is queued behind the runner.
- **Ripe when:** next CI-touching wave, after the intent question is answered on the REQ record.
- **Size:** small (one conditional, if the answer is "extend").
- **Composed:** LOCKSMITH (#132) — doyle reads the consuming gates during the batch's CI-touching
  wave (the intent question), BEFORE any classifier remedy. 2026-08-03.

### IR-20 — resident_service_e2e's `spt daemon stop --force` does not stop the daemon; teardown is complete only because the kills are
- **Status:** open · **Origin:** hertz 2026-08-03, measured on the IR-18 lane's own clean run
  (hfenduleam, log kept); routed text, doyle-landed.
- **MEASURED:** teardown runs `spt(&["daemon","stop","--force"])` then reaps. At reaper fire, every
  target was still ALIVE and every verdict was `Killed`, not `gone` — verdicts=[boot Killed,
  rel Killed, brain Killed]; the brain's kill line names it `(child process of PID 46896)` — the
  daemon — so the daemon was still resident too and was taken down by the `Child` handle, not the
  stop. A stop that worked would have left the reaper `gone`. This rules OUT the innocent reading
  (stop doesn't manage services): the stop did not reach the DAEMON either.
- **NOT ESTABLISHED — two rungs, neither discriminated:** (1) the rig seeds a `doyle` perch with
  `std::process::id()`, satisfying `ceremony_agent_ground`'s pid-ancestry rung for every child of
  the harness; (2) the rig never scrubs `OWL_SESSION_ID`/`SPT_AGENT_ID`/`SPT_ENDPOINT_ID` from its
  teardown commands, and the measuring run launched from a live agent session, so the env rung was
  live too. `--force` overrides neither. The stop's output is discarded at the call site
  (`let _ = spt(...)`) — no diagnostic names a denial, and no claim is made that one fired.
  Settling it is one run with the stop's stderr captured — on the CI runner AS WELL AS the dev box,
  since the rungs fire on different machines.
- **Why it matters beyond this rig:** REQ-TEST-RIG-DAEMON-TEARDOWN-PROVEN's own failure shape
  inside a rig that passes — teardown completeness rested entirely on breadcrumb kills that were,
  until IR-18, bare `taskkill /F /T` on unauthenticated pids; the most trustworthy-LOOKING
  component (an explicit `--force` stop) was doing nothing while the least trustworthy one did all
  the work. Exactly why the population gate exists rather than per-pid checks alone.
- **Remedy caution (the sentence that must not drop):** the prescribed fix (seed pid 0, scrub the
  three markers — REQ-TEST-RIG-DAEMON-TEARDOWN-PROVEN's own gate) is NOT free here: this rig's
  `doyle` perch pid is load-bearing for the shell bind-by-token legs, so the two remedies are not
  interchangeable — a lane taking this must check which legs depend on the pid before changing it,
  or it fixes the stop and breaks the REQ-INSTALL-11 legs the rig exists for. Kin:
  REQ-BROKER-STOP-ENDPOINT-DENY (the refusal being worked around).
- **Ripe when:** a hertz test-hardening wave, or alongside the (b) helper lane's touch of this rig.
- **Size:** small (stderr-captured discrimination run × two machines, then the scoped remedy).

## IN-FLIGHT ON THE BOARD (not re-homed — live WIP lanes)

- releases#93 (servicehost swap test pid-inequality), releases#47 (thin-lane unit(Windows)
  isolation class), releases#32 (worker_lifecycle_e2e Phase A intermittent) — infra-shaped but WIP;
  a live lane is never re-homed mid-flight. When each closes, any residue lands here as a new entry.

## BUILT / RETIRED

### IR-15 — provably_gone is pid-only on Windows: teardown tests can fabricate reds
- **Status:** BUILT 2026-08-03 · **Origin:** golden 30776330383 red on the #125 fix lane (2026-08-02)
- **Lane:** hertz `golden/ir15` @a5042ec — REQ-TEST-LIVENESS-ORACLE-AUTHENTICATED (impl+unit): one
  shared authenticated death-oracle test helper backed by `spt_procident::process_identity`
  (identity pinned at find time, re-verified at assert), both pid-only polling sites repinned
  (daemon.rs teardown test; endpoint_lifecycle.rs relay_pid). Ruled polarity held: Absent⇒gone,
  Present(same start)⇒not gone, Present(different)⇒gone, Unproven⇒NOT gone, missing-stamp
  degrades to pid-only loudly — every unknown errs toward the recoverable red, zero new
  false-green paths. Linux caveat documented in the helper (10ms jiffies: Present(different) is
  narrowing, not decisive; same-tick reuse errs red, safe).
- **Golden:** run 30782259675 red on `resident_service_e2e` bring-up — delta exonerated (unrelated
  family, now [[IR-17]]; same job minted [[IR-8]]'s defining specimen). Same-sha rerun 30784469908
  GREEN; main ff'd to a5042ec.
- **A/B discriminator (hertz):** 80/80 green both arms, quiet + churn phases; churn arm
  positive-controlled (pid-allocator wrap observed <400ms, so reuse pressure was REAL in the churn
  arm); rule-of-three bounds the original flake at ~7.5%/run/sha. Specimen 30776330383 remains
  not-reproduced, cause unidentified — the repin removes the false-red MECHANISM; it does not
  adjudicate the specimen. [[IR-16]]'s kill-side arm (TerminateJobObject return discarded) stays
  a live discriminating instrument for any recurrence — and since 2026-08-03 it is no longer the
  only one: [[IR-18]] (the test's OWN bare breadcrumb tree-kill) is the second kill-side candidate,
  test-side rather than product-side. A recurrence must discriminate between them, not assume
  either: IR-16's arm is a job whose termination silently half-fails (survivor still holds the
  captured image); IR-18's is a victim killed by a bare pid it no longer owns —
  `broker_survived=false` with the boot service still ALIVE and its message spooled. (An earlier
  spelling of IR-18's signature here said "empty stderr"; retracted — empty stderr is present on
  healthy runs and discriminates nothing.)

### IR-21 — CLASS: a helper binary's build is never requested, only its LOCATION is, so any narrow invocation manufactures a red that belongs to the rig
- **Status:** open · **Origin:** todlando 2026-08-03. Filed as one instance, rewritten as a CLASS the
  same day when a second member appeared, rewritten AGAIN when the mechanism was measured — the
  first two versions described symptoms and got the remedy wrong. **Corrected a fourth time the same
  day**: remedy (1) claimed the 11 same-package sites were missing a build edge, and todlando
  falsified that by measurement while executing it (replicated independently by doyle). The error was
  doyle's to carry — it was ruled on, not just written. The general rule that refutes it was already
  in this entry's own CI-member section; diagnosing a class does not inoculate you against drawing
  its opposite consequence one section later.
- **Numbers below re-derived on `main` @`3efd7e6` over `git ls-files` (tracked files only). Each
  carries its command; re-run rather than cite.**
- ⚠ **Scan-root hazard, measured 2026-08-03 and worse than first reported:** a naive recursive
  `grep -r` from the project root inflates by **~35×**, not the ~5× an earlier draft of this entry
  claimed — 426 tracked `.rs` against 14,865 on disk with `target/` excluded, because `.worktrees/`
  holds full copies of the tree. **And the unscoped grep does not COMPLETE** (still running at a
  120s timeout while `git ls-files` returns instantly), so the failure mode is not only a wrong
  number but a command that reads as hung on a tree where dozens of worktrees are normal. Use
  `git grep` or `git ls-files | xargs grep`; both are scoped to tracked files by construction.

#### THE MECHANISM (measured, both ends)

**Build end — `cargo test` with a narrow target selector compiles a `[[bin]]` AS A TEST HARNESS and
never emits the plain executable.** Measured: `cargo test -p spt --bins` on a clean pool produced
five executables, every one hash-suffixed under `target/<profile>/deps/`, and ZERO plain exes in
`target/<profile>/`. The bin was built. The file the test looks for was not written.

**Consumer end — the resolver borrows a guaranteed binary's path to locate an unguaranteed one.**
All 29 copies of `sibling_bin` in `crates/spt/tests/` reduce to two textual variants (22 + 7) of one
body:

```rust
fn sibling_bin(name: &str) -> PathBuf {
    PathBuf::from(env!("CARGO_BIN_EXE_spt"))
        .with_file_name(format!("{name}{}", std::env::consts::EXE_SUFFIX))
}
```

`CARGO_BIN_EXE_spt` is used **only as a directory anchor**. Cargo therefore sees a dependency on
`spt` and on nothing else; the `{name}` half is a string join it cannot observe. The dependency edge
does not exist at any level a build system could act on — which is why "use the wider command" is
not the fix and why the failure is invisible on a warm pool where some earlier run happened to leave
the file behind.

The unit-test resolver at `crates/spt/src/cli.rs:25601` reaches the SAME directory from a different
anchor (`current_exe()` → `deps/` → parent) for the same reason: its own doc comment records that
unit tests get no `CARGO_BIN_EXE_*` at all.

**That mechanism explains both original members at once, including the polarity inversion that made
them look like different bugs:** whether `cargo test -p spt` or `cargo test -p spt --bins` happens
to leave a plain exe behind is incidental to a dependency neither command was told about.

#### SCOPE — WHERE IT BITES, AND WHERE IT DOES NOT

**It bites NARROW invocations — `-p <pkg>`, `--bins`, `--lib` — i.e. gate rigs and local runs.**
Both members were hit on the LOCKSMITH t1 lane against fresh throwaway pools; each was discharged
in-lane as a rig artifact. That is the whole field population to date.

**GOLDEN IS ACQUITTED, and the acquittal is measured rather than assumed.** `cargo test --workspace
--no-run` emits all 13 plain binaries — mock-session, mock-shell, capture-player,
console-mode-probe, service_fixture and the rest — so a workspace build produces the cross-package
helpers by construction. Confirmed under nextest, the tool CI actually runs, with a real compile.

⚠ **The measurement that establishes this is not the obvious one.** Deleting the plain exe and
watching it reappear is NOT evidence of a rebuild: cargo's uplift restores a hardlink from an intact
`deps/` artifact, with link count 3 and an UNCHANGED mtime, which looks exactly like a build and
says nothing about a pool that never had the file — and a pool that never had it is the only kind a
rig runs on. The sound probe removes the plain exe AND both `deps/` artifacts, confirms all three
absent, then watches the target actually recompile (mock-adapter, 5.77s, fresh mtime). The first two
attempts were setup, not measurement.

⚠ **The suspicion this acquits is structurally well-founded, so record the answer, not just the
verdict.** `twohost-a`/`twohost-b` are `needs: test`, so the only mock-adapter prebuild runs AFTER
the phases that use it; `target/` is gitignored, so checkout never cleans it on a persistent
self-hosted workdir. Every precondition for artifact leakage is present — the build simply does not
need it. The next person who reads that job graph will form the same hypothesis; this is the answer
waiting for them.

#### THE ONE CI-SIDE MEMBER THAT IS REAL

`crates/spt/src/cli.rs::adapter_translate_proof_gates_on_commit` is a **unit** test (`kind(bin)`),
and `CARGO_BIN_EXE_*` is set only for integration tests and benches of the declaring package. A unit
consumer therefore CANNOT express the dependency through the env var at all — it has no choice but
to resolve by path. That is why `.github/workflows/ci.yml:105-106` carries a hand-written
`cargo build -p spt --bin translate_proof_fixture` before the unit lane, with a comment
(`ci.yml:102-104`) stating this exact mechanism.

**Deleting that step would red the unit lane on a clean pool, and it would read as a code red.**
Somebody already hit this class, fixed their own leg correctly, and never turned it into a rule —
the comment at `ci.yml:102` is IR-21 written a milestone early, in the one place only its author
would find it.

#### POPULATION

**13 bin targets in the workspace** (`cargo metadata --no-deps`, not a grep — an auto-target under
`src/bin/` and `xtask` are both invisible to a `[[bin]]` grep). Two are not helpers (`spt`, `xtask`);
the other **11 are test helpers**, across three packages:

| package | helpers |
|---|---|
| `adapters/mock` | mock-session, mock-shell, capture-player, console-mode-probe |
| `crates/spt-daemon` | dispatch_fixture, service_fixture, xlate_choreo_fixture |
| `crates/spt` | translate_proof_fixture, post_step_fixture, gh_fixture, git_fixture |

**44 literal `sibling_bin("…")` call sites**, all in `crates/spt/tests/`, served by **29 copied
resolvers**. Split by whether the BUILD IS ALREADY GUARANTEED — which is not the same question as
whether the env var is available, and an earlier version of this entry conflated the two:

| class | sites | detail | build guaranteed? |
|---|---|---|---|
| **cross-package** | **33** | mock-session 26, mock-shell 6, service_fixture 1 | **NO — the hazard members** |
| **same-package** | **11** | translate_proof_fixture 7, git_fixture 2, post_step_fixture 1, gh_fixture 1 | **YES — already, by construction** |

⚠ **MEASURED TWICE, and it falsifies what this entry said on 2026-08-03 before this revision:** cargo
builds **every bin target of a package whenever it builds ANY integration test of that package** —
that same act is what sets `CARGO_BIN_EXE_*` in the first place. So the 11 same-package sites were
never unexpressed in a way that could bite, and the hazard population is **33 cross-package sites
plus the one unit-test member = 34**, not 44.

- **Probe 1 (todlando, root pool):** deleted all four `translate_proof_fixture` artifacts (both
  hash-suffixed harness exes, the `deps/` plain exe, the uplifted plain exe), confirmed absent, then
  built ONE UNRELATED and UNMODIFIED integration test of the same package —
  `cargo test -p spt --test attach_wedge_e2e --no-run`, exit 0, 14.45s. Both plain exes returned with
  fresh mtimes; the hash-suffixed harness exes stayed absent, which is what distinguishes a bin
  DEPENDENCY build from a `--bins` harness build.
- **Probe 2 (doyle, `.worktrees/gate-ec5f38a` pool, independent replication with a different fixture
  and a different probe test):** deleted `gh_fixture`'s plain exe, its `deps/` plain exe AND its
  hash-suffixed harness exe, confirmed all three absent, then built `--test json_emit --no-run`
  (exit 0) — a test that never names `gh_fixture`. The plain pair returned at a FRESH mtime (09:13
  against the 09:00 it carried before), so this is a real build and not the hardlink uplift this
  entry warns about elsewhere; the harness exe stayed absent.
- **Neither probe needs a baseline arm:** the probe test is unmodified and references nothing under
  edit, so what it measures is cargo's behaviour, not anyone's change.
- **Corroborated by this entry's own field data:** neither original member was a same-package
  integration site — member 1 is a UNIT test, member 2 is CROSS-package. The class never had a
  same-package integration member, and the CI-member section below already stated the governing rule
  (`CARGO_BIN_EXE_*` is set only for integration tests and benches of the declaring package) one
  section before the remedy drew the opposite consequence from it.

Command: `git ls-files '*.rs' | xargs grep -hon 'sibling_bin("[a-z_-]*"' | sed 's/.*sibling_bin("//;
s/"//' | sort | uniq -c`.

⚠ An earlier report gave 48 sites and a 6/11/37 split. Take the table above: it counts only literal
call sites in tracked files and it ships its command. The 11 is the same 11 in both counts.

**The LOCATION half of this class is already closed** by `crates/spt-term/tests/support/fixture_bin.rs`
— a shared resolver rather than 29 copies. It does not close the BUILD half, and should not be
mistaken for having done so.

#### REMEDY SHAPE (not ruled)

The distinction that matters is location vs. build:

1. **The 11 same-package sites are NOT hazard members and need no build fix.** Their build edge
   already exists (see the two probes in POPULATION above); `env!("CARGO_BIN_EXE_<name>")` for the
   fixture itself would add nothing to it. Converting them is a **CLARITY** change, worth doing on
   its own smaller merits — the path becomes the one cargo actually emitted rather than a string-join
   of a directory anchor and `EXE_SUFFIX`, five copies of `sibling_bin` stop existing (29 → 24), and
   it completes a migration already paid for: `crates/spt/tests/fixtures/translate_proof_fixture.rs:7-12`
   records that the fixture was re-homed into `spt` precisely to obtain
   `CARGO_BIN_EXE_translate_proof_fixture`, and then all 7 call sites resolved by path anyway. **It is
   not a build fix and must not be filed as one.**
2. **The 33 cross-package sites cannot**, by cargo's design. Their options are an asserted build in
   the test's own setup, a `dev-dependencies` artifact dependency, or an explicit documented
   prebuild — the ci.yml:106 shape, made a rule instead of a local fix.
3. **Standardising on one wider invocation is NOT a remedy.** It changes which pools happen to work;
   it does not create the dependency edge, and the two original members had opposite polarity under
   exactly that theory.
4. Collapsing the 29 resolver copies is worth doing on the `fixture_bin.rs` model, but on its own it
   makes the class HARDER to see — one shared resolver still anchored on `CARGO_BIN_EXE_spt` hides
   the 33 genuinely unexpressed dependencies among its 44 call sites behind one function.

#### SUPERSEDED FRAMING, KEPT SO IT IS NOT RE-DERIVED
- **Status of the original filing:** open · **Origin:** todlando 2026-08-03, both members hit on the
  LOCKSMITH t1 lane against fresh throwaway pools; each discharged in-lane as a rig artifact, filed
  here so the next clean rig does not re-diagnose them as code reds.
- The first two versions of this entry framed the class as "the rig's command does not build what
  the test needs" and proposed standardising on a wider invocation. **Both are superseded by the
  measured mechanism above** — the dependency is not under-expressed, it is INEXPRESSIBLE in the
  form these call sites use, so no choice of invocation creates it. Kept only as the two FIELD
  MEASUREMENTS that produced the class, which remain true:
- **MEMBER 1 — MEASURED:** `cli::tests::adapter_translate_proof_gates_on_commit` failed on the
  first `cargo test -p spt --bins` run. Its fixture binary `translate_proof_fixture` (a
  `tests/`-homed `[[bin]]`) was ABSENT from the pool — `ls` on the path returned No such file.
  Building it explicitly and re-running the IDENTICAL command PASSED, after which the full `--bins`
  suite passed 584/585 with only the releases#117 probe red (that one RED by design). So the
  discriminator is the fixture's presence, not the tree: same command, same sha, red then green
  across one `cargo build` of the fixture.
- **MEMBER 2 — MEASURED:** `cargo test -p spt` does not build `mock-adapter --bin mock-session`, so
  `attach_wedge_e2e` panics `"the dummy-harness program must be built"`. Note the polarity is
  INVERTED against member 1 — there the narrower `--bins` was the defective invocation and
  `cargo test -p spt` the correct one; here `cargo test -p spt` is itself insufficient. So the
  class is NOT "use the wider command"; it is that the dependency is not expressed to the build at
  all, and which invocation happens to work is incidental.
- **What/why (still true):** on a WARM pool the helper is already there from some earlier run and
  the test passes, so the defect is invisible exactly where most people work and fires only on a
  clean pool — i.e. on a GATE RIG, which is the one place a false red costs the most.
- **The sweep this entry once called its first step HAS BEEN RUN** (todlando 2026-08-03) and its
  result is the POPULATION section above. It is no longer outstanding.

- **Why it is register debt and not a lane bug:** nothing in the product is wrong. The gap is
  between what a test needs built and what the rig's command builds, and the fix belongs to the
  tests' declarations, not to whoever is running a gate that day. Sibling rule:
  [[gate-clean-target-not-incremental]].
- **Ripe when:** the next gate-rig or CI-touching wave. Cheap, and it pays for itself the first time
  it stops someone chasing a phantom red on a clean pool.
- **Size:** remedy (1) is small AND optional — it buys clarity and subtraction, never a build edge;
  medium for (2), which is a design call before it is an edit and is the only remedy that closes the
  class.

### IR-22 — An inherited identity env var fails a test, and the diagnostic names them ONE AT A TIME so a correct fix reads as no fix
- **Status:** open · **Origin:** todlando 2026-08-03, chasing what looked like an `attach_wedge_e2e`
  code red on the LOCKSMITH t1 lane; root-caused to the runner's own process environment.
- **MEASURED:** `attach_wedge_e2e` failed for an INHERITED PROCESS-GLOBAL and nothing in the tree:
  the daemon-stop refusal fired on the running session's own identity env. It named
  `$OWL_SESSION_ID`; clearing that made it name `$SPT_ENDPOINT_ID`. With `OWL_SESSION_ID`,
  `SPT_ENDPOINT_ID`, `SPT_AGENT_ID` and `SPT_SESSION_ID` all cleared: exit 0, 1 passed.
- **The finding is the DIAGNOSTIC SHAPE, not the env hygiene.** Naming one variable at a time means
  a correct partial fix produces an identical-looking failure, so the natural reading of "I cleared
  it and it still fails" is that the clearing did not work — when in fact each step was right and
  the message had simply moved on to the next name. A refusal that can only ever name one member of
  a set it is checking teaches the person debugging it the wrong lesson. Compare the same class in
  [[IR-15]]/[[IR-18]] terms: the instrument is competent and the report is not.
- **Why it matters beyond one test:** any agent running suites from a live spt session carries these
  vars, so this fires for every builder on a perched session and for nobody running from a bare
  shell — which is precisely the split between how builders work and how CI runs.
- **Candidate remedies (not ruled):** have the refusal name EVERY identity var it found set, in one
  line, rather than the first; and/or have the affected tests clear the identity set in their own
  setup so a perched session is not a special environment. The first is the one that pays off
  outside this test.
- **Ripe when:** next CI/test-hygiene wave. **Size:** small.

### IR-23 — `endpoint_teardown_authority_e2e`'s two tests collide with EACH OTHER through the machine-global spt home
- **Status:** open · **Origin:** todlando 2026-08-03, LOCKSMITH t1 lane.
- **MEASURED:** both tests copy a psyche binary fixture into `perch::spt_home()/srcs/dummyharness/`
  (`crates/spt/tests/endpoint_teardown_authority_e2e.rs:399`), which is process-global, so run in
  parallel inside one binary each holds the file the other wants: `os error 32`, "used by another
  process". **Signature: WHICH of the two fails alternates between runs.** Under
  `--test-threads=1`: 2 passed, exit 0 — and the wall clock drops from 182s to 14s.
- **What/why:** two defects in one, and they should not be conflated. (1) The tests are not
  isolated from each other. (2) The staging path is the MACHINE-GLOBAL spt home rather than the
  test's own temp home — on a box that is also a CI runner, so the blast radius is not confined to
  the suite. (2) is the one worth fixing; (1) is a symptom of it.
- **Note on why this is not already caught:** the standing rule is that integration tests run
  through nextest, which gives each test its own process and hides the collision entirely. So this
  is latent on the sanctioned path and only bites the bare `cargo test` path — the rule is working
  and masking a real defect at the same time, which is why the entry exists rather than a shrug.
- **Candidate remedy (not ruled):** stage the fixture into the test's own temp home. Sweep for
  siblings first — any other test writing under `perch::spt_home()` rather than a temp home shares
  the shape, and nobody has counted them.
- **Ripe when:** next test-hygiene wave; the 182s -> 14s figure makes it pay for itself on the
  bare path. **Size:** small per test, unknown until the sweep.

### IR-24 — `reap::terminate_job` discards `TerminateJobObject`'s return, alone among its own module's siblings
- **Status:** open · **Origin:** todlando 2026-08-03, swept while building [[IR-16]]; deliberately
  NOT folded into that lane (doyle ruling, same day) and filed instead.
- **MEASURED:** `crates/spt/src/reap.rs:207-211` calls `TerminateJobObject` and discards the result,
  the identical shape [[IR-16]] closed at `spt-daemon`'s `kill_tree`. Its own module's
  create/assign siblings at `:178` and `:202` ARE instrumented, so this call is the odd one out
  where it lives — the module already decided that these returns are worth reading.
- **Why it was NOT folded into IR-16:** different subject. IR-16's site is a SUPERVISED SERVICE's
  teardown, where the loss is "a supervised service's descendants survive" and the promise it
  breaks is `REQ-RESIDENT-SERVICE`'s tree claim. This site is the BRAIN SUBTREE's kill-on-close
  job, which has its own lifetime, its own caller and its own answer to "what does a failed
  termination cost here" — and that answer has not been written down by anyone. Folding it in would
  have meant settling that question in passing, inside a commit about the supervisor, which is how a
  second ruling gets smuggled into a lane scoped to one.
- **What it needs that IR-16's fix does not supply:** IR-16 ruled a LOUD REFUSAL (option B) on the
  ground that the alternative — a process-table tree-walk fallback — is measured blind in exactly
  that failure state ([[IR-18]]: descent breaks at the dead middle hop) and would trade a silent
  loss for a false clean. Whether the same reasoning holds here depends on whether this site kills
  its direct process in the same breath, which is what makes the middle hop dead by construction
  there. **That is the first thing to check, and it is not assumed.**
- **Ripe when:** any wave touching reap/teardown; it inherits IR-16's vocabulary and its
  discrimination note, so the second one is cheaper than the first. **Size:** small, once the
  cost-of-loss question is answered for this subject.

### IR-25 — `spt-daemon --lib` reds 2-in-3 under concurrent load with bare `cargo test`, and holds green under nextest
- **Status:** open · **Origin:** doyle 2026-08-03, found while gating LOCKSMITH tranche 1 in an
  isolated worktree; chased to a mechanism and scoped OUT of the release path before the head was
  assembled.
- **MEASURED, four arms, same box, same hour, matched load** (a second `cargo test -p spt-store
  --lib` loop running throughout; `spt-store` itself stayed green in every round, so the box was not
  generically failing):

  | tree | instrument | result |
  |---|---|---|
  | lane `ec5f38a` | `cargo test --lib`, at rest | 821/821 ×4 |
  | lane `ec5f38a` | `cargo test --lib`, under load | **2 of 3 RED** (142s, 117s) |
  | lane `ec5f38a` minus its 5 new tests | `cargo test --lib`, under load | 3 of 3 green (117s, 84s, 105s) |
  | main `932e14b` | `cargo test --lib`, under load | 3 of 3 green (97s, 119s, 104s) |
  | lane `ec5f38a` | **`cargo nextest run`, under load** | **3 of 3 green, 821/821** (88s, 85s, 72s) |

- **Three DIFFERENT victims across two loaded runs**, all process/timing-shaped, all PRESENT AT MAIN
  and green there: `servicehost::…a_service_that_ignores_the_stop_marker_is_force_killed_and_confirmed_dead`
  (panics `ForceKilled must MEAN the owned child is gone` right after `SERVICE_KILL_UNCONFIRMED`),
  `applyhost::…broker_reports_its_compiled_image_version_over_ipc`, and
  `daemon::…a_tree_teardown_reaches_a_grandchild_the_service_spawned`.
- **MECHANISM: in-process thread interference, not product code.** Bare `cargo test` runs a crate's
  tests as threads in ONE process. The lane's five new tests are process-spawning kill-tree tests;
  under load they starve confirm windows of NEIGHBOURING tests that were always marginal. Removing
  exactly those five flips 2-of-3-red to 0-of-3-green at the same sha, in the same binary, at the
  same durations — one of the green runs sits at 117s, precisely a duration that had produced two
  failures with them present.
- **IT DOES NOT REACH GOLDEN.** nextest gives every test its own process, and golden runs nextest.
  The population is GATE RIGS AND LOCAL RUNS — the same population as [[IR-21]], reached by a
  different mechanism, which is why these are two entries and not one.
- ⚠ **The instrument switch is the whole finding.** Measured with bare `cargo test`, this reads as a
  lane blocker; measured with the tool CI actually runs, it is a rig-scoped nuisance. Anyone
  re-opening this must state WHICH instrument produced their observation before quoting a verdict.
  The same tool gap acquitted [[IR-21]]'s golden question the same day.
- ⚠ **The pre-existing fragility is NOT thereby closed.** Those three tests were marginal before this
  lane and the lane only exposed them; "make the new tests quieter" would re-hide a real weakness.
  Hardening them is test-side work (hertz's lane by the dispatch split), not the builder's.
- **Two rig defects of the gater's, recorded because they nearly cost the verdict:** (1) a first
  re-run at rest came back 4/4 green and proves NOTHING — a sequential idle probe cannot express a
  load-sensitive failure, so that is a competence-controlled zero, not an acquittal; (2) the first
  baseline attempt ran its two arms UNSYNCHRONISED (the load generator finished while the measured
  arm was still on run 1), which would have compared a loaded lane against an idle main and read as
  "the lane broke it". A discriminator whose arms ran under different conditions cannot discriminate.
- **Ripe when:** alongside [[IR-21]] on the next gate-rig or CI-touching wave, or immediately if
  anyone starts gating on bare `cargo test` on a loaded box. **Size:** small to document the rig
  rule (gate with nextest); medium to harden the three marginal tests.
