> CI / boxes / infra sub-index — split out of MEMORY.md 2026-08-03 (doyle) to cure index-over-read-limit
> truncation. Entries VERBATIM from the index; consult when working CI, runners, pools, rigs, or
> teardown on shared boxes. This file = mechanisms+rules for infra surfaces; not the population either.

## Boxes / CI / infra
- [seedmap = STARVATION](seedmap-test-collides-live-daemon.md) gate box AND runner · [runner deaf](runner-online-but-deaf.md) · [disk-full CI](hfenduleam-disk-full-ci.md) · [flynn shares it](hfenduleam-hosts-flynn.md) · [leaked daemons + RANDOM-VICTIM family](e2e-leaked-daemons-shared-box.md) ⭐⭐ a DIFFERENT test dying each run on ONE sha = ONE env cause, not N flaky tests; hardening members never closes it. ⛔ leg 3 (move the runner off this box) is an operator NON-OPTION — upheld 2026-08-04, do not re-propose · [no machine-wide kill](no-machinewide-killon-shared-runner.md) · [which is the listener](spt-daemon-is-live-infra.md) · [reap only your own](rig-ownership-reap-only-your-own.md) · [authenticated ancestry](reap-root-needs-authenticated-ancestry.md).
- [merge-push RE-OCCUPIES the box](merge-push-reoccupies-the-box.md) ⭐⭐ the ff-push CONCLUDING a golden STARTS the automatic post-merge ci run on this runner — "golden green, box is free" is FALSE for minutes after the merge; box empties after the POST-MERGE run, not the golden. Runner's own target ⇒ CPU contention only, no pool at risk. Parent-chain a stray cargo to `Runner.Worker.exe`; sequence around it (⛔ never re-propose moving the runner, line above).
- Pools — [stale false-green](shared-target-stale-false-green.md) tell = test COUNT · [two live trees](shared-target-two-live-trees.md) · [sccache keys on path](sccache-target-path-in-key.md) · [preflight hang](delegate-build-preflight-hang.md).
- [a cold pool costs 2,500 worktrees](a-cold-pool-costs-2500-worktrees.md) MEASURED 2026-08-22: 45 worktrees = 0.79 GB, 3 pools = 130.45 GB. Disk is spent by CONCURRENT POOLS, never worktree count — pruning worktrees is a day of work for <1 GB and leaves the lever untouched. Ceiling: TWO live pools against the 40 GB floor (the floor event happened at FOUR).
- Teardown — [classify first](gate-worktree-target-disk.md) · [junction FIRST](worktree-target-junction.md) · [never into scratchpad](scratchpad-target-trees-eat-the-box.md) · [no inbound link](in-tree-target-has-no-inbound-link.md) · [subtree not session dir](reap-subtree-not-session-dir.md).
- [preservation is an OWNED step BEFORE the release call](preservation-is-an-owned-step-before-the-release-call.md) ⭐⭐ ruled doyle + banked independently by deployah 2026-08-29: naming an artifact worth keeping INSIDE the pools-released broadcast is a starting gun to everyone able to destroy it — todlando's verbatim copies lost to my reap by ~1 min, only prior diff-snapshots saved the 830-line instrument. Preserve (named owner, path + hash confirmed on the record) FIRST; release as a SECOND message gated on the confirmation; a preserved patch's restore COST (applies-at-main or not) is part of the preservation.
- [`cargo run -p xtask -- gen` DEADLOCKS](xtask-gen-deadlocks-under-cargo-run.md) ⭐⭐ xtask shells to `cargo build -p spt` under the OUTER cargo's target lock; silent, 40min of nothing. Run `target/debug/xtask.exe gen` directly; tell wedged from slow by CPU (a blocked rustc burns none), never by elapsed time.
- [inserting a clap variant orphans the next doc block](inserting-a-clap-variant-orphans-the-next-doc-comment.md) the new verb ships the OLD verb's help and the old ships none; read the `xtask gen` diff for rows you did NOT touch.
- [no warm CI target](ci-runner-has-no-warm-target.md) ⭐⭐ checkout `git clean -ffdx` kills it each job; floor read BEFORE its own reclaim = red over bytes the next step deletes.
- Pins — [holder death ≠ lane state](pool-claim-holder-death-is-not-lane-state.md) ⭐⭐ 3/3 dead holders, one a LIVE lane; decide from git ancestry · [orphan or own cwd](worktree-pin-holder-triage.md) · [pool-claim false orphan](worktree-pool-claim-false-orphan.md) · [orphan conhost](orphan-conhost-cwd-pins-worktree.md) · [husk cleanup](wt-single-process-husk-cleanup.md).
- [a pool MARKER without lane identity answers nothing](pool-marker-without-lane-identity-answers-nothing.md) ⭐⭐ 2026-08-29 disk event, 4th face of the false-read class: `POOL-OWNER.json` held ONLY `owner_tree` + `written_by: spt-poolguard` — a poolguard MARKER, not a `pool-claim` record (no `lane`/`branch`/`base`); that pool PREDATES the claim discipline, so the population is not fully claimed and a missing claim is not evidence of an unowned lane. Second half, the one that nearly mis-reaped: **NOT-ancestor-of-origin/main ≠ stray** — `0ebe0fbd` was the BASE of `d0fdd58d`, a live SEMAPHORE #241 head; `git branch --contains` is the cheap discriminator, ancestry vs main alone returns the same answer for a dead stray and a live lane's base. Reap authorised on 3 named arms instead: clean `status --porcelain`, `ls-remote --heads origin` at the IDENTICAL sha (durable off-MACHINE, not just off-worktree), regenerable target. +38.38 GB, free 70.1. Also: "written TODAY" was true and read as live — newest file 01:48, ZERO newer than 02:00, ~7.5h cold; and the co-author trailer needs a RAW BODY read (`--format=%b`) or the owner reads as absent.
- [free-space floor](free-space-floor-blocks-golden.md) 32GB, LNK1318, resource red = UNTESTED · [serial legs share workdir](serial-legs-share-runner-workdir.md) · [two runs per sha](two-runs-per-sha-notification-trap.md) · [thin lane skips int](thin-lane-ci-skips-integration-tests.md) · [opt-in legs skip silently](opt-in-ci-legs-skip-silently.md) skipped = SILENCE · [traceability gate](ci-traceability-gate.md) · [no internal codes](public-help-no-internal-codes-gate.md).
- [self-host migration](ci-selfhost-migration.md) · [kitsubito speedup](ci-kitsubito-speedup-plan.md) · [kitsubito rig](kitsubito-linux-rig.md) · [wifi-only QUIC seam](kitsubito-wifi-only-quic-seam.md) · [linux runner](linux-runner-migration.md) · [cross-machine rig](cross-machine-test-rig.md) · [gravity deploy](gravity-deploy-procedure.md) · [mirror CI dead](mirror-repo-ci-dead.md).
- [unit-lane isolation](unit-lane-inprocess-isolation.md) · [fixture bins](spt-bin-lane-fixture-bins.md) · [bin-name collision](workspace-bin-name-collision.md) · [libsqlite3-sys corruption](libsqlite3-sys-artifact-corruption.md) · [UAC 740](windows-uac-binary-name-740.md) · same mechanism, second write-up [uac740 dup](win-update-exe-uac740.md) · [PATHEXT shim](ccs-win-pty-program-resolve.md) bare node CLI → os error 193 · [console flash](translation-binary-console-window-bug.md) new spawn site missed CREATE_NO_WINDOW · [IPv6 poisons iroh](broken-ipv6-poisons-iroh-discovery.md) · [service-detection](daemon-service-detection-gotcha.md) · [Linux SPT_HOME no-bug](linux-spt-home-no-bug.md).

