# DISPOSITION — Windows consumer leg on fix-2 7890ead3 (#304 / #297)

Author: doyle. Drafted 2026-09-14 ~14:15Z. Status: **DRAFT — holes marked PENDING are unfilled; this file is not a verdict until every PENDING is replaced by a measurement or a ruling.**

Standing condition (deployah, recorded on #304): later greens NEVER erase the reds below. The three original failures stay in this file verbatim regardless of cohort outcome.

## Subject

- Candidate: `7890ead39bb7f14ed44aaae44b0951f098ffe9ac` (fix/297-enforcement-shape, parent S2 `527cd8e8d7ef192892d5630fce10e69a6d811893`), asm/304-v3 head, gated PASS by doyle (ancestry / trailer / scope / tags / traceable-reqs 0.2.0 + 0.4.1 exit 0).
- Tree: `.worktrees/asm-304-v3` (warm target, pool claimed for the leg, released at close).
- Driver: `consumer-windows-7890ead3/run.ps1`. Start 2026-09-14T13:08:07Z.
- Receipt: `attempt1-receipt.txt` sha256 `0aed8db470963e1f34289d7914cd6ae6f548268b1b70c0281a11beb57b938004`.

## Result

| phase | exit | summary (nextest) | end (UTC) |
|---|---|---|---|
| A (`not HEAVY`) | 0 | 3463 run: 3463 passed (7 slow, 6 leaky), 1 skipped | 13:32:09Z |
| B (`HEAVY`) | 100 | 239 run: 236 passed (1 slow), 3 failed, 0 skipped | 13:52:57Z |

Phase-A count 3463 = S2 3459 + 4 new tests (fix-2 adds four `#[cfg(windows)]` tests in `bootstrap_firewall/windows.rs`), exactly as predicted before the run. Phase-B cell count 239 unchanged from S2.

Sibling leg (Linux, todlando, kitsubito, same sha): A 3417 passed / 1 skipped, B 224 passed, inventories exact, receipt sha `f7186226d1aa9456e8fec28bc8fc2ef1278805ccd0af608c17a6850067e31b6f`, re-hashed by doyle, HEAD pinned 7890ead3 — ACCEPTED. The Windows-only cells below have no Linux counterpart to compare against for (1); (2)/(3) are cross-platform cells that were green on Linux in this same run.

## The three reds (verbatim from `attempt1-phase-b.log`)

### (1) `spt::webserve_attachment_e2e::an_attachment_is_snapshot_served_fetched_back_and_named_by_its_message` — FAIL [10.309s] (78/239)

```
thread 'an_attachment_is_snapshot_served_fetched_back_and_named_by_its_message' (14860) panicked at crates\spt\tests\webserve_attachment_e2e.rs:568:9:
each attachment registered its OWN entry - alpha.md is missing from [
  { ... "served_name": "report.md", ... "url": "http://localhost:59236/hfenduleam/f/report.md" }
  ... report~1.md, beta.md ...
]
```
(full list at log lines 97–160; three other names present, alpha.md alone absent, both ATTACHED URLs were produced and distinct before the assertion.)

**Mechanism — CLASSIFIED (hertz RCA from source, `.spt/preserved/hertz-attachment-NO4JJOEL/rca-source.json`):** broker Attach/List and the brain TTL reaper hold DIFFERENT process-local `REGISTRY_WRITE` mutexes; the reaper can publish a stale whole-registry snapshot between two registrations and drop the earlier one. Mechanism proven in source; this incident's exact interleaving inferred. Contract loss (assertion names both entries, ARM11), not the retired expired-entry count flake.

**Pre-existing:** 6/6 green on all prior preserved Windows+Linux phase-B legs (49a08a07, S2, full49); fix-2 diff is disjoint from this path. Filed as **#308** (BUGFIX, state backlog; detail comment 5665237597). Windows leg record: #304 comment 5665188212.

**Cohort (hertz, 10x on exact 7890ead3, S2 rig, 14:27Z, msg 75S2DFAR):** **9/10 passed, 1/10 red** under SERIALIZED single-cell consumer-shape load, zero SPT knobs. Attempt01 hit the same `:568` membership contract with the OPPOSITE survivor (beta.md lost, alpha.md kept) — live registration loss reproduced, not the retired count flake, and not a fixed-order artefact. Receipt: `.spt/preserved/hertz-attachment-NO4JJOEL/attachment-consumer-cohort-receipt.json`. Load axis: serialized one cell; full 239-cell HEAVY-load rate UNMEASURED (the original red occurred under that load). Golden implication: 1/10 is the OBSERVED SAMPLE RATE under serialized load, not a floor and not a bound on the heavy-load rate (unmeasured, could be lower or higher). Mechanism is cross-platform (0 reds in 4 Linux B runs — a sample, not a negative). A golden red matching the `:568` signature does NOT auto-authorize a rerun: any retry needs a recorded ruling with the original failure retained, and a later pass never establishes the defect fixed (deployah, msg LBPAEVAO).

### (2) `spt-daemon::inject_control_wedge::g1_choreography_happy_path_payload_reaches_pty_and_controller_keeps_control` — FAIL [2.549s] (149/239)

```
SPAWN_PHASE:xlate-g1-ep phase=pty_created t_ms=891 pid=Some(55576)
...
SPAWN_PHASE:xlate-g1-ep phase=waiter_armed t_ms=892

thread 'g1_choreography_happy_path_payload_reaches_pty_and_controller_keeps_control' (56388) panicked at crates\spt-daemon\tests\inject_control_wedge.rs:1317:10:
spawn translation-bearing session: Custom { kind: TimedOut, error: "brain IPC read deadline elapsed" }
```

### (3) `spt-daemon::inject_control_wedge::g7_native_injects_mid_active_bypassing_the_idle_gate` — FAIL [2.571s] (155/239)

```
SPAWN_PHASE:xlate-g7-ep phase=pty_created t_ms=1327 pid=Some(42684)
...
SPAWN_PHASE:xlate-g7-ep phase=waiter_armed t_ms=1328

thread 'g7_native_injects_mid_active_bypassing_the_idle_gate' (56552) panicked at crates\spt-daemon\tests\inject_control_wedge.rs:1317:10:
spawn translation-bearing session: Custom { kind: TimedOut, error: "brain IPC read deadline elapsed" }
```

**Mechanism for (2)/(3) — UNCLASSIFIED.** Same panic site and wording; deployah's caveat stands: shared deadline wording is not a shared cause. Observed: spawn reached `waiter_armed` within ~0.9–1.3 s in both, then the brain IPC read deadline elapsed at the test's spawn helper (`:1317`). g2–g6 between them PASSED in the same run; both cells 6/6 green on all prior legs; NOT in hertz's S2 hardened set (that set was `harness_only_refuses_truthfully_pre_stream` and `a_raw_dead_connection_bound_opener_is_not_re_served_by_the_next_generation`). Suspected seam under trace: #302 NetHost 2-worker runtime / unbounded brain read (`cold_start` ⇒ `io_timeout` None). Fix-2 diff does not touch spt-daemon's inject/session path (six files, all under `bootstrap_firewall` + its tests/fixtures/toml).

**Localization (hertz, 14:05Z, msg SGZ2T4YN):** both fail after `waiter_armed` (892 ms / 1328 ms) and before `translation_ready`, against a fixed 2 s pump-read budget; both expire at ~2.04 s. That interval creates the translation process, writes Init synchronously, starts threads — not NetHost/journal operations. Startup-budget exhaustion outranks #302 equivalence; exact stall unproven.

**RIG DELTA (doyle, measured 14:12Z):** `golden.yml` @7890ead3 lines 111–123 sets `SPT_ATTACH_IPC_DEADLINE_MS=30000`, `SPT_ATTACH_GATE_WATCHDOG_MS=120000`, `SPT_TEST_EPHEMERAL_ADVISORY_PORTS=1` for the HEAVY legs. Both consumer legs carried `SPT_TEST_EPHEMERAL_ADVISORY_PORTS=1` and NEITHER deadline knob. (Correction 14:32Z, hertz UMWW5ONC, verified by doyle: `run.ps1` writes the env receipt `after=[]` at line 20 — post-scrub — and only then sets ADVISORY_PORTS at line 24, so `attempt1-env.txt` records the scrub result, not the final producer env. The next driver revision records the post-overlay names too.) `attach_ipc_deadline()` (`inject_control_wedge.rs:126`) therefore ran at the local-tight 2 s default, which golden never runs at; the `spawn_session` at `:1317` reads under that `io_timeout`. golden.yml's own comment names this class: serviced-but-late ack past 2 s under co-tenant load (doyle's serialized repro 2.016 s, source=channel — not a wedge). Consequence: (2)/(3) are candidate **rig-shape reds**, not product reds, pending the golden-shape cohort arm. The consumer rig must carry golden's env block verbatim on the next leg (routed to hertz).

