title = "A PSYCHE FAULT STAMP REMEMBERS WHICH LATCH SLOT PRODUCED IT, SO A DAEMON RESTART CANNOT CLEAR A FAULT IT NEVER SAW. ROOT (releases#115): the three fault latches -- latch_turn, latch_ingest, latch_timeout -- live in memory behind a Mutex and are never seeded from disk, while the `psyche_host_error` stamp they compose to OUTLIVES the process on disk. After a bounce the stamp stands with nothing standing behind it, so the first `note_success` of ANY kind recomposes an empty latch set to None and clears a fault whose kind this process never learned. THE PER-KIND SEPARATION BAROMETER W1 BUILT IS THEREFORE UNDONE BY A RESTART: one working ingest erases a standing turn defect it says nothing about, which is precisely the vouching REQ-PSYCHE-HARD-BUDGET-PER-KIND exists to forbid -- the defect does not lose information at the margin, it re-opens a closed hazard. FIX: the stamp carries a SLOT-KEYED sibling map written by the SAME seam that writes the reason, so the sentence and the latches that produced it can never disagree on disk, and the pulse loop seeds its latches from that map at startup BEFORE any tick can report a success. THE KEY IS A LATCH SLOT, NOT A KIND, and the distinction is load-bearing rather than nominal: there are THREE slots against TWO kinds, because the timeout latch is shared cross-kind by the ruled BAROMETER W1 semantics and belongs to no kind at all -- a kind-keyed reading would be re-read later as a per-kind register and gain a fourth key the day a fourth kind appears. THE VOCABULARY IS CLOSED to those three slots, and an unrecognized key is IGNORED AND ANNOUNCED rather than seeded: an unknown slot can only come from a newer binary owning a latch this one has no code to clear, so seeding it would strand a fault that no success could ever recompose away, while dropping it silently would make a rollback that loses a standing fault look identical to a recovery. A PRE-#115 STAMP CARRIES NO SLOTS AND SEEDS NOTHING, deliberately: its kind is genuinely unrecoverable, and the honest behaviour for an unknown-kind fault is the one that shipped, where any success clears it (REQ-PSYCHE-STAMP-CLEAR-ANY-SUCCESS) -- inventing a kind for it would be worse than forgetting one. `reason` stays BYTE-IDENTICAL, and the map is serde-default plus skip-when-empty so a stamp with no standing latches serializes byte-identically to the pre-#115 shape; N-1 holds in BOTH directions, the old-binary/new-record leg proven by a MEASURED absence of any live deny_unknown_fields attribute repo-wide (zero, on this struct and on InfoJson alike) rather than by assuming serde's default. Gate: impl -- the slot-keyed map on the stamp, written by the single existing writer alongside the reason it composed to, the closed three-slot vocabulary with ignore-and-log on an unknown key, and the pulse-loop seed running before the first tick; unit -- a stamp whose slots record a standing INGEST fault SURVIVES a fresh process reporting a TURN success (the row the shipped code cannot pass, since an unseeded set recomposes to None and clears it), a seeded latch IS still cleared by a success of ITS OWN slot (asserted alongside, since the survival row alone passes an implementation that has simply stopped clearing anything), a pre-#115 SLOTLESS stamp is still cleared by any success (the N-1 behaviour-preservation row), and an UNKNOWN slot key seeds NO latch while a known key beside it in the same map DOES seed (the pair asserted together, since over an unknown key alone a seed-nothing implementation and a correct one agree)." required_stages = ["impl", "unit"] # ACTIVATED LOCKSMITH t1 (evidence lands here); MINTED LOCKSMITH t1 (todlando, 2026-08-03), releases#115. Shape approved by doyle: sibling map INSIDE the existing psyche_host_error, reason byte-identical, serde(default), seeded at pulse-loop startup. Conditions 8 (key by SLOT and name it slot) and 9 (closed vocabulary, defined unknown-key read behaviour) are his and are binding, not preferences. Condition 10 -- the surfaced-field question -- was DISCHARGED before building by a measured reader sweep: 5 src readers, ALL class (a) (they read reason/attempts/ts field-selectively), ZERO serializing PsycheHostError wholesale to a user-visible surface, closed by mechanism (no other Rust type embeds it, and whole-InfoJson serialization happens at exactly one non-test site, write_info_unlocked -> the on-disk record). No `doc` stage: the CONTEXT.md/KNOWN-HAZARDS model text already states the stamp is current-state and cleared by a success, and this fix changes WHICH success clears it, not the model an adapter builds against. [[requirements]] id = "REQ-PSYCHE-INGEST-INTENT-MARKER" title = "A COMMUNE THAT WAS EXPECTED AND NEVER ARRIVED IS DETECTABLE POSITIVELY, PER ATTEMPT, RATHER THAN INFERRED FROM AN ABSENCE. ROOT (releases#96, split out of the #90 recon): the summarizer spawn killed at its bound dies BEFORE writing the drop file, so it produces no file and no ingest -- and every presence-based check is structurally blind to it, because there is nothing on disk to find and nothing failed loudly enough to stamp. AN ABSENCE CANNOT BE OBSERVED; AN EXPECTATION CAN. THE DISCRIMINATOR IS A WRITE-AHEAD INGEST-INTENT MARKER: the lifecycle persists an expected-ingest record (timestamp + trigger) BEFORE launching the summarizer spawn, a completed ingest CONSUMES it, and a marker still standing past the spawn budget with no corresponding drop positively identifies the killed-at-bound case for that attempt -- no staleness threshold to tune and no guessing. THE ORDERING IS THE PROPERTY, not an implementation detail: a marker written after the spawn returns cannot survive the case it exists to detect, exactly as an intention recorded only after an answer arrives cannot survive an answer that never comes. SURFACING rides where the degraded party is already listening -- at resume/compose, beside the un-ingested-drop warning, saying that a commune was expected and never ingested and that the reader may be resuming stale. The marker is therefore written by the daemon lifecycle and read by the CLI compose path, so its storage must serve both. A killed-at-bound attempt counts on the SOFT timeout budget, never the hard one. Gate: impl -- the marker persisted before the spawn with its timestamp and trigger, consumed on ingest completion, the orphan classified past the budget, the resume/compose surfacing, and the storage readable from the CLI compose seam; unit -- a spawn killed at its bound leaves a standing marker with no drop and classifies as the expected-never-ingested case, a completed ingest leaves NO marker (the pair asserted together, since the orphan row alone passes an implementation that never consumes and would then report every healthy commune as orphaned), a marker whose drop IS present is not classified orphaned, and the write-ahead ORDERING is asserted directly by observing the marker from a spawn that never returns -- a post-spawn write passes every other row and fails this one." required_stages = ["doc", "impl", "unit"] # ACTIVATED BAROMETER W1 at impl+unit (evidence lands here). Storage shape ruled by doyle on my recommendation: a perch-dir `commune-intent.json`, atomic, daemon sole writer, CLI compose read-only -- the same shape the perch already uses for daemon-owned per-endpoint sentinels (ready file, echo gate, ops epoch), so neither end invents addressing. Consumed at INGEST, never at spawn-Ok: the expectation is that a commune ENTERS THE TIER, and a drop written but never ingested is the sibling case. ~~`doc` NOT activated: the CONTEXT.md Psyche entry already carries the model sentence ("a commune whose summarizer died before producing its drop is still expected"), and unlike the manifest budget key this surface is agent-facing prose rather than a contract another party builds against.~~ STRUCK AND AMENDED, doc ACTIVATED BAROMETER W1 (deployah 2026-08-02, doyle-ruled, releases#96 comment 5156710377): the struck reason holds ONLY for CONTEXT.md and was written as though it were blanket. It is not. The marker has a second surface: `docs-site/src/harness-contract/echo-commune.md` is the HARNESS CONTRACT an adapter author blind-builds against, and there the expectation model is not prose about ourselves -- it is the reason file-presence cannot be the health signal (the #96 discriminator), the thing an author must know to read a COMMUNE_NEVER_INGESTED resume warning, and the context for declaring a sane `invocation_budget_secs`. doc = the "A bound kill is not a non-zero exit, and it is not silent" section of that page (the tag sits on it), which states the record-before-spawn expectation, the resume-time surfacing, and the current-state overwrite rule. Untagged it would have rested on nobody deleting it -- the class that let a stale hedge survive a full gate in DOORBELL. EDGE RULED (doyle, my recommendation): CURRENT-STATE ONLY, no history count -- a later successful commune overwrites the marker and the warning stops, because the surface answers "may I be resuming stale NOW" and a superseded loss is noise; the killed attempt is still remembered where it belongs, on the soft timeout budget. MINTED BAROMETER W1 (todlando, 2026-08-02), releases#96 -- inactive-first. Marker shape is the operator's bag-grill ruling; storage shape comes to doyle as its own recommendation before it is built (his instruction), since it must be daemon-writable and CLI-readable at the reporting.rs resolve_filedrops seam. [[requirements]] id = "REQ-SHELL-PERSISTENT-BOOT-RESTORE" title = "A `persistent` SHELL COMES BACK AFTER A NODE RESTART, WHICH IS THE ONE CASE THE CONTRACT'S OWN SENTENCE PROMISES AND THE IMPLEMENTATION NEVER HANDLED. CONTEXT.md states it plainly -- a persistent shell is automatically brought online whenever its owner endpoint is online -- and the shipped code honors that across a graceful suspend->wake rest edge ONLY. A machine restart produces no such edge and there is no boot-time restoration at all, so after a reboot every persistent shell on the node stays down until a human runs `relink` by hand, with no surface saying so. Field, HFENDULEAM 2026-08-01: the fleet came up at 01:11 and NOT ONE persistent shell came back; the two instances that did were relaunched by a human at 01:27, sixteen minutes later. TWO INDEPENDENT GATES, both of which must fall or the promise stays broken. GATE 1, no restoration path: the five launch sites all require either an explicit command, a rest edge, or a `wake_command` the adapter may deliberately not declare, and daemon boot starts only the servicehost sweep and the wake reconciler. GATE 2, the stale record blocks the cascade even when an edge DOES arrive: the to_active arm gates on the RECORDED status being offline, and a machine death breaks no link, so the close that would write offline never runs and the record says online over a corpse forever. LEG (a) HEALS THE RECORD TO THE TRUTH, with a BIRTH-STAMPED probe rather than bare pid liveness -- a pid namespace resets at boot, so a corpse pid can be REUSED by an unrelated process, and a reused pid reads alive, makes the derived status read online, and makes `relink` refuse SHELL_ALREADY_ONLINE: the one command that recovers the instance refusing on the very state that is wrong. TWO STAMPS ARE PARKED, NOT ONE, AND THE REASON IS A PLATFORM ASYMMETRY THAT WOULD OTHERWISE SHIP SILENTLY BROKEN ON LINUX: `process_started_at` returns a Windows FILETIME (absolute, comparable across boots) but on Linux returns field 22 of /proc//stat, which is JIFFIES SINCE BOOT and resets every boot, so a value recorded before a restart is indistinguishable from a fresh one after it. The NATIVE stamp is therefore used for one question only -- the same-pid-different-process PAIR test within a single boot, mirroring `liveness::relay_liveness` -- and an ABSOLUTE epoch-ms launch stamp is parked beside it for the cross-boot question. LEG (b) IS A ONCE-PER-DAEMON-GENERATION BOOT SWEEP relaunching persistent instances whose owners are online, and its discriminant is THE LAUNCH STAMP PREDATES THE BOOT INSTANT, which preserves the class-c force-kill ruling BY CONSTRUCTION rather than by a second rule: a force-kill during steady-state operation leaves a corpse launched AFTER boot, so it is never spontaneously relaunched and the mid-deploy exe-overwrite hazard that ruling protects is untouched. A NAMED SLACK CONSTANT absorbs boot-instant jitter so a process launched moments after boot is never misclassified as a corpse. Gate: impl -- the two stamps parked at the two production pid-write sites (the census is authoritative: five LAUNCH sites funnel through exactly TWO pid writes), the birth-stamped death probe, the record heal in the daemon-side reconciler guarded on an actual change of the recorded value, the boot-instant helper on both platforms, and the boot sweep with its predates-boot discriminant plus slack; unit -- a reused pid (same pid, different birth stamp) reads GONE where bare-pid liveness reads alive (the row the shipped probe cannot pass), a same-pid-same-birth process reads HELD, the heal writes offline over a stale online record and writes NOTHING when the record already matches the truth (the guard asserted by counting writes, since a heal that rewrites every cycle passes any state-only assertion), a corpse launched BEFORE the boot instant is eligible for restore while one launched AFTER it is NOT (the class-c pair, asserted together since either alone passes an implementation that restores everything or nothing), and an instance whose OWNER is offline is not restored even though its corpse predates boot." required_stages = ["doc", "impl", "unit"] # doc ACTIVATED BAROMETER W2 doc leg (doyle-ruled, this milestone): the CONTEXT.md `persistent` amendment states the boot sweep and its four conjunct gates incl. no-stamp => not restored, which IS this requirement's doc evidence; leaving the stage inactive would have made it evidence the registry cannot see. [[requirements]] id = "REQ-SHELL-KILL-AUTHENTICATED" title = "A RECORDED PID IS NOT KILL AUTHORITY ON THE PRODUCT PATH EITHER: no shell-lifecycle kill fires until the pid+birth PAIR proves the process at that pid is still the one we launched. BAROMETER W2 authenticated the DERIVATION path (`shellinfo::shell_pid_provably_dead` runs the pair test) and left the KILL path believing a bare pid, so the same recycled-pid state that the derived read correctly calls a corpse still routes to `taskkill /PID /T /F` (unix `kill -9`) against whatever unrelated process now wears that number -- and `/T` takes its whole subtree with it, on the user's machine. Proven reachable by probe, not inferred: a live stranger's pid parked beside a foreign birth stamp is killed by `kill_shell_at` while `shell_pid_provably_dead` calls the same pair a corpse. SITE SHAPE IS TWO CHOKEPOINTS, NOT THREE CALL SITES: `shellhost::kill_shell_at` (reached by `close_shell` and the `spt shell teardown` force path) and `shellwake::kill_waker_at` (reached by `launch_shell`, `close_shell`, `stop_watcher`, and the reconciler), both funnelling into the single `kill_shell_pid` taskkill; the gate therefore lands in the two chokepoints and NO caller changes. THE WAKER HALF NEEDED A WRITE-SIDE MINT BEFORE ANY GATE COULD MEAN ANYTHING: `waker.pid` was written bare, and `relay_liveness(live_pid, None)` is HELD by design (pre-stamp records fail toward alive), so a read-side gate there would have returned Held for every record that exists today and every one written tomorrow -- a VACUOUS gate that proves green. The pair is therefore minted in the waker's single existing write as a two-line `waker.pid` (`\\n`): ONE file, ONE write, so the pair is atomic -- a second file has a torn window in which the pid is on disk and the stamp is not, and that window reads Held, which is the vacuous arm reintroduced as a race. Write and every reader move through ONE shared record/read function pair, mirroring `record_shell_launch`/`read_shell_launch`. FAIL-TOWARD-ALIVE IS THE PARSE ARM TOO: an unparseable record reads None and REFUSES the kill while LEAVING the record, because kill-nothing-and-retire-the-pid-file-anyway orphans a live waker while presenting success -- worse than the defect being fixed. UNPROVEN REFUSES: the destructive arm treats unknown as do-not-fire (consequence asymmetry -- a mis-fire force-kills a stranger's tree, a missed kill leaves our own binary running and observable), which FALSIFIES the shipped unconditional promise that a link-break's force-close always kills and \"the binary never survives\", so `close_shell`'s step 3, the REQ-SHELL-2 language, the CONTEXT lifecycle line and KNOWN-HAZARDS 7.58 are amended together with the code rather than one comment patched. THE REFUSAL IS LOUD: every declined kill names the reason and the pid on the channel the close path already speaks, and the bounded confirm loop reports a binary that outlived it -- a quiet wrong state is the un-RCA-able one, and the harm-asymmetry argument has to hold in the log and not only in principle. THIS NARROWS THE MIS-FIRE, IT DOES NOT ELIMINATE IT, AND THE TEXT SAYS SO: on Linux `process_started_at` reads /proc//stat field 22, which counts CLK_TCK=100 jiffies, so two processes whose starts fall in the SAME 10ms tick carry an identical stamp and the pair cannot separate them. The window closes from ANY recycled pid to A PID RECYCLED INTO THE SAME 10ms TICK AS THE RECORDED START -- which requires our process to die AND the OS to hand its number to a new process inside one tick, a precondition that is its own mitigation. Windows is unaffected (FILETIME, far finer resolution). Measured by hertz on kitsubito; recorded verbatim so nobody re-derives it. THE ASYMMETRY IS WHY THIS IS THE KILL PATH'S SENTENCE TO WRITE: the same predicate with the same imprecision is SAFE on the derivation side and UNSAFE here -- Held means 'stays stale' for a derived read and 'fire the kill' for a destructive one, so only the kill side carries the residual harm and only the kill side has to declare it. Image-path corroboration (which would unify this rule with the rig-side technique in KNOWN-HAZARDS 7.58) is filed past as releases#120, deliberately not taken in a closing milestone. MIGRATION WINDOW, NAMED NOT SILENT: pre-W2 shell records and pre-fix waker records carry no stamp, read Held on existence alone, and keep today's bare-pid kill until their next launch writes a pair. DOWNGRADE DIRECTION, NAMED: an OLD binary reading the NEW two-line `waker.pid` parse-fails to None, which reads as no-pid and refuses the kill -- missed-kill, not mis-fire, the safe polarity. Gate: impl -- the pair gate in both chokepoints, the shared waker record/read pair with the two-line format, every waker.pid reader moved onto it, the loud refusal arms, and the confirm-loop survivor report; unit -- a recycled pid (live, birth mismatch) is NOT killed where the shipped code kills it, a genuine own-process pair (Held) IS still killed so the gate is not vacuous, an absent stamp keeps the pre-stamp kill, Unproven refuses, an unparseable waker record refuses AND leaves the record in place (asserted together, since retire-anyway passes a kill-count assertion alone), and the refusal is observable rather than silent; int -- hertz's probe inverted: a live stranger parked beside a foreign stamp SURVIVES `kill_shell_at` while `shell_pid_provably_dead` still calls the pair a corpse (the control), with the victim checked through `try_wait` on the held handle rather than a pid-existence probe, which reads alive for an already-killed process while the handle is open." required_stages = ["doc", "impl", "unit", "int"] # ACTIVATED BAROMETER W2 reopen in the commit landing the evidence. doc = the KNOWN-HAZARDS 7.58 amend this fix carries (doyle's rider: the entry was scoped TEST-only and that scoping went false the moment the product defect existed, so the de-scope is a mint-time answer, not an assembly-time one). MINTED BAROMETER W2 reopen (todlando, 2026-08-02), releases#114 -- inactive-first per doyle's build order. Kin REQ-HAZARD-TEST-PID-TREE-KILL-IDENTITY (the same invariant on the TEST population, de-scoped from TEST-only by the amend this fix carries), REQ-SHELL-PERSISTENT-BOOT-RESTORE (W2, which authenticated the derive path and minted the shell birth stamp this gate reads), REQ-SHELL-2 (the link-break close whose unconditional-kill promise this narrows), REQ-RELAY-DEATH-CONVERGENCE (`relay_liveness`, the ONE predicate both paths call -- no second discriminant is minted here). -- ACTIVATED BAROMETER W2 at impl+unit once BOTH legs landed -- deliberately not at leg (a), since the gate clause covers the boot sweep too and activating early would have let the requirement read satisfied while half its impl was unbuilt. MINTED BAROMETER W2 (todlando, 2026-08-02), releases#78 -- inactive-first per doyle's build order; activated in the commits landing each leg's evidence. Forks ruled by doyle on releases#78 comment 5156688496: the two-value birth stamp with the jiffies asymmetry recorded here as its REASON, and the heal living in `shellwake::reconcile_once` every cycle (write-guarded on change) rather than at the discovery seam, since `shelldisc` documents display consumers as read-only BY CONSTRUCTION and healing there would contradict a stated design decision. [[requirements]] id = "REQ-HAZARD-RESTART-STRANDS-PERSISTENT-SHELLS" title = "A NODE RESTART MUST NOT PERMANENTLY STRAND EVERY `persistent` SHELL, AND THE EXISTING CASCADE TEST CANNOT SEE THAT IT DOES. Distinct from REQ-HAZARD-SHELL-STALE-ONLINE, which governs a force-kill DURING operation: this is a different trigger with a different safe remedy, and conflating them is how the restart class stays invisible. THE COVERAGE GAP IS THE HAZARD'S OWN SUBJECT, and it must be named here so no future reader mistakes the cascade test for coverage of this class: `rest_edges_cascade_shells_with_divergence` (spt-daemon resting.rs) is the cascade's only coverage and it walks the graceful path ONLY -- it SUSPENDS FIRST, and the suspend edge WRITES the offline record, so by the time the wake edge fires the instance is already in exactly the state the to_active arm requires. The restart shape -- record left online over a corpse, no rest edge ever -- is UNREACHABLE FROM THAT TEST BY CONSTRUCTION. The test is not weak; its SETUP SUPPRESSES THE FAILING ARM, so a reader asking whether the cascade is covered gets a true answer to the wrong question. This is the third suppressed-arm instance found in one week, and the pattern is the same each time: a fixture that establishes the precondition the code under test is supposed to establish. THE OWNER-FACING SURFACES HIDE THE FAULT, which is why it survived unreported for days: every display path (`shell list`, its --json twin, the shell-context render) routes through the ONE discovery seam, which DERIVES status and so correctly reports the binary as offline, while the only consumer whose decision matters -- the wake cascade -- reads the RECORDED field that no owner-facing surface shows. Absence of a visible symptom is therefore not evidence of absence of this fault, and a clean-looking context render must never be taken as proof the class did not occur; the correct falsifier is the on-disk record. Gate: impl -- the restart shape reaches a restoration path at all (leg b) and the record stops lying (leg a); unit -- the RESTART shape specifically, constructed WITHOUT a suspend edge: an instance whose record says online over a corpse that predates boot, with an online owner, is restored -- the row `rest_edges_cascade_shells_with_divergence` cannot express, asserted on a fixture that never calls the suspend path, since a fixture that suspends first re-creates the suppressed arm and proves nothing about this class." required_stages = ["doc", "impl", "unit"] # doc ACTIVATED BAROMETER W2 doc leg (doyle-ruled, this milestone): the KNOWN-HAZARDS 2.7 entry the mint note said was owed. AGENTS.md rule 4 makes every KNOWN-HAZARDS entry a REQ-HAZARD-* requirement and rule 1 makes the tag ride the same change as the evidence, so an untagged entry would be the untagged-evidence shape rule 1 bans. -- ACTIVATED BAROMETER W2 at impl+unit once BOTH legs landed -- deliberately not at leg (a), since the gate clause covers the boot sweep too and activating early would have let the requirement read satisfied while half its impl was unbuilt. MINTED BAROMETER W2 (todlando, 2026-08-02), releases#78 -- inactive-first. KNOWN-HAZARDS entry owed with the doc leg. The suppressed-arm sentence is REQUIRED text per the filing and doyle's dispatch: the hazard exists partly BECAUSE the existing test reads as coverage, so a requirement that did not name the gap would leave the same trap for the next reader. [[requirements]] id = "REQ-FIXTURE-BIN-BUILD-EDGE" title = "IR-21 remedy (c), ENFORCED FORM: every test consumer of a fixture `[[bin]]` is CLASSIFIED by whether that bin's build is guaranteed, by a check anyone gating can run, rather than by whoever remembers the rule. THE MECHANISM, measured 2026-08-03 and NOT the one the class was originally filed on: cargo builds EVERY bin target of a package whenever it builds ANY integration test of that package, so a SAME-PACKAGE INTEGRATION consumer is already guaranteed and `env!(\"CARGO_BIN_EXE_*\")` adds NO edge there -- the first remedy claim to the contrary was measured FALSE and the register entry was corrected. The real exposure is CROSS-PACKAGE consumers and SAME-PACKAGE UNIT tests, which get no `CARGO_BIN_EXE_*` at all; that unit member (`crates/spt/src/cli.rs`, resolving `format!(\"translate_proof_fixture{EXE_SUFFIX}\")` relative to `current_exe()`) is exactly why `.github/workflows/ci.yml:105-106` hand-prebuilds that fixture. THE CHECK READS THE DEPENDENCY SITUATION, NOT THE EXPRESSION -- owning package, consuming package, target kind -- so it classifies an UNCONVERTED tree correctly and stays true after any consumer is rewritten; that property is what makes it adoptable independently of the sibling_bin->CARGO_BIN_EXE_ conversion lane. FOUR SYNTAXES NAME A FIXTURE BIN and all four are detected: `sibling_bin(\"n\")`, `CARGO_BIN_EXE_n`, the shared resolver `fixture_bin(\"n\", \"cargo build ...\")` (crates/spt-term/tests/support/fixture_bin.rs), and the `current_exe()`-relative `format!(\"n{...}\")`. A TWO-SYNTAX DETECTOR IS THE FAILURE MODE THIS REQUIREMENT EXISTS OVER: the first prototype knew two, missed seven sites including that unit member, and therefore returned a GREEN over the single gap the class was filed for -- a zero from a tool that could not see the known-real case. Population at 6d291e0: 185 consumer sites, 146 guaranteed, 39 needing an explicit build, 11 with no prebuild anywhere. THE 11 ARE NOT CI DEFECTS: a per-job mapping showed every narrow cargo invocation in CI is covered by its own job (prebuild or an earlier workspace-shaped build), so the exposure is narrow invocations OUTSIDE CI -- gate rigs and local `-p`/`--test`/`--bins` against a cold pool -- which is why the check ships as a runnable command and is deliberately NOT wired into `xtask check`: it exits 1 on today's tree and wiring it would red the docs gate over a hazard that is not a CI defect -- a gate that reds on a population of known non-defects gets ignored or gets its teeth pulled, and either way the next REAL member arrives into a check nobody reads (doyle ruling, 2026-08-03). THE WIRING CONDITION IS THEREFORE A COMMITTED BURN-DOWN BASELINE, NOT FIXING ALL 39 FIRST, and it ships here so the choice to wire is a one-line decision later rather than a second design problem: `--baseline` reds ONLY on a site absent from `crates/xtask/binedge-baseline.tsv`, exits 0 against today's recorded 11, and REPORTS recorded entries that are gone so the list shrinks instead of ossifying into a permitted-forever set nobody prunes. Baseline keys are `(file, bin)` and deliberately NOT line numbers, which churn on every edit above them and would make the file merge noise; the trade is named -- a SECOND red site for the same bin in an already-listed file is absorbed. TWO CONTROLS SHIP WITH IT RATHER THAN LIVING IN A RUNBOOK. `--no-prebuilds` empties the CI allowlist and must take the reds 11 -> 39 while the 146 cargo-guaranteed sites stay green; a green without that arm carries no information. The false-positive arm asserts the same-package fixture sites are classified guaranteed -- and REFUSES (exit 2) when it recognizes NONE of them, because an arm whose fixtures were renamed away reports `0 wrongly flagged`, which reads exactly like a pass. That arm also filters on target kind, not name alone: it was briefly wrong when a same-package UNIT consumer entered the population and CORRECTLY landed in the flagged set, so a control is a claim about a population and ages with one. Gate: impl -- `crates/xtask/src/binedge.rs` and its `binedge-check` subcommand: the four-syntax scanner over comment-blanked whole text (line comments only; block comments are a NAMED unfixed limit), the guarantee predicate, the nearest-manifest owner resolution, the prebuild-allowlist reader over every tracked file under `.github/` (a prebuild inside a PowerShell CI script guarantees a bin exactly as well as one in a `run:` block), the repo root taken from git IN THE INVOKED TREE rather than from the compile-time `CARGO_MANIFEST_DIR` (a prebuilt xtask would otherwise measure the tree it was BUILT in, and a verdict about the wrong tree is worse than none), the burn-down baseline with its write/compare/prune arms, and the two control arms; unit -- the guarantee predicate on all three of its wrong directions, the baseline delta reddening only on an unrecorded site while reporting a burned-down one (both asserted together, since a delta of nothing passes either alone), the path-kind reader, nearest-manifest ownership including the not-a-whole-component near miss, all four syntaxes with the line numbers the register already cites as evidence, comment blanking that does not shift the lines below it, the near misses that would each be a phantom site, prebuild detection refusing `--bins` (reading it as `--bin s` would fabricate a guarantee for a bin named `s`), and the false-positive arm's blind case with its refusal condition. PORT FIDELITY IS PART OF THE EVIDENCE: this replaces a python prototype whose numbers the register cites, and it was verified against that prototype site-by-site -- 185 tuples identical, not four summary integers, which can agree by coincidence -- with both run on ONE tree after proving the two candidate trees carried an identical `.rs` population. Kin REQ-XTASK-SPT-BIN-TARGET-DIR (the other xtask tooling defect about looking in the wrong place)." required_stages = ["impl", "unit"] # ACTIVATED in the commit landing the evidence (todlando 2026-08-03, IR-21 STEP 4 rig-facing half, doyle-scoped). impl = crates/xtask/src/binedge.rs + the binedge-check subcommand wiring in main.rs. unit = the eight pure seams in binedge.rs's own test module. No doc stage: the register entry (docs/INFRA-REGISTER.md, doyle-owned) carries the prose, and this requirement must not claim doc evidence in a file I do not write. No int stage: the whole command IS an integration-shaped measurement of the real tree, run and recorded at mint time; a test that re-ran it would assert today's 185/146/39/11, which is a population that legitimately moves. [[requirements]] id = "REQ-FIXTURE-BIN-PERJOB-DRIFT" title = "The per-job companion to REQ-FIXTURE-BIN-BUILD-EDGE, and it is a DRIFT GUARD, NOT A FINDER. `xtask perjob-map` walks every CI job step by step and asks, for each narrow cargo invocation, whether the cross-package fixture bins its tests consume were built EARLIER IN THAT JOB -- by an explicit `cargo build -p X --bin B` or by an earlier workspace-shaped build. On this tree the answer is 7 narrow invocations, 0 unguaranteed, which is what establishes that the 11 repo-wide reds are NOT CI defects. THAT ZERO IS A FACT ABOUT TODAY'S WORKFLOWS AND NOTHING MORE, and the requirement says so because the tool's value is entirely in the FUTURE case: the day somebody adds a narrow invocation to a job that does not build what it consumes. A requirement that framed this as proof the class is closed would license deleting it the moment the register entry is written. THE ONE MODELLING TRAP, already paid for once: a workspace-shaped run emits the plain binaries only if it actually builds integration-test targets -- `--workspace` filtered to `-E 'kind(lib) + kind(bin)'` compiles lib/bin harnesses and emits NO plain fixture exe on a clean pool, which is exactly what `ci.yml:102-106` documents and hand-prebuilds around. The first prototype credited it as a builder and returned a GREEN over the one known-real gap; the kind-filter test is therefore a required unit row, not an optional one. THE SCRIPT-BLIND HOLE IS PRINTED IN THE COMMAND'S OWN OUTPUT RATHER THAN FOOTNOTED IN A DOC. The model reads `run:` blocks in workflow YAML; narrow cargo invocations ALSO live inside `.github/ci/*.ps1` and `*.sh`, which those blocks merely invoke, and no `run:` parser can see inside them. Rather than leave that as a limitation somebody has to remember, the scripts are scanned with the SAME detector and every narrow invocation they contain is listed as UNMODELLED with the cross-package bins it consumes: today 2 instances (`g6-curve.ps1`, `g6-postbounce.ps1`, both `-p spt-daemon --test inject_control_wedge`), both consuming NONE, so the hole is real and its instance count is measured at zero instead of asserted. An UNMODELLED invocation that DOES consume a cross-package bin counts as a gap and reds the command, because a verdict nobody can compute must not read green. THAT SCAN NEEDED ITS OWN CORRECTION, AND THE DIRECTION MATTERS: scanning the scripts raw read `reap-census.ps1`'s comment-based-help block -- which DESCRIBES a `cargo test -p spt --test ...` failure in prose -- as a real invocation consuming three cross-package bins, i.e. a fabricated gap inside the section whose entire job is honesty about what cannot be seen. PowerShell `<# #>` blocks and whole-line `#` comments are stripped; a TRAILING `#` deliberately is not, because in sh that would eat `${var#foo}` and losing a real invocation is the worse direction here. THE YAML IS PARSED BY A DELIBERATELY SMALL SUBSET READER, AND ITS FAILURE MODE IS ACCOUNTED RATHER THAN TRUSTED: xtask carries no parser dependency, and a silent mis-parse would DROP steps, after which every job those steps belonged to would read guaranteed -- a green manufactured by not looking. So the reader counts the `run:` command keys present in the file and refuses (exit 2) unless it attributed every one of them to a job. A `run:` that opens a mapping rather than a command (`defaults.run.shell`) is not a command key on either side of that count. LIMITS THAT REMAIN OPEN AND ARE NAMED IN THE COMMAND'S OWN DOC: `uses:` steps are not followed, and guarantee is tracked per job in step order without modelling artifact reuse across jobs on a persistent self-hosted workdir -- and our golden boxes ARE persistent, so a WORKSPACE verdict is sound only within its job and a clean runner could still expose what reuse masks. Gate: impl -- `crates/xtask/src/perjob.rs` and its `perjob-map` subcommand: the consumed-bin index over integration-test targets and over the unit population (unit tests get no `CARGO_BIN_EXE_*` at all, which is why `-E 'kind(lib)+kind(bin)'` is a CONSUMER step), the step walker with its prebuild and workspace-build guarantees, the accounted YAML subset reader, the script scan with its comment stripping, and the reuse of REQ-FIXTURE-BIN-BUILD-EDGE's detector rather than a second one (mapping through a different detector would produce a per-job verdict over a different population); unit -- the parser refusing an unattributable `run:`, block and inline bodies both surviving while `uses:` and `#` lines do not, cargo invocations stopping at a shell separator and `nextest run` not being read as the shorter `test` verb, the kind-filtered workspace run classified as consumer rather than builder, flag values requiring the whole flag (`--bins` is not `--bin s`), script prose not being read as an invocation, and a job guaranteeing by prebuild, by workspace build, and failing when neither ran. THE GUARD WAS OBSERVED FIRING ON A REAL FALSE STATE, not only in tests: while this lane was in progress the checker's own test fixture named `CARGO_BIN_EXE_git_fixture` unescaped in a tracked `src/` file, which entered the unit-consumer population and made this map report a gap in `ci.yml`'s unit lane and exit 1. Kin REQ-FIXTURE-BIN-BUILD-EDGE (the repo-wide half, whose detector and helpers this reuses)." required_stages = ["impl", "unit"] # ACTIVATED in the commit landing the evidence (todlando 2026-08-03, IR-21 STEP 4 second half, doyle-scoped). impl = crates/xtask/src/perjob.rs + the perjob-map subcommand wiring in main.rs. unit = the pure seams in perjob.rs's own test module. No doc stage: docs/INFRA-REGISTER.md is doyle's to write, and this requirement must not claim evidence in a file I do not author. No int stage: the command IS the integration-shaped measurement, run and recorded at mint time; a test asserting today's 7-rows-0-gaps would pin a population that legitimately moves, which is the opposite of a drift guard. # ─────────── USHER F-lane — engine-room lifecycle (releases#142) ──────────── # Minted 2026-08-04 (todlando) under doyle's fix-lane ruling on #142