Milestone `releases#294` — v0.69.0, cross-node communication after the v0.68.0 flip. Eight greenlit BUGFIX requests, assembled and gated as one chain.

Candidate: `a9e786b24fe4e541dcd394ef428f225d72f3024a` (tree `74fa640f78b0a588cd01b90c5898f9ea73e5dc08`), base `main` @ `de5a44bc`. Golden lane: `golden/crossnode-294`.

## The eight members

Each is provable as the second parent of a named merge:

| Request | Member | Merge |
| --- | --- | --- |
| `releases#289` | `6c0fa00b` | `48a7d2e5` |
| `releases#293` | `9d718719` | `e9fa4d7b` |
| `releases#292` | `111568f2` | `0acbe7fe` |
| `releases#281` | `0966ed71` | `80be305e` |
| `releases#285` | `fc5887b1` | `24fdf006` |
| `releases#286` | `19a90979` | `379b80f1` |
| `releases#295` | `9547cd49` | `88f91077` |
| `releases#287` | `53f63c3a` | `117d706d` |

Rider: IR-92 `df024887` via `79ac8d04`. Scope commit: `578ad38b`. Test-only correction: `a9e786b2`.

**Supporting, deliberately not a member:** core PR #217 (`spt-bs-core`, tip `1ebd03dc`, via `d9db9ff3`). Ruled enforcement evidence for `releases#293`'s own `REQ-BRAIN-READ-BOUNDED-PER-CALL` — it adds `[impl->]`, `[unit->]` and `[int->]` tags and introduces zero new REQ ids, touching only `ci.yml`, `crates/xtask` and `docs/KNOWN-HAZARDS.md`. Board membership is counted in releases requests, so a code-repo PR number is not a ninth member. The milestone count is eight. (Note the repo collision: `releases#217` is an unrelated closed FIDO2 request.)

## Gate evidence

Head-level gate on the candidate, both boxes, all numbers read from per-leg exit files rather than a log tail:

- **kitsubito** — compile gate clippy/brainread/xcheck/nextest-xtask/treqs/claim all 0, clippy warning lines 0. Full unit set: `Summary [ 27.752s] 3154 tests run: 3154 passed (2 leaky), 1 skipped`.
- **hfenduleam** — compile gate brainread/claim/clippy/nextest-xtask/treqs/xcheck all 0. Full unit set: `Summary [ 591.579s] 3167 tests run: 3167 passed (4 slow, 4 leaky), 1 skipped`, clippy warning lines 0.
- FAIL / SIGSEGV / ABORT lines in either raw: zero. `traceable-reqs check` exit 0. Whole-tree conflict-marker scan on the commit: zero files.

**Stated limit of that selection:** both head-level runs select `kind(lib) + kind(bin)`, which excludes the e2e binaries — so neither head-level leg exercised `attach_link_push_e2e`, the cell this head fixes. E2e coverage at this exact tree is separately attributed: Linux `3 tests run: 3 passed` over the three touched e2e binaries, and five separate loaded Windows runs, each 782/782 with zero skipped. Head-level e2e proof comes from the golden lane itself, which runs the e2es on both runners.

The published `[0.68.0]` block stayed byte-identical (sha256 prefix `406dd3cdd2a37844`) across all seven merges and the scope commit. `CHANGELOG.md` blob `3b04f056` is identical at the scope commit and at the candidate, as the final head is test-only.

## #287 — why only three e2es were touched, and why the two siblings are excluded

The keeper-before-bind fix (`fix/287-keeper-before-bind`) changes three e2e tests (`activity_link_push_e2e.rs`, `attach_link_push_e2e.rs`, `drive_e2e.rs`) and no product code. Two sibling e2es also drive the shell bind path and are deliberately NOT touched.

**The exclusion rests on the rig, not on any property of the test bodies.** The stale-online heal is reached from exactly one production call site: `heal_stale_online_records` (`crates/spt-daemon/src/shellwake.rs:612`) is invoked at `shellwake.rs:907`, the first leg of `pub fn reconcile_once` (896) — "Leg (a) first, every cycle" — which is swept by the daemon's wake-host thread spawned at `shellwake.rs:~1030`. The two other call sites in that file, 1117 and 1151, are unit tests: `#[cfg(test)]` opens at line 1042.

Neither sibling rig starts a wake host. `start_inproc_daemon` in `tunnel_e2e.rs` stands up three surfaces — seed control, a broker owning a hermetic `NetHost`, and tunnel control; `gateway_owner_shell_e2e.rs` adds drive control and nothing else. No `reconcile_once` sweep runs in either process, so nothing ever flips a bound identity back to offline and the race the fix closes has no driver. Both files reference `shellwake`, `reconcile_once` and the heal zero times.

`gateway_owner_shell_e2e.rs` is additionally already in the corrected order on its own: it writes `shell.pid` and calls `record_shell_launch` at lines 231-232, then binds at 233 — one bind call site, park immediately before it.

**Three earlier rationales for this exclusion were wrong, and are corrected here rather than quietly replaced:**

1. *"Neither file binds"* — false. Both bind through an `online_by_token` closure (`gateway:207`, `tunnel:153`) that shells out to `spt api --adapter mock-shell bind-shell`, a spelling no `bind(` search matches.
2. *"tunnel binds once, so there is no rebind"* — false. `tunnel_e2e` binds twice, at 219 and again at 268 after a relink.
3. *"tunnel parks no identity"* — false. Its `shell spawn` at line 216 records the launched binary's identity, and the rig's spawn template is an exit-0 noop, so a corpse IS recorded. What tunnel lacks is a live stand-in, which was never the load-bearing claim.

**The merge commit body at `a9e786b2` still carries version (1) and is knowingly left uncorrected.** The tree is gated on both boxes and the full unit sets ran on that exact object; a new sha would buy a complete re-gate plus a fresh rig-race roll in exchange for a prose fix that changes no tree byte. The correction lives here and on `releases#294` (comments `5614144564`, `5614211868`) instead.

All three tests that were changed keep their missed-transition premise, each with an inline comment stating so.

## Merge-order notes

1. Order completed: `#285` → `#286` → `#295` → `#287`, then the scope commit, then the test-only correction.
2. Head 7: `crates/spt-daemon/src/brain.rs` `net_status` conflicted; resolved keeping the HEAD side's `REQ-BRAIN-READ-BOUNDED-PER-CALL` tag.
3. Head 8: `CHANGELOG.md` conflicted under `[Unreleased]`/Fixed; resolved as a union (head-7 bullets kept, the member's two appended).
4. Scope commit: the canonical eight censused word-for-word, exactly two `required_stages` lines re-pinned in `traceable-reqs.toml`, `docs-site/src/changelog.md` regenerated. A third `#287` bullet was ruled OMIT — the strict clear was born `fb18e94b` and died `53f63c3a`, both unreleased, and `clear_shell_pid` is absent at `de5a44bc`, so the release-note baseline is the last release rather than the lane parent.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01R1dpz1xXZdTeyjGeKDSbNW