**Cohort (hertz, on exact 7890ead3, S2 rig) — ruled 14:15Z, two arms each for g1/g7:**
- Arm 1 (consumer shape, no knobs, 2 s): g1 **10/10 passed** (hertz QNSFRFPJ, serialized one cell, zero knobs) — spawn completion ranged **26–1967 ms**; one pass landed 33 ms under the 2 s budget with NO co-load, so the local default is marginal on this box even serialized. Does not refute the consumer red (full-load axis unmeasured). g7 **10/10 passed** (M75YUQSD), spawn 24–1340 ms. Load: serialized one cell, zero knobs.
- Arm 2 (golden shape, three knobs): g1 **10/10 passed** (M75YUQSD), spawn 24–229 ms. g7 **10/10 passed** (7JZQ3FTU), spawn 26–445 ms. Load: serialized one cell. Five-arm report: `.spt/preserved/hertz-attachment-NO4JJOEL/five-arm-report.json`; all 58 native jobs complete, hertz pool released, END census BOX_CLEAR 14:53:43Z.
- Reading at 14:45Z: NO arm went red, so the 2 s/30 s discriminator is INCONCLUSIVE under serialized load — 40 serialized greens say nothing about the 239-cell load where the reds happened (hertz claims no full-HEAVY equivalence; doyle concurs). What the arms established: serialized spawn tail reaches 1967 ms against a 2000 ms budget — zero headroom at the local default before any co-load.
- **Arm 6 (ruled 14:45Z): ONE full Windows phase B (239 cells, golden parallelism) on exact 7890ead3 under GOLDEN-SHAPE env, asm-304-v3 warm target, doyle's producers, hertz-revised driver `run-attempt2.ps1` (post-overlay env line, `-PhaseBOnly`).** Reading (deployah TIUREUZ3, adopted): g1/g7 GREEN ⇒ the candidate executes these cells under the golden configuration at full load — the configuration golden actually runs — so the golden is not predicted red by them; it does NOT by itself prove the missing deadline overrides caused the original reds. That causal question stays INCONCLUSIVE unless separately evidenced (the established facts: knob difference, localization to the spawn interval, serialized spawn tail 1967 ms vs 2000 ms budget — circumstantial, not mechanism). g1/g7 RED at 30 s ⇒ product stall, HOLD.
  **RESULT (END 15:19:06Z): phase B exit 100 — 239 run, 237 passed (1 slow), 2 failed, 0 skipped, 1249.8 s.** Receipt `attempt2-receipt.txt` sha256 a514b56a45421572737b3e10a4c26caa33151be4291221dc2f19a9d30a0da736; log `attempt2-phase-b.log` sha256 9069916f12e97bcd894096fc0db26f79d01483c042ed5111e8d58ff7c25d358a; env `attempt2-env.txt` sha256 89ff836b0d86736c20681e1e3e0aa9f27e53beb9605fcd16a050a3ba5c638e8d (post-overlay names; values attested in `attempt2-env-values.txt`). Driver sha 3dfed3e6…; launch record `attempt2-launch.txt`; aborted first execution `attempt2-aborted-*` + NOTE.
  - Original (1) `webserve_attachment_e2e`: **PASS 13.928 s** (78/239). Original (2) g1: **PASS 13.447 s**. Original (3) g7: **PASS 15.619 s**. All three originals green in the golden configuration at full load; the reds they produced in attempt 1 stay on record above.
  - The 2 failures are NEW cells (4) and (5) below — both green in attempt 1. Across two full Windows phase-B runs on this sha, 5 distinct cells red, none red twice.
  - Close: driver pid 50940 exited; own asm-target orphans reaped = 0 (`attempt2-orphan-reap.txt`); pool lane `consumer-windows-7890ead3-attempt2` released 15:20Z.

