# LIFECYCLE-TRUTH W3 — GATE VERDICT: **PASS** (doyle, 2026-07-07)

**Wave head `e75e856`** (branch `lifecycle-truth`). All 6 W3 REQs built + gated. Both legs green.

## REQ ledger (all gated)
| REQ | SHA | stages |
|-----|-----|--------|
| REQ-UPDATE-FINISH-ENDPOINT-SURVIVAL | `049b2be` | impl+unit+int |
| REQ-DAEMON-STDERR-PERSIST | `32c789e` | impl+unit |
| REQ-DAEMON-STOP-LIVE-SESSION-WARN | `ff6ebeb` (+int `8931680`) | impl+unit+int |
| REQ-RC-RECONNECT-TRUTH | `3d632b9` | impl+unit+int |
| REQ-UPDATE-ONE-SHOT-FINISH | `e85da91` | impl+unit |
| REQ-DIGEST-GENERATION-SUPERSEDE | `7e37e37` | impl+unit+int |
| REQ-UPDATE-PROMOTE-DRAINED | `e75e856` | impl+unit+int |

## Gate legs — both green
- **Windows (HFENDULEAM), isolated worktree `.worktrees/gate-e75e856`, fresh target, `CARGO_INCREMENTAL=0`:**
  clippy `--workspace --all-targets` exit 0 · nextest `--workspace --no-fail-fast` **1692/1692 passed** (8 leaky, 1 skip) exit 0 · `xtask check` (docs-drift + token) **OK** · traceable exit 0.
- **Linux (kitsubito), bundle-deployed `spt-core-deploy` @e75e856, fresh, `CARGO_INCREMENTAL=0`:**
  clippy `--workspace --all-targets` exit 0 · nextest `--workspace --no-fail-fast` **1680/1680 passed** (2 leaky, 1 skip) exit 0. (1680 vs 1692 = normal cfg(windows)-conditional divergence.)

### xtask 101 on first Win pass — env artifact, NOT a real failure
The full-workspace nextest leaked 4 dev-daemon `spt.exe` from e2e teardown gaps, pinning
`gate-e75e856\target\debug\spt.exe` → xtask's spt rebuild hit `os error 5` (Access denied) →
build panic before the docs-drift check ran. Scoped-swept the 4 leaked pids (path ==
worktree target only; never the AppData plugin listener) → `xtask check: OK` exit 0. The
gotcha todlando flagged in the wave-gate report; recurrence expected until
REQ-XTASK-SPT-BIN-TARGET-DIR / a teardown-reap seed lands.

## Diff review (both new REQs — faithful)
- **REQ-DIGEST-GENERATION-SUPERSEDE** (`digest.rs`): faithful to the ruling
  (docs/W3-DIGEST-GENERATION-UNION-RULING.md). `logical_key=(role,ts,text,tool)` NUL-joined;
  keep NEWEST-ordinal occurrence (survivor seq = live gen → snapshot + `--follow` agree);
  cross-generation ONLY (equal-ordinal within-session repeats survive); supersede runs on the
  RAW span before the window fold; 3-pass boundary trim leaves no orphaned divider. 4 units +
  RED-first int (`two_origin_spanning.rs`); disjoint-span test stays green (supersede no-op).
- **REQ-UPDATE-PROMOTE-DRAINED** (`brainproc.rs`/`broker.rs`/`daemon.rs`): sound. Readiness
  LATCHED (`ready_seen`, `try_wait` only pre-ready → ready-then-exit still promotes once
  drained); promote gated on `ready_seen && old_gen_drained()`; never-drains → WindowElapsedAlive
  → kill + rollback (conservative — never false-promote onto a wedge). `old_gen_drained` reads
  broker truth in-process (`any_local_controller_wedged`, `by:None` only — remote conns excluded,
  the W2 concern), sessions→log lock order, no I/O under lock, poison → false (fail toward
  promotion, never strands). Fail-safe→drained where nothing to read (net-less / NoTrialEnv).
  **No normal-apply regression:** a clean-closed old conn drains at once → fast promote; only the
  pathological black-hole wedge gates, worst case = safe rollback. Test env `drain_countdown`
  defaults 0 (always drained) → all 24 prior trial tests unaffected. RED-first int
  (`false_promote.rs`, real broker) + 2 units. Closes KH 7.36 (the W2 15s residual).

## Staged conditions (doyle) — satisfied
- **Grep OLD rc auto-start assertions: CLEAN** — every `rc.rs` reference asserts the NEW
  connect-only truth ("rc won't auto-start", DaemonDown, WMI-resurrection RED). The
  `contract_e2e.rs:476` cold-`api`-seed auto-start is a SEPARATE preserved seam (REQ-DAEMON-3),
  not rc's reconnect loop — correctly untouched.
- **Seam regression-safety:** digest (supersede no-op on disjoint) + brainproc/broker (default
  drained) → no prior-behavior assertion breaks; confirmed by both legs' full green.

## Verdict
**W3 GATED PASS — CLOSED.** LIFECYCLE-TRUTH W1+W2+W3 all gated. Next:
1. **W1 field-accept swap window** (operator-coordinated): `update apply --finish` IS the swap
   (ENDPOINT-SURVIVAL makes the daemon restart non-massacre); both psyche stamps self-clear on
   next commune post-swap.
2. **Release (counter 49 → v0.29.0)** via deployah (parked — operator wake pending),
   bump-on-milestone-branch. NO release until this bless + the swap window.
3. W4/W5/W6 activation (relay-respawn / delivery-integrity / docs) after the swap.
4. Reply flynn: digest gen-union fixed + gated, ships in the counter-49 cut.
