---
name: gate-rig-mechanisms-not-remembered-steps
description: "Gate-rig steps that keep failing as remembered discipline — workspace prebuild leg 0, exe sweep before every cargo line, LEG OMEGA end-of-battery daemon kill (bite #7: 12 leaked daemons), df+stale-target reclaim at leg 0."
metadata: 
  node_type: memory
  type: feedback
  originSessionId: 82118e6c-5d10-4230-aef4-ed67f20814ba
  modified: 2026-08-03T14:23:42.245Z
---

Two rig steps have now failed their own authors repeatedly (6 bites by 2026-07-21, twice in one hour in the gater's hands). Both are mechanism-shaped, not discipline-shaped — stop trying to remember them.

1. **Prebuild the WORKSPACE as an unconditional first rig leg.** Bite #6 (2026-07-21, rc-resize-geometry-epoch gate): the battery script omitted the prebuild line ENTIRELY — "prebuild `-p mock-adapter`" is still a remembered step, and forgetting it cost 25 fail-fast e2e reds (missing `mock-session.exe`) that read as a branch-wide regression until rerun. The mechanism is now: every battery's leg 0 is `cargo build --workspace` into the throwaway target (clippy `--workspace --all-targets` does NOT emit exes — check profile builds nothing runnable). A package list is the same defect as a bin list, one level up.
2. **Sweep leaked `target\debug\spt.exe` before EVERY cargo invocation**, exe-path-scoped (never machine-wide on a shared runner) — not once before the suite, not once before xtask. A leak from run N holds the link/write lock for run N+1's BUILD, so the failure surfaces as `Access is denied. (os error 5)` or a link error and zero tests execute.

**Why:** both failures LOOK like a red in the code under test and are not. Placement judgement missed twice in one session by the person who wrote the rule about rules that fail their authors — that is the proof the step must be a mechanism (a `sweep()` call, a package-scoped build) rather than a remembered ordering.

3. **Leg omega = kill your OWN spawned test daemons at battery END, then leg-0 of the NEXT gate re-sweeps.** Bite #7 (2026-07-22, NOTIF-TRUTH W1 gate): the W1 battery's between-leg sweep only ran BETWEEN legs — the battery finished green and exited, and **12 spt.exe leaked from `.worktrees/gate-d289787/.gate-target` sat alive for 4+ hours holding ~2.7k handles on the CI host**, becoming contention evidence in the v0.40.0 gate-red incident (deployah's census caught them). The end-of-battery kill is the mechanism: final `sweep()` AFTER the last leg, target-path-scoped, BEFORE worktree removal (a daemon running from the target also pins the worktree). And leg 0 of every battery re-sweeps `*.gate-target*`-pathed processes from PRIOR gates — a dead session never cleans up after itself.
4. **Leg 0 also checks `df` + reclaims stale `gate-*`/`tgt-*` throwaway targets** in the claude temp tree ([[hfenduleam-disk-full-ci]] 07-21 mechanism — disk starvation presents as timing-assert reds, not just link errors).

**How to apply:** in any gate/loop script: leg 0 = df-check + stale-target reclaim + prior-gate exe sweep + `cargo build --workspace` (throwaway target); `sweep()` immediately before each `cargo` line; leg omega = final sweep before worktree removal. When a suite fail-fasts early, report it as UNJUDGED — never as a partial pass. Related: [[gate-clean-target-not-incremental]] · [[no-machinewide-killon-shared-runner]] · [[rule-failed-its-author-needs-a-mechanism]] · [[hfenduleam-disk-full-ci]] · [[teardown-authority-progress]]

**BITE #8 — THE SWEEP IS STILL NOT IN MY SCRIPTS (2026-08-03, #134 lane).** I wrote a mutation-battery driver with a real dirty-tree refusal mechanism in it, and did NOT put the exe sweep in the same script. Predictable result: after the e2e legs, `cargo nextest` died with `failed to remove file ...\target\debug\spt.exe: Access is denied. (os error 5)` and **8 leaked `spt.exe` were live out of my pool** — path-scoped sweep killed 8, 0 after, re-run 5/5. ⭐⭐ **This is releases#123's class (the golden's `prerelink` reap) reproduced LOCALLY** — it is not a CI-only hazard: any local gate that runs an e2e and then relinks hits it, because Windows cannot overwrite a running image. So the sweep belongs in the RIG SCRIPT beside the dirty-tree refusal, not in the operator's head; a driver that mechanises one precondition and remembers the other will keep paying for the remembered one. Sweep predicate that worked: `Get-Process | Where-Object { $_.Path -and $_.Path.StartsWith($pool, OrdinalIgnoreCase) }` — path-prefix scoped, never by process NAME (this box hosts doyle's daemon and flynn).

**LEG-0 EXTENSION (2026-07-22, W3 gate LNK1318 incident):** leg 0 = df + stale gate-target sweep + **shared-checkout-target SIZE CHECK against a ~100 GB ceiling** — when over, cargo-clean it under the declared-window discipline (verify no cargo/rustc/link/nextest + nothing executing from it, announce, sweep, ALL-CLEAR). The shared checkout target regrew 205 GB in 3 days (7-19 clean → 7-22 incident); lane-close doctrine covers only lanes — the shared target has no close trigger, so the gate rig is its trigger. Also: NEVER pipe battery legs to tail inside a && chain — the pipe masks the leg's exit and the chain runs on over a dead build (this incident's second bite: nextest LNK1318 exit-101 read as leg-4-reachable). Capture exits per leg.

**VERDICTS-FROM-EXITS (2026-07-22, both agents bitten same week):** grep/tail the output for DETAIL; take the VERDICT from the EXIT — never let a pipe be the last thing in a chain (`cmd; echo EXIT=$?` or pipefail). todlando's `clippy | grep ^error | head` reported "clean" as absence-of-matched-lines with the status discarded; doyle's `nextest | tail` read LNK1318 exit-101 as leg-4-reachable. Positive harness lines ("test result: ok", "Finished dev profile", "xtask check: OK") are real evidence; SILENCE is not. Every gate leg records its exit in the verdict.

**CWD-INDEPENDENT BATTERY COMMANDS (2026-07-22, 4 consecutive self-caught misfires):** background Bash starts in the SESSION cwd, and a composed `cd <worktree> &&` prefix repeatedly failed to survive into the submitted command — four kills in a row before the mechanism replaced the intent. Rig rule: NEVER anchor a gate battery on cd. Anchor on `cargo <cmd> --manifest-path <abs>/Cargo.toml` + `CARGO_TARGET_DIR=<abs>/target-gate` + absolute log paths — the command is then correct from any cwd by construction. (Also the reason the retry rig red on `prebuild the player` was possible: the W3 rig resolves fixture bins at `<root>/target/debug` HARDCODED, ignoring CARGO_TARGET_DIR — second instance of the REQ-XTASK-SPT-BIN-TARGET-DIR class, fix post-merge with #13; interim = build the bins into the worktree's default target too.)