### (4) ARM 6 NEW RED — `spt::er_briefing_presented_e2e::the_engine_room_briefing_is_presented_before_the_first_actionable_turn` — FAIL [79.834s] (38/239), attempt2 (golden-shape env), 15:03Z

```
thread 'the_engine_room_briefing_is_presented_before_the_first_actionable_turn' (36128) panicked at crates\spt\tests\er_briefing_presented_e2e.rs:782:9:
REQ-ER-BRIEFING-PRESENTED clause 4: the new session's own briefing must be delivered at the same attach that supersedes the retained row. The cross-session chain is miss -> release -> retained -> superseded-with-delivery, never merely disappearance.
rows=[SpoolAuditRow { id: 2, from: "spt-engine-room", delivered: false, taken_leg: None, taken_sid: None, taken_pid: None, taken_at_ms: None }]
```
Not one of the original three. Attempt 1: PASS at 38.159 s (same index 38/239); 6/6 green on all prior legs. Env equivalence for this cell MEASURED: the two deadline knobs are read only by `inject_control_wedge.rs` (grep at 7890ead3), so arm 6's env is equivalent to attempt 1's here — a fourth intermittent under full HEAVY load, not a knob effect. Row present but UNDELIVERED at the superseding attach; duration doubled (38 → 80 s, "running for over 60 seconds"). **Mechanism — INTERIM (hertz RECCB5HI, 15:12Z, source+log; written RCA pending):** the red is the PRE-INJECT ELIGIBILITY TIMEOUT (arm 5's specific 10 s eligibility-expired branch), not a failed translation write. Log order: `CONTROL_REAP_NO_SESSION` → `LIVENESS_RECONCILE_OFFLINE` → `SPAWN row_inserted` at 3366 ms. Livehost's session poll discards the broker's bringing-up ledger and treats only PUBLISHED sessions as alive, so a slow spawn under full HEAVY load is reconciled OFFLINE before it publishes; the 45 s test barrier then expires without retrying presentation. `controllable=true` at the end does not establish `online=true`. Product-side liveness/spawn gap, timing-exposed.

**RCA — FILED (hertz, `.spt/preserved/hertz-attachment-NO4JJOEL/er-briefing-arm6-rca.json`, sha256 3fc7ea651f626da5e5363a2d145ac8def8d57e0229355b0aa7b3417501de27ad):** the new row composed successfully but the presentation worker returned BEFORE native drain — its independent 10 s eligibility poll never saw an eligible endpoint. Strongest explanation: a pre-existing spawn-publication vs liveness-reconciliation race — the harness can bind before the broker publishes its HostedSession; livehost discards `bringing_up` and terminal-normalizes the bound endpoint as dead. The offline write and per-poll predicate values were not captured, so attribution is a strong inference, not instrumented proof. NOT a test defect. **NOT INTRODUCED BY FIX-2: PROVEN (origin date not established — unchanged code says nothing about when the defect began; deployah JCOKTRD4)** — all 9 relevant blobs (ER test, broker, livehost, inject, info, liveness, deliver, api/startup, mock/main) identical between S2 and 7890ead3; fix-2's exhaustive file list is CHANGELOG, `bootstrap_firewall/windows.rs`, docs-site changelog, `docs/297-ENFORCEMENT-CODES-DIAGNOSIS.md`, ADR-0059, `traceable-reqs.toml`. The two deadline knobs have no path to this cell (accepted). Duration delta 41.7 s = the outer wait exhausting, not evidence against a race. Recommended: keep as a product eligibility/lifecycle defect, preserve clause-4 assertions; repair target = the spawn/reconcile authority boundary (coherent live/starting/absent observation, protect false-death mutations incl. control cleanup), NOT a longer briefing wait. Board: **#309** (BUGFIX, backlog; RCA comment 5666263268).

### (5) ARM 6 NEW RED — `spt-daemon::inject_control_wedge::c1_strike_fault_stamps_perch_and_bounded_respawns_then_gives_up` — FAIL [5.297s] (148/239), attempt2 (golden-shape env), ~15:13Z

```
TRANSLATION_RESPAWN:xlate-c1b-ep: rebuilt faulted binary (attempt 1/2)
...
TRANSLATION_FAULT: no {commit} within INJECT_COMMIT_DEADLINE for the strike budget — terminating binary; idle messages spool until a respawn or a working binary
SPAWN_PHASE:xlate-c1b-ep phase=row_removed session=1 lived_ms=5195
=== C-1 B FAULT/RESPAWN/GIVEUP GATE: stamped=Some("no {commit} within INJECT_COMMIT_DEADLINE for the strike budget") inits_logged=2 saw_spool=false attempts=8 (fixed = stamped Some, inits in 2..=3 (initial + bounded respawns), give-up spool; pre-C-1 = no stamp + never respawns + permanent death) ===

thread 'c1_strike_fault_stamps_perch_and_bounded_respawns_then_gives_up' (55840) panicked at crates\spt-daemon\tests\inject_control_wedge.rs:2104:5:
once the respawn budget is exhausted the binary must stay dead and inbound must SPOOL (delivered=false), loudly — not respawn forever
```
Not one of the original three; distinct from (4). Attempt 1: PASS at 3.028 s (same index 148/239); green on prior legs. Stamp and bounded respawn observed (inits 2, respawn attempt 1/2 logged, no 2/2 line), the give-up SPOOL was NOT observed before the session row was removed at 5195 ms. **Env caveat: `inject_control_wedge.rs` DOES read both deadline knobs (`attach_ipc_deadline()`), so for THIS cell a knob-shape effect is NOT excluded — unlike (4).** **Mechanism — INTERIM (hertz TKGTZ6WP, 15:20Z; written report pending):** knob effect EXCLUDED for this cell after all — c1's eight probes use raw `LocalSocketTransport` with a fixed 3 s outer receive, not the 30 s Brain `io_timeout` (that knob reaches only the already-successful 40 ms setup spawn); all eight probes returned true. Seven injections were queued before the first fault; only the eighth triggered respawn 1/2. The test then stops and kills its PTY BEFORE observing exhaustion — its 600 ms sleep is not a fault-completion barrier; `row_removed` before the printed gate is explicit test teardown, not a probe outliving the session. **RCA — FILED (hertz 2RA2LKJS, `.spt/preserved/hertz-attachment-NO4JJOEL/c1-strike-arm6-rca.json` + `c1-strike-arm6-proof.json`): TEST DEFECT.** The fixed-sleep test drive failed to reach exhaustion — not evidence of infinite respawn. Seven accepts preceded fault 1; exactly one respawn occurred; the eight 600 ms sleeps account for 4.8 s of the 5.297 s. Probes use fixed 3 s raw-socket wrappers, unaffected by the 30 s Brain knob. Exact source unchanged since S2. Repair (hertz's test-rework lane, after GO): generation-completion barriers, then an explicit exhausted-budget reply; distinguish transport errors from `delivered=false`. No board BUGFIX; candidate test-only rider A' (see ruling section).

