# W1 tranche-2 — JIT plan (todlando), rev 2

Supersedes the rev-1 plan committed on the usher-u3 lane at `ee33d62`. Order
unchanged (#6 → #75 → #109); this revision carries what the source recon
actually found, so the next session starts from mechanisms rather than from the
field symptom.

**Builds are HELD** until deployah announces the fleet-0.53.0 daemon-restart
window CLOSED on this box. He pre-announced the roll on 2026-08-04 and I
answered CLEAR (nothing of mine spans it). Source recon and authoring proceed;
nothing below has been compiled.

## #6 — `spt shell relink --force` — AUTHORED, awaiting the window

Lane `build/w1t2-shell-relink-force` off main `30bbe22`, authored at `1906b7f`
(the commit says plainly it is unbuilt). `REQ-SHELL-RELINK-FORCE` minted and
activated doc/impl/unit/int. doyle ratified all four recon findings on the
issue; the two riders (the ephemeral refusal must NAME the escape; the
post-close probe must use the pid+birth authentication, never a bare alive
check) are folded into the requirement title and the code. `spt shell unlink`
was ruled a SEPARATE surface and re-homed as releases#152 — not this PR.

Outstanding, all build-window work, in order:

1. `cargo run -p xtask -- gen` — `docs-site/src/cli/reference.md` is generated
   from the binary's own `--help` and drift-gated in CI, so the new flag must
   land there through the generator, never by hand.
2. `traceable-reqs check` (the REQ is ACTIVE now — an unbuilt tag is a red).
3. clippy, units (`-p spt-daemon`, `-p spt`), then the new e2e
   `crates/spt/tests/shell_relink_force_e2e.rs`.
4. `binedge-check` — the new e2e is a NEW consumer site of the `mock-shell`
   fixture bin. Every existing mock-shell consumer sits in
   `crates/xtask/binedge-baseline.tsv` (the burn-down list of accepted reds),
   so mine will probably red too. Do NOT reflexively baseline it: read the
   verdict first, because the honest fix is the CI job building the fixture,
   and growing a burn-down list is the thing that list exists to shrink.

## #75 — `spt subnet status` — RECON DONE, two independent mechanisms

Both defects located in source; neither is fixed and no code is written.

### Defect 2 (the `7/1`) — the numerator counts CONNECTIONS, the denominator counts MEMBERSHIP

The line is composed in `crates/spt/src/cli.rs::render_peer_health_line`:

```
h.live_peers, h.peers_total.max(h.targets.len())
```

- The **denominator** is roster/membership-derived — it follows a subnet leave.
- The **numerator** is `PumpHealth::live_peers`, set from `conns.len()` in
  `crates/spt-daemon/src/pump/mod.rs` (`note_connected` / `note_disconnected` /
  `note_failed` call sites around :1027/:1084). `conns` is inserted into on
  EVERY `PRESENCE_CONNECTED` — the `is_target` flag is computed beside it and
  does not gate the insert — and an entry leaves only on
  `PRESENCE_DISCONNECTED`. Leaving a subnet does not disconnect anybody, so an
  ex-member's live QUIC connection keeps counting.

That is exactly the field specimen: 7 live connections, 1 remaining membership
target. The JIT's predicted shape ("count from membership, not from residue")
holds, and the fix should be the INTERSECTION of `conns` with the current
target set rather than a connection teardown at leave — a peer can be reached
through two subnets, and leaving one must not drop a connection the other still
justifies. Tearing down would also make the count right for the wrong reason.

### Defect 1 (an offline peer reads `degraded`) — needs a vocabulary ruling before code

`PumpHealth::verdict` (`crates/spt-daemon/src/pump/health.rs`) reaches
`DegradedPartial` whenever ANY target is in `failing`, which is populated by
`PRESENCE_DIAL_FAILED` for any reason at all — including the ordinary "that
peer's machine is off". The rendered word then points at THIS node.

The discriminant is already in the snapshot and is not being used: **a live
peer proves this node's egress works**, so failing peers beside a live one are
*their* absence, not our degradation. The failure `stage` is the second signal
(`address-resolution` / `quic-connect` are pre-handshake — consistent with "not
there"; `alpn` / `seed-proof-*` / `roster-exchange` mean we DID connect and the
fault is ours-or-theirs at a layer worth alarming about).

⚠ ASK DOYLE BEFORE BUILDING THIS: the degraded/healthy vocabulary is ADR-0039
Decision 5 + REQ-PEER-HEALTH-PARTIAL-DEGRADE (#41), and #41 exists precisely
because a live connection used to outvote failing peers and render green. A
naive "peers offline ⇒ not degraded" would re-open that defect from the other
side. The proposal to put to him is a THIRD word — peers-unreachable, distinct
from both healthy and degraded — never a widening of healthy. Two defects, two
teeth, per the original dispatch.

## #109 — perch GC for purged endpoints — untouched

Unchanged from rev 1: read the `KNOWN-HAZARDS` perch-directory section FIRST
(a dir carrying a record or a spool is OCCUPIED; ambiguity resolves toward
refusal; unreadable counts as occupied, never as residue), and make the GC's
refusal posture match it. Deletion is irreversible, refusal is recoverable.
Deliberately last.
