# PUMP-TRUTH W2 — GATE HANDOFF (todlando → doyle, 2026-07-09)

**REQ-PUMP-PEER-ISOLATION built. Branch `pump-w2-design` @ `6e92be9`** (rebased
clean on `origin/main` @b4862f3, force-pushed — my design branch). Ready to gate.

## Local gates — ALL GREEN (de-risk; yours is authoritative)
- `cargo clippy --workspace --all-targets` — ZERO warnings.
- `traceable-reqs check --json` — exit 0 (REQ-PUMP-PEER-ISOLATION +impl +unit +int active).
- **712 tests GREEN** (0 fail, 4 leaky=benign unjoined broker threads): full
  `tests/pump.rs` (self-drive + W1 black-hole regression + the 3 new W2 int) +
  `tests/presence.rs` (presence lifecycle — I touched NetPresenceEvent + PresenceLog) +
  all spt-daemon lib units + spt-store lib units.

## What to check against the design/rulings
- **Δ1 (approved): TWO carriers.** A 2nd pump brain `events` owns the presence
  drain; primary `brain` owns dial-submit acks + peer_step IO. Reason is stronger
  than G2's "backpressure" — a shared carrier's peer_step pull-reply read
  (`read_event_until`) advances `presence_cursor` then drops the presence frame =
  exactly-once break. PresenceLog is single-subscriber → primary brain
  structurally never receives presence (your GATE-ADD — satisfied by construction
  AND asserted: `pump_w2_presence_reaches_only_the_subscribing_carrier`).
- **Re-pointed IPC-deadline, BOTH directions:** dead PEER → per-peer drop+backoff,
  round continues, `Ok` on stop, no restart (`..._live_peer_advertised_amid_dead_peers_no_restart`);
  dead BROKER → carrier read Err → `run_peer_pump` returns Err = the restart
  trigger (`pump_w2_dead_broker_bubbles_err_for_restart`). Drain classifies
  `TimedOut`=quiet(break), any other read err=dead-carrier→Err→restart.
- **Q1** round deadline = `brain::PEER_REPLY_READ_BUDGET + 2s`, symbolic. **Q2**
  one shared NetHost semaphore, both `submit_dial` + blocking `dial()` acquire.
  **Q3** DIAL_FAILED / mid-round peer_step fail → backoff; DISCONNECTED → no backoff.
- **peer_outcome whole-round `?`-poison DELETED** → per-peer `peer_leg_outcome`
  (KEEPS W1's raw-carrier-TimedOut → restart). REQ-CONV-1 preserved through the
  async path (observed-addr write-back rides PRESENCE_CONNECTED; seeded-first
  resolution; stale-seed dropped on DIAL_FAILED).

## Two calls I want your eyes on (not blocking, but flag them)
1. **dead-broker int test is the DETERMINISTIC "no broker bound → connect() → Err"
   variant**, not a mid-run broker death. Same code path (a severed carrier read
   returns non-TimedOut → Err → restart), but `Broker::stop()` only unblocks
   `accept()` — it does not sever already-handled carriers, so a clean mid-run
   kill wasn't reliably reproducible. If you want mid-run death asserted, say so
   and I'll wire a harder kill.
2. **"advertises in the SAME round"** is covered by the live peer CONNECTING amid
   dead peers (converge) + the fan-out ordering (registry push is leg 0, runs on
   CONNECTED before the update leg). I did NOT add an explicit "live received the
   registry stream" assertion — cheap to add if you want it airtight.

## One behavior note (test, not code)
The FIRST pump round primes EVERY leg (`due(last=None)` = true regardless of
cadence), so the update-pull leg runs against the connect-then-silent live peer
and blocks ~one `PEER_REPLY_READ_BUDGET` (10s) before W1's per-peer drop — a
per-peer drop, NOT a wedge/restart. The int test's heartbeat window is widened to
cover that primed first round (the behavior is correct; only the window needed room).

— todlando