Also observed in arm 6: **g1 PASS at 13.447 s** (149/239) and **g7 PASS at 15.619 s** (155/239) under golden shape — vs FAIL at 2.549 s / 2.571 s in attempt 1. Both spawn tails ran well past 2 s and inside 30 s under full HEAVY load. Per the adopted reading: establishes execution under the golden configuration; original causality inconclusive.

## Box state at close

- 6 leaky phase-A `spt.exe` (asm-304-v3 target/debug, created 13:21:48–13:22:58Z, all parents dead) reaped by doyle, `attempt1-orphan-reap.txt`, `orphans left: 0`.
- Pool released. No other doyle producer on the box. hertz's cohort rig (S2 tree) was admitted after close.

## Rulings and sizing

- **todlando read-only fix sizing for (1) (14:06Z, msg TNOC5BOW, base 7890ead3):** RCA CONFIRMED from source — one `REGISTRY_WRITE` declaration (`servehost.rs:18-20`) but broker (`apply_at` :171) and brain (`with_registry_write` :148 ← `livehost.rs:1287` reaper) are separate processes with independent instances; `serving.rs` `save_at` writes the whole registry atomically with no CAS. Stale-write path fits the reported membership exactly (inferred, not traced). Overwrite also clobbers `next_suffix`/`name_owners` (ADR-0057 stale-link identity at risk). **A green 10x cohort would not refute this gap.** Minimal fix: one per-registry CROSS-PROCESS file-lock guard owned by spt-store (`serving.rs`, fs2 sentinel pattern from `info.rs:871-886`, no new dep), acquired before load and held through mutation + durable publish; `servehost.rs` and `livehost.rs` both switch to it. Blast radius ≈ 3 runtime files + 2 e2e files that mutate the registry under a live daemon + a two-process regression with worker fixture ≈ 8 files. **Rollout constraint:** both broker and brain must run the fixed implementation; an old broker + new brain pair stays unsafe. No schema/CLI/URL/TTL change.
- **Operator ruling (Reavo, given in-session 2026-09-15, relayed by lia msg RRWDOYDQ received 2026-09-15 ~06:45Z; my first write of this line carried a stale 09-14 clock and is replaced): OPTION A + A'.** Verbatim: "SHIP #304 / v0.70.0 ON RECORD with #308 and #309 named on the milestone. Rerun protocol pre-agreed with deployah: a golden red matching a CLASSIFIED signature (:568 registry, :782 briefing) => recorded ruling on #304 + ONE same-sha rerun of that leg. A second red, or any unclassified red => STOP AND REFER. A' included: take hertz's test-only c1 barrier repin on top, with the spt-daemon suite re-run on both OSes for the new sha. Not B, not C. #297 acceptance is met; proceed to hand-off."

## Disposition — ACCEPT-ON-RECORD (doyle, 2026-09-15 06:50Z, under the operator's A + A' ruling)

Windows consumer on 7890ead3: phase A green (3463/1 skipped); phase B run twice — attempt 1 (local env) 236/3, attempt 2 = arm 6 (golden env) 237/2 — five distinct red cells, none red twice, every one classified: (1) #308 registry lost-update, product, not introduced by fix-2, cohort 1/10 serialized (sample rate, not a floor); (2)(3) g1/g7 red only at the local 2 s default, green under golden's 30 s at full load, original causality inconclusive; (4) #309 engine-room briefing liveness race, product, not introduced by fix-2; (5) c1 give-up-spool, TEST DEFECT, repinned by rider A'. Linux A+B green. The three original reds and the two arm-6 reds stay on this record; later greens do not erase them. Rerun protocol for the golden as ruled above. Rider A' produces a successor sha (test-only, two files) whose spt-daemon suite is re-run on both OSes before hand-off.