- [twohost runs in a TEMP SPT_HOME](twohost-runs-in-its-own-temp-spt-home.md) ⭐⭐ rig sets `SPT_HOME` to a TempDir at test entry and spawns its OWN daemons; "canonical stores" in the comments = paths INSIDE that home. The resident broker version CANNOT enter a twohost result — I built a pair-roll rule and a golden ban on the opposite premise. Open axis: relay-mediated rendezvous.
- [broker cutover refuses from a PERCHED shell](broker-cutover-refuses-from-a-perched-shell.md) ⭐⭐ `spt update --restart` hits the same `OWL_SESSION_ID` guard as `daemon stop` (no flag overrides) and **EXITS 0** — releases#153; a plain-ssh success does NOT generalise to a perched shell, the caller's ENVIRONMENT is the variable. Installed/coordinator image ≠ RUNNING broker image.
- [read enforcement state in the RUNNING image's tree](inert-on-this-version-kills-a-probes-discrimination.md) ⭐⭐ a version banner's prose ("INERT on earlier versions") got 4 agents to mis-scope a real wire falsification; `git show v0.52.0:…/wan.rs` showed tier 1 LIVE and abstaining. If the box runs an older image than your checkout, main is the WRONG tree.
- [dir LastWriteTime is BLIND to nested writes](dir-lastwritetime-is-blind-to-nested-writes.md) ⭐⭐ called a build pool "15 days cold" off the dir stamp; it had been built into that morning — newest nested file was 15 days newer. Root stamp tracks only its OWN entry list. Take max(LastWriteTime) over files in the same walk as the size sum — and answer LIVENESS by process census / claim holder, never by a timestamp.
- [literal \n glues the co-author trailer](literal-backslash-n-glues-the-coauthor-trailer.md) ⭐ trailer mid-line after literal backslash-n = invisible to ci-notify's anchored sed, attribution silently doyle-only; audit anchored per commit, fix by message-only reword, verify tree-id equality so measurements carry.
- [pool-release refusal TAIL reads as a release confirmation](pool-refusal-tail-reads-as-release-confirmation.md) ⭐⭐ the releases#103 blurb closes a `SPT_POOL_FOREIGN` REFUSAL too — `tail -2` turned four failed builds into four apparent successes, all four POOL-OWNER.json still on disk. Verdict token is at the TOP. Also: the release tool is BUILT THROUGH the pool it would release (a bad claim blocks its own fix), and a claim OUTLIVES its worktree (root pool owned by a gate-204 that no longer exists). Reaping the target subtree kills the claim with it.
- [a config fix is verified against the WINNING merge, not your file](config-fix-verified-against-the-winning-merge-not-your-file.md) ⭐⭐ kitsubito 2026-08-25: my `50-backlog.rules` lost the augenrules lexical merge to apt's own `audit.rules` (digits sort BEFORE letters; last directive wins) — kernel silently kept 8192/60000 through a proof run while the fragment grepped perfect and `--check` said "No change". Verify at the EFFECTIVE layer (`auditctl -s`/sysctl readback), read the RENDERED merge, edit the winning file, restart-cycle once and read back again. "Remediation done" in a commune is a claim; the readback is the measurement.
- [cargo REPLAYS a cached build-script's warnings](cargo-replays-cached-build-script-warnings.md) ⭐ deployah, v0.63.0 publish: the green publish build printed the SPT_POOL_UNCHECKED override warning naming a lane that had already been taken over — cargo replayed the PRIOR invocation's stored build.rs output (0.85s, build.rs did not re-run); the env var was NOT set and the on-disk owner record was correct. A build-script diagnostic in a log dates the last EXECUTION, not the invocation that printed it — check whether build.rs actually re-ran before reading its warnings as that build's state.
- [warm rig ≠ spent pool](warm-rig-is-not-a-spent-pool.md) ⭐ 2026-08-29 disk event: "HEAD is ancestor of origin/main" nearly reaped the deliberate W2-W4 warm gate rig (43 GB, would re-derive at gate time into the same thin disk) — "landed" classifies the LANE, a pool also has a FUNCTION axis (spent vs still EARNING for a named future consumer); ask the owner / check the kept-deliberately note first. Same event: ancestor tests against a STALE local main called five landed lanes NOT-IN-MAIN — test against origin/main.
- [a PR open is a CI battery on BOTH runner boxes](a-pr-open-is-a-ci-battery-on-both-runner-boxes.md) ⭐⭐ 2026-09-07: "open the PR at the tip" mid-battery → Windows CI died on disk-full, kitsubito CI `rust-lld` OOM-killed INSIDE the runner cgroup (15 GB), runner unit stayed `failed` (relaunch did not stick) — zero test signal on both, reads as a red head. Open PRs only when both boxes are free; after a "shutdown signal" red, `systemctl is-active` the kitsubito runner and `reset-failed`+`start` it (sudo -n works).
- [a shared tool binary can flip under a live gate](a-shared-tool-binary-can-flip-under-a-live-gate.md) ⭐⭐ 2026-09-07: traceable-reqs.exe 0.2.0→0.4.0 at 02:34Z by an unannounced hand; same tree exit 0→1/396 findings on EVERY lane incl. main, wearing a code-regression shape. Criterion = the CI PIN (ci.yml WANT=), not PATH; classify a window leg by its OUTPUT SHAPE + clock vs exe mtime; pin back, keep the .bak as control, adoption is its own lane (IR-37).
