The file C:\Users\decid\Documents\projects\spt-core\docs\DEFERRED.md has been updated successfully. (file state is current in your context — no need to Read it back)

| **`spt update fetch` single→set shape-upgrade at same version (REQ-UPD-8 transitional trap)**: `cmd_update_fetch` sets the rollback floor = `staged_version` (the monotonic counter), and the gate is a plain `candidate > floor`. A node that fetched+staged version N as a platform **single** (pre-0.3.2 fetch behavior) can never re-fetch version N as a multi-platform **set** — same counter → `Rollback{current:N, candidate:N}`. Bites the **seed-node bootstrap**: the first node to origin-`fetch` a release applies the single for its OWN platform, then can't re-stage the same version as a set → has no Windows/other-platform artifact to SERVE peers over P2P. Surfaced live in the v0.3.2 cross-platform rig verify (2026-06-09): kitsubito staged+applied the v6 single, then its v6-set re-fetch was refused; unblock was a manual `releases/` cache-clear before re-fetch. Counter vs semver is working as designed (counter = trust spine, semver = cosmetic) — the gap is purely shape-blind: the floor compares version only, ignoring single-vs-set. FIX options: (a) allow a same-version re-fetch when staged shape is `single` and an available `set` is strictly-richer (shape-upgrade allowance), or (b) seed-server flow stages the SET before applying its own single, or (c) a `--force`/`--restage` flag. NOTE — only bites the one migration hop onto 0.3.2; once a node is on 0.3.2 with a fresh cache, future releases are vN+1 and stage clean. Mint a REQ before fixing | v0.3.2 cross-platform rig verify (2026-06-09; user-flagged via session watch) | Transitional-only: the workaround (cache-clear before staging the set) is reliable and was used to complete the v0.3.2 fleet roll; a code fix only saves the manual clear on same-version shape upgrades, which won't recur after the 0.3.2 hop | A future release that again changes staged-artifact SHAPE at a same/non-incrementing counter, or making `spt update fetch` self-sufficient for solo seed-nodes (pairs with the origin-source bootstrap row above) |

| **On-disk `current_exe` reconcile after auto-rollback (the D6-2 reboot residual)**: readiness-gated auto-rollback (ADR-0018 Q7, restoration D6-2) is **record-driven selection** — after a rollback the broker's supervisor keeps spawning the last-known-good `.old-N` binary, chosen from the durable `RolledBack` record, so the rescue survives a reboot for free **with no file rename at the failure instant** (the brittle path the design rejected). But the bytes on disk at `current_exe` are STILL the quarantined bad version. The supervisor rescues the **brain** (it never execs `current_exe` while a `RolledBack` record stands), but an OS-service / autostart / `ensure_running` relaunch execs `current_exe` **as the broker** — and **if the bad binary panics before broker bind, the node is down until manual intervention** (record-driven selection cannot save a binary that won't boot). FIX = a calm-path reconcile: on the next clean `apply` (or a broker self-reconcile once stable), rename the good bytes over `current_exe` so the on-disk seat matches the running selection. Deliberately NOT a failure-time rename | Restoration D6-2 (ADR-0018 Q7, open-call-3, 2026-06-10) — record-driven selection rescues the brain; the on-disk seat reconcile defers | The reboot-survives-via-record path is correct NOW for the common case (broker boots, supervisor re-selects the good binary); the residual only bites when the broker process itself re-execs the quarantined `current_exe` and that binary won't even bind. Failure-time rename is the brittle path the design rejected; the calm-path reconcile needs the next clean-apply seam | First field rollback where the broker (not just the brain) restarts onto the quarantined on-disk bytes — or the D7 process-survival proof exercising a broker re-exec after rollback |

| **Quarantine operator override (`spt update apply --force` — the note-i escape hatch)**: D6-2's quarantine guard refuses re-applying a version that auto-rolled-back on this node (the `RolledBack` record is the marker; clears naturally when N+1 stages). But a version whose failure was **environmental** (a transient boot condition, not bad bytes) leaves the node **permanently allergic** to a genuinely-good version with no escape but staging a newer one. FIX = an explicit operator override (`spt update apply --force`, or a `spt update unquarantine <version>`) that clears the `RolledBack` marker and re-opens the apply for that version — a deliberate, operator-gated act, never automatic | Restoration D6-2 (ADR-0018 Q7, note-i, 2026-06-10) — quarantine ships; the override defers | The natural N+1 clear covers the common "the next release fixes it" path; the override only matters when the SAME version must be retried after an environmental fix. Operator-gated re-apply is a small CLI + record-clear, deferrable to the alarm/adapter era | First node permanently allergic to a genuinely-good version (environmental rollback), or the M8 update-CLI polish |

-| **Broker-side bound on brain-waiting QUIC ops (the pump-IPC-deadline B-half)**: the brain-side deadline (REQ-HAZARD-PUMP-IPC-DEADLINE, KNOWN-HAZARDS 7.6) stops the single-threaded pump wedging when a peer black-holes, by bounding the pump's brain-IPC reads and escalating a TimedOut to a supervised restart. But the ROOT cause is broker-side: the broker's `net_open_stream` / `net_stream_send` / `net_dial` handlers make the brain wait on a QUIC operation to a dead peer with no bound of their own, so the brain only escapes via its own deadline (a 30s stall + a full pump restart each time). FIX = the broker must never make a brain wait unbounded on a QUIC op — bound those handlers broker-side (a QUIC-level timeout that returns an Error event promptly), so a black-holed peer fails the single `peer_step` cleanly (ordinary per-peer abort + redial) without poisoning the client or forcing a pump restart. The broker is RESIDENT by design (CONTEXT §"broker update frequency: rare"), so this cannot reach the deployed fleet without a broker-update path — hence deferred to the next planned broker-update batch rather than riding the brain-only v0.4.1 roll the A-half ships on. **Added motivation (Windows, KH 7.6):** the A-half's reader-thread carrier leaks ONE `pump-ipc-reader` thread per wedge event — on a supervised restart the old reader is left blocked in `read_frame` holding its `RecvHalf`, and interprocess split halves share one OS handle (closes only when BOTH drop), so on a named pipe the broker may never signal the disconnect and the old reader can park indefinitely (especially while the broker itself is wedged on the dead-peer QUIC await — the very thing B fixes). Bounded (one thread per actual wedge, not per restart round — the post-restart conn cache is fresh, so the dead peer is re-dialed, not re-wedged on a cached dead conn), but B is the real cure: bounding the broker's QUIC await makes the brain's read return promptly, so the reader thread is never left parked | Pump-stall diagnosis 2026-06-11 (doyle ruling A-now / B-deferred) | The brain-side A-half fixes the fleet NOW via the brain-only update machinery (v0.4.1 candidate) and makes the wedge self-heal in 5s instead of 2.2h; B is the deeper correctness fix but only reachable through the rare broker-update path. Mint a REQ (broker-side QUIC-op bound) before building | Next planned broker-update batch (folds in with any other resident-broker change) |

+| **✅ RESOLVED — shipped v0.8.3 (REQ-HAZARD-BROKER-QUIC-DEADLINE, KNOWN-HAZARDS 7.8).** ~~Broker-side bound on brain-waiting QUIC ops (the pump-IPC-deadline B-half)~~: the brain-side deadline (REQ-HAZARD-PUMP-IPC-DEADLINE, KNOWN-HAZARDS 7.6) stops the single-threaded pump wedging when a peer black-holes, by bounding the pump's brain-IPC reads and escalating a TimedOut to a supervised restart. But the ROOT cause is broker-side: the broker's `net_open_stream` / `net_stream_send` / `net_dial` handlers make the brain wait on a QUIC operation to a dead peer with no bound of their own, so the brain only escapes via its own deadline (a 30s stall + a full pump restart each time). FIX = the broker must never make a brain wait unbounded on a QUIC op — bound those handlers broker-side (a QUIC-level timeout that returns an Error event promptly), so a black-holed peer fails the single `peer_step` cleanly (ordinary per-peer abort + redial) without poisoning the client or forcing a pump restart. The broker is RESIDENT by design (CONTEXT §"broker update frequency: rare"), so this cannot reach the deployed fleet without a broker-update path — hence deferred to the next planned broker-update batch rather than riding the brain-only v0.4.1 roll the A-half ships on. **Added motivation (Windows, KH 7.6):** the A-half's reader-thread carrier leaks ONE `pump-ipc-reader` thread per wedge event — on a supervised restart the old reader is left blocked in `read_frame` holding its `RecvHalf`, and interprocess split halves share one OS handle (closes only when BOTH drop), so on a named pipe the broker may never signal the disconnect and the old reader can park indefinitely (especially while the broker itself is wedged on the dead-peer QUIC await — the very thing B fixes). Bounded (one thread per actual wedge, not per restart round — the post-restart conn cache is fresh, so the dead peer is re-dialed, not re-wedged on a cached dead conn), but B is the real cure: bounding the broker's QUIC await makes the brain's read return promptly, so the reader thread is never left parked | Pump-stall diagnosis 2026-06-11 (doyle ruling A-now / B-deferred) | The brain-side A-half fixes the fleet NOW via the brain-only update machinery (v0.4.1 candidate) and makes the wedge self-heal in 5s instead of 2.2h; B is the deeper correctness fix but only reachable through the rare broker-update path. Mint a REQ (broker-side QUIC-op bound) before building | Next planned broker-update batch (folds in with any other resident-broker change) |

| **Durable in-daemon alarm scheduler (one-shot deadline machinery — the Q4/V3 deferral)**: the broker/brain restoration (ADR-0018 Q4) fixes the *rule* for one-shot scheduled events — persist the absolute `target-time` at creation; every brain start (update *or* crash) reads it and fires-if-due; **never reset on crash** (a user's "remind me at 3pm" is a commitment that must outlive any restart). But it deliberately does **not** build the machinery: the spt-core daemon has **no one-shot consumer today** — `alarm` exists only as an event *shape* (`spt-proto`) + relay handling (`psyrelay.rs:93`) + a test fixture; the actual "wait until target, fire the TIMED PULSE" timer lives in the **legacy owl listener in-memory** (BROKER-BRAIN-SPLIT-RESTORATION §7). Building the one-shot deadline machinery in the restoration milestone would ship **untested dead code** (violates activate-don't-pre-fail). FIX = port alarms into the daemon as a durable scheduler that rides the Q4 one-shot rule (persist target-time at creation, fire-if-due on every brain start, survive both crash and update). The periodic-loop half of Q4 (anchor+interval derive) DOES ship in restoration D5; only the one-shot machinery defers here. | Restoration milestone D5 (ADR-0018 Q4/V3, 2026-06-09) — rule fixed, machinery deferred | The daemon has no one-shot consumer to exercise it; the periodic-deadline mechanism (the phase-significant pulse loop) ships in D5 and proves out the disk-anchored-deadline pattern the alarm port will reuse | The alarm port — porting the legacy in-memory alarm timer into the daemon as a durable scheduler (first real one-shot consumer); reuses the D5 disk-deadline pattern + the Q4 one-shot rule |

| **Autonomous session-digest freshness + Option-C re-home (M9 ADR-0008 amendment deferral)**: M9 re-founded the digest as an ON-DEMAND projection of normalized session logs (`spt-term::projection`; `spt-daemon::digest::project_endpoint_digest`) — snapshot-pull and the structured-delta-stream CONTRACT ship, deltas driven by pulls / `api digest-entry` pushes. Two pieces deferred, both because they have **no consumer yet** (Shell=M10, GUI/frontend pane, Gateway agent-window — none exist): (a) the **autonomous file-watch→publish freshness nudge** (a watcher that re-projects + publishes when the log grows on its own, vs today's pull/push-driven publishes) — CONTEXT.md "session digest" anticipates this as "an incremental normalize story (design-phase concern)"; (b) the **Option-C opt-in persistence re-home** (the byte-feed engine drove per-turn persistence off `pty_digest.persist`, now deleted; re-homing it onto a `[history]`/digest config seam now = a manifest surface with nothing reading it). Building either now = a speculative realtime subsystem with no reader (the M9-PLAN §9 "no new realtime subsystem" watch-item). | M9 Wave 3 / G3 (doyle ruling 2026-06-13) — snapshot-pull is the G3 bar, delta-stream contract ships | Both ride a live consumer: the digest works topology-independently TODAY (pull projects real content; a subscriber follows and gets push-driven deltas). Autonomous freshness only matters when a frontend pane streams it continuously; Option-C only matters when something reads the coarse activity log. Deferring honors CONTEXT.md's anticipated staging, not a scope cut | The **consuming-frontend milestone** that streams the digest live (Shell M10 drive/sensory pane, the GUI "latest session output" pane, or the Gateway agent-window) — wire the file-watch nudge + re-home Option-C onto a digest config seam then, with a real reader to exercise both |

| **Two-origin `owl_message` context-tap subtype refinement (M10 ADR-0019 deferral)**: the two-origin merge's owl-message producer (`spt::api::startup` `deliver` closure) taps the live-agent **`emit` chokepoint**, so EVERY delivered frame — including resurfaced **notif** frames and shell-context rows — is recorded as a single coarse `owl_message` context-injection entry (`context_kind:"owl_message"`). The data is not wrong (a notif IS injected context), only coarsely labeled; the digest is a glanceable data model this milestone, with no consumer that distinguishes the subtypes yet. Splitting the tap into honest subtypes (true peer message vs notif vs shell-context) means classifying the frame at the delivery seam. | M10 Wave 3 / gate (doyle ruling 2026-06-13, flag 2 ACCEPTED with this tracked condition) | Same logic as the M9 freshness deferral above: refinement only matters when a surface reads + renders the context-injection category by subtype (GUI collapse/expand, or the echo-reads-digest delta loop). Coarse-but-honest labeling is correct for a data-model-only milestone | The **consuming-frontend / echo-reads-digest milestone** — split the `emit`-seam tap by frame type (peer message vs notif vs shell-context) when a reader renders the subtypes |


Add the CHANGELOG bullet under [Unreleased] (version-framed, no internal codes — deployah frames it into [0.8.3] at bump):


Edit

## [Unreleased]

### Fixed

- **A dead or unresponsive peer can no longer stall background sync.** The daemon now bounds every network operation it makes on a live agent's behalf, so a roster peer that has gone offline (or stopped responding mid-handshake) fails fast as an ordinary, recoverable error instead of hanging the daemon's peer-sync loop. Previously such a peer could freeze background synchronization for tens of minutes and force repeated internal restarts; now the peer is simply skipped and retried on the next cycle, and a healthy node's sync keeps flowing. Normal peers are unaffected (no added latency).

## [0.8.2] - 2026-06-16


<tool_use_error>File has not been read yet. Read it first before writing to it.</tool_use_error>

Error: File has not been read yet. Read it first before writing to it.


1	# Changelog
2
3	All notable **user-facing** changes to `spt` — what a person running the CLI
4	notices or does differently. The `## [<version>]` section of each release
5	becomes that release's GitHub Release notes verbatim (see
6	`docs/RELEASE-RUNBOOK.md`). This project follows
7	[Keep a Changelog](https://keepachangelog.com) and semantic versioning
8	(pre-1.0: breaking changes bump the minor).
9
10	## [Unreleased]
11
12	## [0.8.2] - 2026-06-16
13
14	A reliability patch for command-template argument handling and dead-on-launch Psyche reporting.
15

# Changelog

All notable **user-facing** changes to `spt` — what a person running the CLI
notices or does differently. The `## [<version>]` section of each release
becomes that release's GitHub Release notes verbatim (see
`docs/RELEASE-RUNBOOK.md`). This project follows
[Keep a Changelog](https://keepachangelog.com) and semantic versioning
(pre-1.0: breaking changes bump the minor).

## [Unreleased]

## [0.8.2] - 2026-06-16

A reliability patch for command-template argument handling and dead-on-launch Psyche reporting.


## [Unreleased]

### Fixed

- **A dead or unresponsive peer can no longer stall background sync.** The daemon now bounds every network operation it makes on a live agent's behalf, so a roster peer that has gone offline (or stopped responding mid-handshake) fails fast as an ordinary, recoverable error instead of hanging the daemon's peer-sync loop. Previously such a peer could freeze background synchronization for tens of minutes and force repeated internal restarts; now the peer is simply skipped and retried on the next cycle, and a healthy node's sync keeps flowing. Normal peers are unaffected (no added latency).

## [0.8.2] - 2026-06-16


The file C:\Users\decid\Documents\projects\spt-core\CHANGELOG.md has been updated successfully. (file state is current in your context — no need to Read it back)

## [Unreleased]

### Fixed

- **A dead or unresponsive peer can no longer stall background sync.** The daemon now bounds every network operation it makes on a live agent's behalf, so a roster peer that has gone offline (or stopped responding mid-handshake) fails fast as an ordinary, recoverable error instead of hanging the daemon's peer-sync loop. Previously such a peer could freeze background synchronization for tens of minutes and force repeated internal restarts; now the peer is simply skipped and retried on the next cycle, and a healthy node's sync keeps flowing. Normal peers are unaffected (no added latency).

## [0.8.2] - 2026-06-16

+- **A dead or unresponsive peer can no longer stall background sync.** The daemon now bounds every network operation it makes on a live agent's behalf, so a roster peer that has gone offline (or stopped responding mid-handshake) fails fast as an ordinary, recoverable error instead of hanging the daemon's peer-sync loop. Previously such a peer could freeze background synchronization for tens of minutes and force repeated internal restarts; now the peer is simply skipped and retried on the next cycle, and a healthy node's sync keeps flowing. Normal peers are unaffected (no added latency).

A reliability patch for command-template argument handling and dead-on-launch Psyche reporting.


Activate the `doc` stage now that the hazard doc carries the `[doc->...]` tag:


required_stages = ["impl", "unit", "int"]  # registry-first mint (rule 3); activated per wave in v0.8.3. impl = NetHost::bounded_block_on

required_stages = ["doc", "impl", "unit", "int"]  # registry-first mint (rule 3); activated per wave in v0.8.3. doc = KNOWN-HAZARDS 7.8 (+ the 7.6 B-half-fixed reword + DEFERRED.md:42 RESOLVED). impl = NetHost::bounded_block_on


The file C:\Users\decid\Documents\projects\spt-core\traceable-reqs.toml has been updated successfully. (file state is current in your context — no need to Read it back)

title = "The broker bounds every brain-waiting QUIC op (dial / open_stream / send_stream) so a black-holed or dead peer fails PROMPTLY with an ORDINARY error the broker REPLIES, never an unbounded await. The bound (< the brain's 30s PUMP_PEER_IO_TIMEOUT so the BROKER fires first) surfaces to the pump as a normal broker error reply → peer_outcome's non-TimedOut arm → drop conn + redial next tick, the round CONTINUES and the heartbeat keeps advancing — it must NEVER manifest as the brain's own read-deadline (the A-half poison → supervised-restart path REQ-HAZARD-PUMP-IPC-DEADLINE guards). Exactly-once is preserved: a timed-out journaled op fails INSIDE its apply_once closure so no phantom conn_id/stream_id is recorded and a fresh tick re-dials cleanly. The happy path is unchanged (a live peer completes with zero added latency; the bound only bites a non-responsive peer). This is the ROOT-cause cure for the 2.2h hfenduleam pump wedge — a dead roster peer whose QUIC path the broker awaited unbounded — recurring on hfenduleam 2026-06-16."

-required_stages = ["impl", "unit", "int"]  # registry-first mint (rule 3); activated per wave in v0.8.3. impl = NetHost::bounded_block_on wrapping dial/open_stream/send_stream's QUIC await sites under a quic_op_timeout (default 10s = BROKER_QUIC_OP_TIMEOUT_MS, test-overridable via set_quic_op_timeout); unit = the bound wrapper returns a prompt non-TimedOut error on a never-completing op + a fast op is untouched [nethost.rs]; int = a black-holing peer (membership-mismatch hang) → the broker REPLIES an ordinary error within the bound (not a wedge) + exactly-once-on-timeout (journal not applied, conn table empty) [tests/netbroker.rs], and the pump round survives a dead peer — heartbeat monotonic-advances + run_peer_pump exits Ok (no PEER_PUMP_RESTART) [tests/pump.rs]. doc activates with the KNOWN-HAZARDS 7.8 + 7.6 B-half-fixed reword + DEFERRED.md:42-resolved commit

+required_stages = ["doc", "impl", "unit", "int"]  # registry-first mint (rule 3); activated per wave in v0.8.3. doc = KNOWN-HAZARDS 7.8 (+ the 7.6 B-half-fixed reword + DEFERRED.md:42 RESOLVED). impl = NetHost::bounded_block_on wrapping dial/open_stream/send_stream's QUIC await sites under a quic_op_timeout (default 10s = BROKER_QUIC_OP_TIMEOUT_MS, test-overridable via set_quic_op_timeout); unit = the bound wrapper returns a prompt non-TimedOut error on a never-completing op + a fast op is untouched [nethost.rs]; int = a black-holing peer (membership-mismatch hang) → the broker REPLIES an ordinary error within the bound (not a wedge) + exactly-once-on-timeout (journal not applied, conn table empty) [tests/netbroker.rs], and the pump round survives a dead peer — heartbeat monotonic-advances + run_peer_pump exits Ok (no PEER_PUMP_RESTART) [tests/pump.rs]. doc activates with the KNOWN-HAZARDS 7.8 + 7.6 B-half-fixed reword + DEFERRED.md:42-resolved commit

title = "Elevation guidance on Unix names the binary's ABSOLUTE path under sudo (a user-local install ~/.local/bin · ~/.cargo/bin is not on sudo's secure_path, so bare `sudo spt` dies 'command not found'); gated commands auto-elevate on an interactive TTY, else print the runnable hint (5.10)"


Bash

traceable-reqs check 2>&1 | grep -iE "BROKER-QUIC|FAIL|MISSING|ERROR" | head; echo "exit=${PIPESTATUS[0]}"; echo "=== full exit ==="; traceable-reqs check >/dev/null 2>&1; echo "traceable exit: $?"

Verify doc stage + overall traceable exit


       Peer address seeding, both cold starts: durable peer-addrs.json (identity dir) maps peer pubkey → last-known dialable address; the pump's resolver consults it FIRST with id-only discovery fallback on miss or dial failure (a stale addr never strands a peer); written by the pairing ceremony (both sides, from the live connection) and by the pump on successful connect; post-join first sync and post-restart resync converge in seconds, not ~1 min (M8 decisions 14, 20)
       Net-bind boot-race resilience: a daemon that comes up net-less (NetHost::start failed — e.g. the systemd unit autostarted before the network/DNS stack was ready, `Failed to create an address lookup service`) must SELF-HEAL — retry the net bring-up in the background with capped backoff and, on success, attach net to the broker + spawn the dispatcher/peer-pump (which today are gated on `net_up` at boot and so never start, leaving the node silently unreachable until a manual restart — kitsubito 2026-06-08). Status surfaces the net-less state honestly (a net-less broker renders as 'no connection', not only a pump-STALLED line with a bogus pre-boot heartbeat age). The installer's autostart unit waits for the network (`Wants=/After=network-online.target`) as belt-and-suspenders.
  [OK] REQ-HAZARD-BROKER-QUIC-DEADLINE  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int
       The broker bounds every brain-waiting QUIC op (dial / open_stream / send_stream) so a black-holed or dead peer fails PROMPTLY with an ORDINARY error the broker REPLIES, never an unbounded await. The bound (< the brain's 30s PUMP_PEER_IO_TIMEOUT so the BROKER fires first) surfaces to the pump as a normal broker error reply → peer_outcome's non-TimedOut arm → drop conn + redial next tick, the round CONTINUES and the heartbeat keeps advancing — it must NEVER manifest as the brain's own read-deadline (the A-half poison → supervised-restart path REQ-HAZARD-PUMP-IPC-DEADLINE guards). Exactly-once is preserved: a timed-out journaled op fails INSIDE its apply_once closure so no phantom conn_id/stream_id is recorded and a fresh tick re-dials cleanly. The happy path is unchanged (a live peer completes with zero added latency; the bound only bites a non-responsive peer). This is the ROOT-cause cure for the 2.2h hfenduleam pump wedge — a dead roster peer whose QUIC path the broker awaited unbounded — recurring on hfenduleam 2026-06-16.
       A surfaced concurrent context pair is durably preserved (both versions, tracked artifacts) until a strictly dominating write clears it; no reconcile failure path discards an unmerged version (6.6, ADR-0013)
       The brain's daemon-hosted Psyche lifecycle surfaces a host-FAILURE on the live perch (harness-diagnosable) and runs net-INDEPENDENTLY. When reconcile_once→host_one→spawn_psyche fails for a state=live_agent+status=online endpoint (e.g. the adapter's psyche binary absent from its install dir, REQ-INSTALL-11), the failure MUST be written to the perch info.json as a CURRENT-STATE field (reason + ts + attempt count; overwritten each 5s retry, CLEARED on successful host) and surfaced by `spt endpoint list`/status — never left as an eprintln on the brain's invisible stderr where a harness reading only perch state is blind. status=online stays authoritative (agent reachable; only the Psyche is missing — brain-restart rehydrate legitimately has online-without-Psyche windows), so this is a SEPARATE psyche-host-health field, never a status de-stamp. Net-independence is a locked-in invariant: spawn_live_host (brainproc.rs:230) reaches the reconcile and hosts the Psyche on a net-less/unpaired/peer-pump-STALLED node, proven by a REAL detached-daemon E2E (real broker→brain-child, real api seed+listen, real install-dir psyche binary). spt-core SURFACES the failure; the adapter owns fixing its packaging.
       A daemon-hosted Psyche that spawns then EXITS IMMEDIATELY is a host failure, surfaced like a spawn failure (closes the v0.8.1 residual masking): the REQ-HAZARD-LIVEHOST-BOOT-RACE signal stamps `psyche_host_error` only when `spawn_psyche` returns Err, NOT when the detached spawn() returns Ok but the child dies within moments (e.g. a bad-argv child exiting 2 — the F-009 case). That leaves the residual 'online + no Psyche + no cause' gap: the nested `{id}-psyche` info.json is written status=online with a real-but-DEAD pid and the PARENT perch carries NO psyche_host_error (perri's F-010: tasklist showed 0 host procs across the window while info.json read online). The host MUST confirm RESIDENCY — a hosted child not alive (or whose `{id}-psyche` perch never re-registers / has a dead pid) within N seconds of spawn is treated as a host failure: stamp the parent perch `psyche_host_error{reason:"host not resident within <n>s (psyche perch missing/dead pid)"}` (and do not leave a phantom online nested perch). Closes the last masking gap the v0.8.1 fix left open. perri's F-010 (v0.8.1 dogfood). Sibling of REQ-HAZARD-LIVEHOST-BOOT-RACE.
       Concurrent SQLite openers (registry/spool) must not fail with 'database is locked' (4.7)
       Stale registry entries degrade to fallback, never hard-fail (4.3)
       Command-template substitution fills argv ELEMENTS, not a re-tokenized string: spt-core currently `fill_template`s {key} values INTO the command STRING and THEN `tokenize`s the filled string (runtime.rs:94/122), so a multi-word {key} value whitespace-SPLITS into multiple argv tokens unless the adapter hand-quotes the placeholder, and a value containing a `"` (or `;`) injects/breaks tokenization (shell-injection-adjacent). A filled value MUST become exactly ONE argv element regardless of spaces/quotes in the value. Fix: tokenize the TEMPLATE into argv FIRST, then `fill_template` EACH token, so a `{key}` slot resolves to a single element and the value never participates in tokenization (no whitespace-split, no quote/semicolon injection); preserve the missing-key / empty-command errors and `{{`/`}}` non-interpretation. perri's F-009 (v0.8.1 dogfood, argv-capture-confirmed): a multi-word `{psyche_prompt}` = "PSYCHE REVIVAL time: epoch-ms:… incoming event: (none)" arrived as argv[6..12] (7 stray tokens), the harness runner strict-parsed `--prompt` against the 2nd word, exited 2 within ~1s → phantom hosted perch. Applies to EVERY [session.<role>] template (psyche_init, extractor, notif, …); digest survives today only because its fills ({session_id}/{source}) are single-token.
exit=0
=== full exit ===
traceable exit: 0


traceable exit 0 — all four stages (`+doc +impl +unit +int`). Commit 3 (docs).


git add docs/KNOWN-HAZARDS.md docs/DEFERRED.md CHANGELOG.md traceable-reqs.toml && git commit -q -m "v0.8.3 docs: KNOWN-HAZARDS 7.8 + 7.6 B-half-fixed reword + DEFERRED resolved + CHANGELOG

doc stage for REQ-HAZARD-BROKER-QUIC-DEADLINE:
- KNOWN-HAZARDS 7.8: new subsection (the broker-side QUIC-op bound), with
  the [doc->REQ-HAZARD-BROKER-QUIC-DEADLINE] tag + a conformance row.
- KNOWN-HAZARDS 7.6: the two 'B-half deferred (DEFERRED.md)' lines now
  read 'shipped in v0.8.3 as 7.8'.
- DEFERRED.md:42: marked RESOLVED (shipped v0.8.3).
- CHANGELOG [Unreleased]: a version-framed user-facing bullet (no
  internal codes) for deployah to fold into the [0.8.3] release body.
- traceable: activate REQ-HAZARD-BROKER-QUIC-DEADLINE doc stage
  ([doc,impl,unit,int]); traceable-reqs check EXIT 0.

Co-authored by: todlando" && git log --oneline -4

Commit docs


f4dc053 v0.8.3 docs: KNOWN-HAZARDS 7.8 + 7.6 B-half-fixed reword + DEFERRED resolved + CHANGELOG
cece4a6 v0.8.3 F-B-half: bound broker-side QUIC ops (impl+unit+int)
69af744 v0.8.3 base: mint REQ-HAZARD-BROKER-QUIC-DEADLINE (registry-first)
4ac17c2 release: v0.8.2 — template-argv fill + non-resident Psyche host reporting


Three clean commits. Now the GATE BAR. Start with the exact-CI clippy (workspace-wide per the preflight rule) + docs-drift gen, in parallel.


cargo clippy --workspace --all-targets -- -D warnings 2>&1 | tail -20

Workspace clippy, deny warnings (exact CI)


    Checking spt-proto v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\spt-proto)
    Checking spt-store v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\spt-store)
    Checking mock-adapter v0.8.2 (C:\Users\decid\Documents\projects\spt-core\adapters\mock)
    Checking spt-msg v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\spt-msg)
    Checking spt-runtime v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\spt-runtime)
    Checking spt-term v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\spt-term)
    Checking spt-net v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\spt-net)
    Checking spt-live v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\spt-live)
    Checking spt-daemon v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\spt-daemon)
    Checking xtask v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\xtask)
    Checking spt v0.8.2 (C:\Users\decid\Documents\projects\spt-core\crates\spt)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 13.71s


Clippy clean workspace-wide. Now docs-drift gen + check (no CLI change expected, but run it):


cargo run -q -p xtask -- gen 2>&1 | tail -5; echo "=== git status post-gen ==="; git status --short; echo "=== xtask check ==="; cargo run -q -p xtask -- check 2>&1 | tail -15; echo "check exit: ${PIPESTATUS[0]}"

Docs-drift gen + check


xtask gen: wrote C:\Users\decid\Documents\projects\spt-core\docs-site/src/cli/reference.md
=== git status post-gen ===
 M docs-site/src/cli/reference.md
=== xtask check ===
xtask check: OK
check exit: 0


`gen` modified reference.md though I added no CLI command. Inspect the diff:


git diff docs-site/src/cli/reference.md | head -40

Inspect reference.md drift


warning: in the working copy of 'docs-site/src/cli/reference.md', LF will be replaced by CRLF the next time Git touches it


Diff is empty (only a CRLF line-ending warning) — content identical, no real drift. Restore the file and re-confirm check passes against the committed version:


git checkout docs-site/src/cli/reference.md 2>&1; echo "=== status ==="; git status --short; echo "=== re-check ==="; cargo run -q -p xtask -- check 2>&1 | tail -5; echo "check exit: ${PIPESTATUS[0]}"

Restore reference.md + reconfirm check


Updated 1 path from the index
=== status ===
=== re-check ===
xtask check: OK
check exit: 0


Working tree clean, docs-drift passes (the change was CRLF-only). Now the critical **shared-seam sweep** — I changed the broker net seam, so run ALL tests doyle named, full files. Locate them.


find crates -path '*/tests/*' \( -name 'netbroker.rs' -o -name 'pump.rs' -o -name 'mesh.rs' -o -name 'replicate.rs' -o -name 'wanmsg.rs' -o -name 'attach.rs' \) -not -path '*/target/*'; echo "=== daemon_lifecycle_real_brain ==="; grep -rln "daemon_lifecycle_real_brain" crates --include=*.rs | grep -v target

Locate seam test files


crates/spt-daemon/tests/attach.rs
crates/spt-daemon/tests/mesh.rs
crates/spt-daemon/tests/netbroker.rs
crates/spt-daemon/tests/pump.rs
crates/spt-daemon/tests/replicate.rs
crates/spt-daemon/tests/wanmsg.rs
=== daemon_lifecycle_real_brain ===
crates/spt/tests/livehost_bootrace_e2e.rs
crates/spt-daemon/tests/daemon_e2e.rs


`daemon_lifecycle_real_brain` lives in `daemon_e2e.rs`. Run the full seam suite (all files doyle named, complete):


cargo test -p spt-daemon --test netbroker --test pump --test mesh --test replicate --test wanmsg --test attach 2>&1 | grep -E "Running|test result|FAILED|error\[|panicked" | tail -40

Run broker net-seam test suite


     Running tests\attach.rs (target\debug\deps\attach-cf2e11d57a77e7c8.exe)
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.47s
     Running tests\mesh.rs (target\debug\deps\mesh-91486225ca965881.exe)
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.70s
     Running tests\netbroker.rs (target\debug\deps\netbroker-06288c72f971fd61.exe)
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.77s
     Running tests\pump.rs (target\debug\deps\pump-eea49d224d42cbab.exe)
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.29s
     Running tests\replicate.rs (target\debug\deps\replicate-a75047134625e490.exe)
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s
     Running tests\wanmsg.rs (target\debug\deps\wanmsg-b28c7e651e6225d5.exe)
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.24s


All green. Now `daemon_e2e` (holds `daemon_lifecycle_real_brain` — the v0.8.2 sibling-break) — the real-broker E2E:


cargo test -p spt-daemon --test daemon_e2e 2>&1 | grep -E "Running|test result|FAILED|error\[|panicked|daemon_lifecycle" | tail -30

Run daemon_e2e (daemon_lifecycle_real_brain)


     Running tests\daemon_e2e.rs (target\debug\deps\daemon_e2e-bb89eb474c38540f.exe)
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.11s


`daemon_lifecycle_real_brain` passes (the v0.8.2 sibling — clean). Run the full spt-daemon lib units (effect/pump-peer_outcome/brain/nethost) to close the seam sweep:


cargo test -p spt-daemon --lib 2>&1 | grep -E "test result|FAILED|error\[|panicked" | tail -10

Run spt-daemon lib unit tests


test result: ok. 314 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.29s


Gate bar complete — clippy clean, traceable EXIT 0 (all 4 stages), seam sweep all green (netbroker/pump/mesh/replicate/wanmsg/attach/daemon_lifecycle_real_brain + 314 lib units), docs-drift clean. Push + open PR.


git push -u origin v0.8.3-broker-quic-deadline 2>&1 | tail -8

Push branch


remote:
remote: Create a pull request for 'v0.8.3-broker-quic-deadline' on GitHub by visiting:
remote:      https://github.com/SaberMage/spt-core/pull/new/v0.8.3-broker-quic-deadline
remote:
branch 'v0.8.3-broker-quic-deadline' set up to track 'origin/v0.8.3-broker-quic-deadline'.
To https://github.com/SaberMage/spt-core.git
 * [new branch]      v0.8.3-broker-quic-deadline -> v0.8.3-broker-quic-deadline


cat > /tmp/pr-body.md <<'EOF'
## v0.8.3 — broker-side QUIC-op bound (the pump-IPC-deadline B-half)

Resolves `DEFERRED.md:42` — the deferred broker-side complement of `REQ-HAZARD-PUMP-IPC-DEADLINE` (the A-half, v0.4.1). **PATCH 0.8.2 → 0.8.3.** Root-cause cure for the 2.2h hfenduleam pump wedge, recurring on hfenduleam **2026-06-16**.

### Root cause
A DEAD roster peer → the broker's brain-facing QUIC op (`dial`/`open_stream`/`send_stream`) awaits the dead peer's QUIC path **unbounded**. The A-half bounds only the brain's *read*, not the broker's *await*, so the brain escapes only via its own 30s deadline → a 30s stall + a full pump restart each round, and the supervised restart re-dials the same dead peer and re-wedges.

### The fix
`NetHost::bounded_block_on` wraps the three QUIC await sites in `tokio::time::timeout` under `quic_op_timeout` (default `BROKER_QUIC_OP_TIMEOUT_MS` = 10s). On elapse the future is dropped (cancelling the in-flight op) and a non-`TimedOut` `io::Error` is returned → the broker REPLIES an ordinary error frame.

### The four invariants
1. **Ordinary error, NOT TimedOut.** The broker REPLIES an error frame; the brain reconstructs `ErrorKind::Other` (`Brain::net_dial`/`net_open_stream`/`net_stream_send` → `io::Error::other`), so `pump::peer_outcome` takes the non-TimedOut arm (drop conn + redial, round continues, heartbeat advances). It never manifests as the brain's own read-deadline (the A-half poison → supervised-restart path).
2. **Bound < 30s, broker fires first.** `10s` — comfortably above any legit LAN/relay connect+seed-proof round-trip (sub-second typical, a few seconds on a slow relay), **20s below** the brain's 30s `PUMP_PEER_IO_TIMEOUT` (margin covers the error frame's IPC transit + the brain's read scheduling). Justified in the const doc + commit.
3. **Exactly-once preserved.** The QUIC call is made *inside* the `apply_once` closure (`host.dial(...)?` etc.), so a timeout → closure `Err` → `effect()?` propagates **before** `applied.insert` → no phantom `conn_id`/`stream_id` recorded → a fresh tick re-dials cleanly (no dedupe into a dead conn).
4. **Happy path unchanged.** A live op completes with zero added latency; the bound only bites a non-responsive peer.

### Timeout-value rationale
10s. Legit round-trips are sub-second (loopback/LAN) to a few seconds (cold relay) — 10s never bites a live peer. The brain's deadline is 30s; a 20s margin guarantees the **broker** replies its ordinary error before the **brain** hits its own read-deadline `TimedOut`, which is what keeps the failure on `peer_outcome`'s per-peer arm and off the supervised-restart path. Test-overridable via `set_quic_op_timeout` (off `NetConfig`, mirrors `set_roster_exchange`).

### Exactly-once-on-timeout proof
`tests/netbroker.rs::dial_to_a_black_holing_peer_fails_with_a_bounded_ordinary_error` dials a membership-mismatch black-hole peer with a journaled op (`Some(OP)`); on the bounded timeout it asserts: `!journal().is_applied((NET_EFFECT_SESSION, OP))`, `journal().applied_count() == 0`, `conn_count == 0` (no phantom), the broker still serves, and re-driving the SAME op re-attempts (no phantom dedup). Mechanism: `effect.rs::apply_once` runs `effect()?` before `applied.insert`, so a closure-`Err` leaves the key un-applied (existing `failed_effect_is_not_recorded_applied` covers the journal semantics).

### Evidence
- **impl** (`nethost.rs`): `bounded_block_on` wraps `dial` / `open_stream` (QUIC branch) / `send_stream`; `BROKER_QUIC_OP_TIMEOUT_MS` + `set_quic_op_timeout`.
- **unit** (`nethost.rs`): `bounded_block_on_cuts_a_never_completing_op_with_an_ordinary_error` — a never-completing op → prompt non-`TimedOut` error; a ready op untouched.
- **int** (`tests/netbroker.rs`): the black-holing peer → ordinary error within the bound + exactly-once-on-timeout (above).
- **int** (`tests/pump.rs`): `pump_survives_a_black_holing_peer_heartbeat_advances_no_restart` — the production pump against a dead roster peer: heartbeat **monotonic-advances** + `run_peer_pump` exits **Ok** (no `PEER_PUMP_RESTART`). Pre-fix the dial freezes ≥30s; the 20s observation window catches it.
- **doc**: `KNOWN-HAZARDS` §7.8 (new) + §7.6 B-half-fixed reword + conformance row; `DEFERRED.md:42` RESOLVED; `CHANGELOG [Unreleased]`.

### Gate bar (preflighted locally)
- `cargo clippy --workspace --all-targets -- -D warnings` — **clean**.
- `traceable-reqs check` — **EXIT 0** (`REQ-HAZARD-BROKER-QUIC-DEADLINE` `[doc,impl,unit,int]` all evidenced).
- **Shared-seam sweep** (broker net seam): `netbroker` 6 · `pump` 2 · `mesh` 2 · `replicate` 1 · `wanmsg` 3 · `attach` 12 · `daemon_e2e`/`daemon_lifecycle_real_brain` 1 · spt-daemon `--lib` 314 — **all green**.
- `xtask gen` + `xtask check` — **OK** (no CLI change; the only `gen` delta was CRLF line-endings, reverted).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
gh pr create --base main --head v0.8.3-broker-quic-deadline --title "v0.8.3: broker-side QUIC-op bound (pump-IPC-deadline B-half)" --body-file /tmp/pr-body.md 2>&1 | tail -5

Create PR base main


PR #19 up. Ping doyle PR-ready with the requested evidence.


$OWL send doyle <<'EOF'
v0.8.3 broker-QUIC-deadline PR-READY — PR #19 (base main). Self-driven end-to-end; gate bar all green locally. Your three asks:

== TIMEOUT-VALUE RATIONALE ==
10s (BROKER_QUIC_OP_TIMEOUT_MS). Legit connect+seed-proof round-trips: sub-second loopback/LAN, a few seconds cold relay → 10s never bites a live peer. 20s BELOW the brain's 30s PUMP_PEER_IO_TIMEOUT so the BROKER replies its ordinary error FIRST (margin covers error-frame IPC transit + brain read scheduling) → failure stays on peer_outcome's per-peer arm, off the supervised-restart path. Test-overridable via set_quic_op_timeout (off NetConfig, mirrors set_roster_exchange).

== EXACTLY-ONCE-ON-TIMEOUT PROOF ==
The QUIC call is INSIDE the apply_once closure, so timeout→closure Err→effect()? propagates BEFORE applied.insert → no phantom conn/stream id. netbroker int dials a black-hole peer with Some(OP), asserts post-timeout: !is_applied((NET_EFFECT_SESSION,OP)), applied_count()==0, conn_count==0, broker still serves, re-drive same OP re-attempts (no phantom dedup). (effect.rs failed_effect_is_not_recorded_applied covers the journal semantics.)

== INT EVIDENCE ==
- tests/netbroker.rs::dial_to_a_black_holing_peer_fails_with_a_bounded_ordinary_error: membership-mismatch black hole → broker REPLIES ordinary error within bound (not wedge) + the exactly-once proof above. ~1.7s.
- tests/pump.rs::pump_survives_a_black_holing_peer_heartbeat_advances_no_restart: production pump vs dead roster peer → heartbeat MONOTONIC-ADVANCES + run_peer_pump exits Ok (no PEER_PUMP_RESTART). Pre-fix dial freezes >=30s; 20s window catches it. ~5.8s.
- unit nethost: bounded_block_on → prompt non-TimedOut err on never-completing op; ready op untouched.

== GATE BAR ==
clippy --workspace --all-targets -D warnings CLEAN · traceable EXIT 0 ([doc,impl,unit,int] all evidenced) · SEAM SWEEP green (netbroker6/pump2/mesh2/replicate1/wanmsg3/attach12/daemon_lifecycle_real_brain1 + 314 lib) · docs-drift OK (no CLI change; only CRLF delta, reverted).

3 commits: mint(69af744) → impl+unit+int(cece4a6) → docs(f4dc053). KNOWN-HAZARDS 7.8 + 7.6 reword + DEFERRED:42 RESOLVED + CHANGELOG [Unreleased]. CARGO.LOCK bump = deployah's at release. Over to you to gate.
EOF

Ping doyle PR-ready


Command running in background with ID: bz6rwaw49. Output is being written to: C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\bz6rwaw49.output. You will be notified when it completes. To check interim output, use Read on that file path.


<task-notification>
<task-id>bz6rwaw49</task-id>
<tool-use-id>toolu_01K4uVS7qtNdxK3awwfwxjpG</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\bz6rwaw49.output</output-file>
<status>completed</status>
<summary>Background command "Ping doyle PR-ready" completed (exit code 0)</summary>
</task-notification>


While that sends, record the v0.8.3 work in memory.


Write

---
name: v083-broker-quic-deadline
description: v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate
metadata:
  type: project
---

v0.8.3 (PATCH 0.8.2→0.8.3) = the deferred **B-half** of REQ-HAZARD-PUMP-IPC-DEADLINE ([[peer-pump-stall-bhalf-confirmed]], DEFERRED.md:42). doyle DISPATCH 2026-06-16 (I own end-to-end exec, doyle gates, deployah releases). Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19, base main, PR-READY — pinged doyle with rationale+proof, awaiting gate.**

Minted **REQ-HAZARD-BROKER-QUIC-DEADLINE**. Root cause: a DEAD roster peer → broker's brain-facing QUIC op (dial/open_stream/send_stream) awaits unbounded; A-half bounds only the brain READ → 30s stall + pump restart re-dials same dead peer + re-wedges. Recurred hfenduleam 2026-06-16.

FIX: `NetHost::bounded_block_on` wraps the 3 QUIC await sites in `tokio::time::timeout` under `quic_op_timeout` (default `BROKER_QUIC_OP_TIMEOUT_MS`=10s; test-override `set_quic_op_timeout`, off NetConfig like set_roster_exchange). On elapse → future DROPPED (cancels op, nothing half-registered) → non-TimedOut io::Error → broker REPLIES ordinary error frame.

4 invariants: (1) ordinary err not TimedOut — brain maps BrokerEvent::Error→io::Error::other=ErrorKind::Other → peer_outcome per-peer arm, NOT brain's own recv-deadline TimedOut (A-half poison path). (2) 10s < brain's 30s PUMP_PEER_IO_TIMEOUT so broker fires first (20s margin). (3) exactly-once: QUIC call is INSIDE apply_once closure → timeout→closure Err→effect()? before applied.insert → no phantom conn/stream id. (4) happy path zero added latency.

Tests: unit nethost (never-completing→prompt non-TimedOut err; ready untouched); int netbroker (membership-mismatch black hole: A=membership Some, B=None → A's prove_membership hangs → broker ordinary err in bound + exactly-once-on-timeout: !is_applied, applied_count 0, conn_count 0, redial clean); int pump (production pump vs dead peer → heartbeat monotonic-advances + run_peer_pump exits Ok, no PEER_PUMP_RESTART; pre-fix freezes ≥30s, 20s window catches). Membership-mismatch = the documented native black hole (nethost docs "both peers must agree or the side expecting the control stream would hang").

3 commits: mint 69af744 → impl+unit+int cece4a6 → docs f4dc053. Docs: KNOWN-HAZARDS 7.8 NEW + 7.6 B-half-fixed reword + conformance row, DEFERRED:42 RESOLVED, CHANGELOG [Unreleased]. Gate bar preflighted: clippy --workspace -D warnings clean · traceable EXIT 0 [doc,impl,unit,int] · seam-sweep green (netbroker/pump/mesh/replicate/wanmsg/attach/daemon_lifecycle_real_brain + 314 lib) · docs-drift OK (CRLF-only). CARGO.LOCK bump = deployah's at release.


<tool_use_error>File has not been read yet. Read it first before writing to it.</tool_use_error>


Prompt:
<task-notification>
<task-id>bz6rwaw49</task-id>
<tool-use-id>toolu_01K4uVS7qtNdxK3awwfwxjpG</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\bz6rwaw49.output</output-file>
<status>completed</status>
<summary>Background command "Ping doyle PR-ready" completed (exit code 0)</summary>
</task-notification>


Ping delivered to doyle (exit 0). The memory file Write wants a prior Read — check if it exists:


Bash

Check if memory file exists


-rw-r--r-- 1 decid 197609 3009 Jun 16 20:40 C:/Users/decid/.ccs/instances/bigscreen/projects/C--Users-decid-Documents-projects-spt-core/memory/v083-broker-quic-deadline.md


1	---
2	name: v083-broker-quic-deadline
3	description: "v0.8.3 = broker-side QUIC-op bound (deferred pump-IPC B-half). doyle design+gate, todlando exec, deployah release (counter 19, PATCH). Branch v0.8.3-broker-quic-deadline. Fixes live HFENDULEAM pump-stall (dead peer wedges pump unbounded)."
4	metadata:
5	  node_type: memory

---
name: v083-broker-quic-deadline
description: "v0.8.3 = broker-side QUIC-op bound (deferred pump-IPC B-half). doyle design+gate, todlando exec, deployah release (counter 19, PATCH). Branch v0.8.3-broker-quic-deadline. Fixes live HFENDULEAM pump-stall (dead peer wedges pump unbounded)."
metadata:
  node_type: memory


The file was auto-seeded earlier. Overwrite with the full record:


Write

---
name: v083-broker-quic-deadline
description: v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate
metadata:
  type: project
---

v0.8.3 (PATCH 0.8.2→0.8.3) = the deferred **B-half** of REQ-HAZARD-PUMP-IPC-DEADLINE ([[peer-pump-stall-bhalf-confirmed]], DEFERRED.md:42). doyle DISPATCH 2026-06-16 (I own end-to-end exec, doyle gates, deployah releases). Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19, base main, PR-READY — pinged doyle with rationale+proof, awaiting gate.**

Minted **REQ-HAZARD-BROKER-QUIC-DEADLINE**. Root cause: a DEAD roster peer → broker's brain-facing QUIC op (dial/open_stream/send_stream) awaits unbounded; A-half bounds only the brain READ → 30s stall + pump restart re-dials same dead peer + re-wedges. Recurred hfenduleam 2026-06-16.

FIX: `NetHost::bounded_block_on` wraps the 3 QUIC await sites in `tokio::time::timeout` under `quic_op_timeout` (default `BROKER_QUIC_OP_TIMEOUT_MS`=10s; test-override `set_quic_op_timeout`, off NetConfig like set_roster_exchange). On elapse → future DROPPED (cancels op, nothing half-registered) → non-TimedOut io::Error → broker REPLIES ordinary error frame.

4 invariants: (1) ordinary err not TimedOut — brain maps BrokerEvent::Error→io::Error::other=ErrorKind::Other → peer_outcome per-peer arm, NOT brain's own recv-deadline TimedOut (A-half poison path). (2) 10s < brain's 30s PUMP_PEER_IO_TIMEOUT so broker fires first (20s margin). (3) exactly-once: QUIC call is INSIDE apply_once closure → timeout→closure Err→effect()? before applied.insert → no phantom conn/stream id. (4) happy path zero added latency.

Tests: unit nethost (never-completing→prompt non-TimedOut err; ready untouched); int netbroker (membership-mismatch black hole: A=membership Some, B=None → A's prove_membership hangs → broker ordinary err in bound + exactly-once-on-timeout: !is_applied, applied_count 0, conn_count 0, redial clean); int pump (production pump vs dead peer → heartbeat monotonic-advances + run_peer_pump exits Ok, no PEER_PUMP_RESTART; pre-fix freezes ≥30s, 20s window catches). Membership-mismatch = the documented native black hole (nethost docs: "both peers must agree or the side expecting the control stream would hang").

3 commits: mint 69af744 → impl+unit+int cece4a6 → docs f4dc053. Docs: KNOWN-HAZARDS 7.8 NEW + 7.6 B-half-fixed reword + conformance row, DEFERRED:42 RESOLVED, CHANGELOG [Unreleased]. Gate bar preflighted: clippy --workspace -D warnings clean · traceable EXIT 0 [doc,impl,unit,int] · seam-sweep green (netbroker/pump/mesh/replicate/wanmsg/attach/daemon_lifecycle_real_brain + 314 lib) · docs-drift OK (CRLF-only). CARGO.LOCK bump = deployah's at release.


The file C:\Users\decid\.ccs\instances\bigscreen\projects\C--Users-decid-Documents-projects-spt-core\memory\v083-broker-quic-deadline.md has been updated successfully. (file state is current in your context — no need to Read it back)

---
name: v083-broker-quic-deadline
description: "v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate"
metadata:
  node_type: memory
  type: project
  originSessionId: 1e7c582d-c03a-4db0-bd84-c7b3b7959ea0
---

v0.8.3 (PATCH 0.8.2→0.8.3) = the deferred **B-half** of REQ-HAZARD-PUMP-IPC-DEADLINE ([[peer-pump-stall-bhalf-confirmed]], DEFERRED.md:42). doyle DISPATCH 2026-06-16 (I own end-to-end exec, doyle gates, deployah releases). Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19, base main, PR-READY — pinged doyle with rationale+proof, awaiting gate.**

Minted **REQ-HAZARD-BROKER-QUIC-DEADLINE**. Root cause: a DEAD roster peer → broker's brain-facing QUIC op (dial/open_stream/send_stream) awaits unbounded; A-half bounds only the brain READ → 30s stall + pump restart re-dials same dead peer + re-wedges. Recurred hfenduleam 2026-06-16.

FIX: `NetHost::bounded_block_on` wraps the 3 QUIC await sites in `tokio::time::timeout` under `quic_op_timeout` (default `BROKER_QUIC_OP_TIMEOUT_MS`=10s; test-override `set_quic_op_timeout`, off NetConfig like set_roster_exchange). On elapse → future DROPPED (cancels op, nothing half-registered) → non-TimedOut io::Error → broker REPLIES ordinary error frame.

4 invariants: (1) ordinary err not TimedOut — brain maps BrokerEvent::Error→io::Error::other=ErrorKind::Other → peer_outcome per-peer arm, NOT brain's own recv-deadline TimedOut (A-half poison path). (2) 10s < brain's 30s PUMP_PEER_IO_TIMEOUT so broker fires first (20s margin). (3) exactly-once: QUIC call is INSIDE apply_once closure → timeout→closure Err→effect()? before applied.insert → no phantom conn/stream id. (4) happy path zero added latency.

Tests: unit nethost (never-completing→prompt non-TimedOut err; ready untouched); int netbroker (membership-mismatch black hole: A=membership Some, B=None → A's prove_membership hangs → broker ordinary err in bound + exactly-once-on-timeout: !is_applied, applied_count 0, conn_count 0, redial clean); int pump (production pump vs dead peer → heartbeat monotonic-advances + run_peer_pump exits Ok, no PEER_PUMP_RESTART; pre-fix freezes ≥30s, 20s window catches). Membership-mismatch = the documented native black hole (nethost docs: "both peers must agree or the side expecting the control stream would hang").

3 commits: mint 69af744 → impl+unit+int cece4a6 → docs f4dc053. Docs: KNOWN-HAZARDS 7.8 NEW + 7.6 B-half-fixed reword + conformance row, DEFERRED:42 RESOLVED, CHANGELOG [Unreleased]. Gate bar preflighted: clippy --workspace -D warnings clean · traceable EXIT 0 [doc,impl,unit,int] · seam-sweep green (netbroker/pump/mesh/replicate/wanmsg/attach/daemon_lifecycle_real_brain + 314 lib) · docs-drift OK (CRLF-only). CARGO.LOCK bump = deployah's at release.

-description: "v0.8.3 = broker-side QUIC-op bound (deferred pump-IPC B-half). doyle design+gate, todlando exec, deployah release (counter 19, PATCH). Branch v0.8.3-broker-quic-deadline. Fixes live HFENDULEAM pump-stall (dead peer wedges pump unbounded)."

+description: "v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate"

-  originSessionId: 9d0930b3-34c1-4dce-943f-72ccdc8fb726

+  originSessionId: 1e7c582d-c03a-4db0-bd84-c7b3b7959ea0

-**v0.8.3 — broker-side QUIC-op bound (the deferred pump-IPC B-half).** Operator-directed 2026-06-16 immediate fix after the live HFENDULEAM pump-stall diagnosis ([[peer-pump-stall-bhalf-confirmed]]). Roles: doyle design ruling + gate, todlando executes end-to-end, deployah signs+releases (counter 19, PATCH 0.8.2→0.8.3). Branch v0.8.3-broker-quic-deadline off main.

+v0.8.3 (PATCH 0.8.2→0.8.3) = the deferred **B-half** of REQ-HAZARD-PUMP-IPC-DEADLINE ([[peer-pump-stall-bhalf-confirmed]], DEFERRED.md:42). doyle DISPATCH 2026-06-16 (I own end-to-end exec, doyle gates, deployah releases). Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19, base main, PR-READY — pinged doyle with rationale+proof, awaiting gate.**

-**REQ:** REQ-HAZARD-BROKER-QUIC-DEADLINE (sibling of REQ-HAZARD-PUMP-IPC-DEADLINE), registry-first mint, activate [doc,impl,unit,int] per-wave.

+Minted **REQ-HAZARD-BROKER-QUIC-DEADLINE**. Root cause: a DEAD roster peer → broker's brain-facing QUIC op (dial/open_stream/send_stream) awaits unbounded; A-half bounds only the brain READ → 30s stall + pump restart re-dials same dead peer + re-wedges. Recurred hfenduleam 2026-06-16.

-**Fix:** bound the broker-side iroh QUIC awaits — nethost.rs dial/open_stream/send_stream (via broker.rs dispatch_net_dial:1114 / dispatch_net_stream_open:1245 / dispatch_net_stream_send:1293) — so a dead/black-holed peer fails promptly instead of awaiting forever.

+FIX: `NetHost::bounded_block_on` wraps the 3 QUIC await sites in `tokio::time::timeout` under `quic_op_timeout` (default `BROKER_QUIC_OP_TIMEOUT_MS`=10s; test-override `set_quic_op_timeout`, off NetConfig like set_roster_exchange). On elapse → future DROPPED (cancels op, nothing half-registered) → non-TimedOut io::Error → broker REPLIES ordinary error frame.

-**FOUR GATE INVARIANTS (the design ruling I gate on):** (1) timeout surfaces as an ORDINARY broker error reply (non-TimedOut) → pump::peer_outcome non-TimedOut arm → drop-conn+redial, round CONTINUES, heartbeat advances — must NOT be the brain's own read-deadline (that's the A-half poison→supervised-restart this fix exists to avoid). (2) bound < 30s brain PUMP_PEER_IO_TIMEOUT so broker fires FIRST (~10s steer). (3) exactly-once preserved: a timed-out journaled dial/open is NOT-applied (no phantom conn/stream recorded → fresh tick re-dials, no dedupe into dead conn) — fail the apply_once closure. (4) happy path zero added latency.

+4 invariants: (1) ordinary err not TimedOut — brain maps BrokerEvent::Error→io::Error::other=ErrorKind::Other → peer_outcome per-peer arm, NOT brain's own recv-deadline TimedOut (A-half poison path). (2) 10s < brain's 30s PUMP_PEER_IO_TIMEOUT so broker fires first (20s margin). (3) exactly-once: QUIC call is INSIDE apply_once closure → timeout→closure Err→effect()? before applied.insert → no phantom conn/stream id. (4) happy path zero added latency.

-**Tests:** unit (timeout wrapper prompt non-TimedOut on never-completing op); int = THE regression (unreachable/black-hole peer → broker handler errors within bound → pump gets ordinary Err → conn dropped, round continues, heartbeat monotonic-advances, NO PEER_PUMP_RESTART). Extend tests/netbroker.rs + tests/pump.rs (loopback QUIC infra there).

+Tests: unit nethost (never-completing→prompt non-TimedOut err; ready untouched); int netbroker (membership-mismatch black hole: A=membership Some, B=None → A's prove_membership hangs → broker ordinary err in bound + exactly-once-on-timeout: !is_applied, applied_count 0, conn_count 0, redial clean); int pump (production pump vs dead peer → heartbeat monotonic-advances + run_peer_pump exits Ok, no PEER_PUMP_RESTART; pre-fix freezes ≥30s, 20s window catches). Membership-mismatch = the documented native black hole (nethost docs: "both peers must agree or the side expecting the control stream would hang").

-**Docs:** KNOWN-HAZARDS 7.6 "B-half deferred"→fixed + new 7.8 subsection; DEFERRED.md:42 strike→RESOLVED v0.8.3; CHANGELOG version-framed bullet.

-**Gate bar to todlando:** clippy --workspace --all-targets -D warnings · traceable EXIT0 · SHARED-SEAM SWEEP ([[shared-seam-change-run-all-seam-tests]] — broker net seam: run netbroker/pump/mesh/replicate/wanmsg/daemon_lifecycle_real_brain/attach, not just the new int) · xtask gen+check. Then PR base main, ping doyle PR-ready w/ int evidence + timeout-value rationale + exactly-once-on-timeout proof.

-**STATUS: dispatched to todlando + deployah on-call notified (2026-06-16). Awaiting todlando PR-ready ping → doyle gate → deployah release.** Resident-broker deploy caveat: reaches fleet only on next daemon restart/update (new binary carries the bound).

+3 commits: mint 69af744 → impl+unit+int cece4a6 → docs f4dc053. Docs: KNOWN-HAZARDS 7.8 NEW + 7.6 B-half-fixed reword + conformance row, DEFERRED:42 RESOLVED, CHANGELOG [Unreleased]. Gate bar preflighted: clippy --workspace -D warnings clean · traceable EXIT 0 [doc,impl,unit,int] · seam-sweep green (netbroker/pump/mesh/replicate/wanmsg/attach/daemon_lifecycle_real_brain + 314 lib) · docs-drift OK (CRLF-only). CARGO.LOCK bump = deployah's at release.

---
name: v083-broker-quic-deadline
description: "v0.8.3 = broker-side QUIC-op bound (deferred pump-IPC B-half). doyle design+gate, todlando exec, deployah release (counter 19, PATCH). Branch v0.8.3-broker-quic-deadline. Fixes live HFENDULEAM pump-stall (dead peer wedges pump unbounded)."
metadata:
  node_type: memory
  type: project
  originSessionId: 9d0930b3-34c1-4dce-943f-72ccdc8fb726
---

**v0.8.3 — broker-side QUIC-op bound (the deferred pump-IPC B-half).** Operator-directed 2026-06-16 immediate fix after the live HFENDULEAM pump-stall diagnosis ([[peer-pump-stall-bhalf-confirmed]]). Roles: doyle design ruling + gate, todlando executes end-to-end, deployah signs+releases (counter 19, PATCH 0.8.2→0.8.3). Branch v0.8.3-broker-quic-deadline off main.

**REQ:** REQ-HAZARD-BROKER-QUIC-DEADLINE (sibling of REQ-HAZARD-PUMP-IPC-DEADLINE), registry-first mint, activate [doc,impl,unit,int] per-wave.

**Fix:** bound the broker-side iroh QUIC awaits — nethost.rs dial/open_stream/send_stream (via broker.rs dispatch_net_dial:1114 / dispatch_net_stream_open:1245 / dispatch_net_stream_send:1293) — so a dead/black-holed peer fails promptly instead of awaiting forever.

**FOUR GATE INVARIANTS (the design ruling I gate on):** (1) timeout surfaces as an ORDINARY broker error reply (non-TimedOut) → pump::peer_outcome non-TimedOut arm → drop-conn+redial, round CONTINUES, heartbeat advances — must NOT be the brain's own read-deadline (that's the A-half poison→supervised-restart this fix exists to avoid). (2) bound < 30s brain PUMP_PEER_IO_TIMEOUT so broker fires FIRST (~10s steer). (3) exactly-once preserved: a timed-out journaled dial/open is NOT-applied (no phantom conn/stream recorded → fresh tick re-dials, no dedupe into dead conn) — fail the apply_once closure. (4) happy path zero added latency.

**Tests:** unit (timeout wrapper prompt non-TimedOut on never-completing op); int = THE regression (unreachable/black-hole peer → broker handler errors within bound → pump gets ordinary Err → conn dropped, round continues, heartbeat monotonic-advances, NO PEER_PUMP_RESTART). Extend tests/netbroker.rs + tests/pump.rs (loopback QUIC infra there).

**Docs:** KNOWN-HAZARDS 7.6 "B-half deferred"→fixed + new 7.8 subsection; DEFERRED.md:42 strike→RESOLVED v0.8.3; CHANGELOG version-framed bullet.

**Gate bar to todlando:** clippy --workspace --all-targets -D warnings · traceable EXIT0 · SHARED-SEAM SWEEP ([[shared-seam-change-run-all-seam-tests]] — broker net seam: run netbroker/pump/mesh/replicate/wanmsg/daemon_lifecycle_real_brain/attach, not just the new int) · xtask gen+check. Then PR base main, ping doyle PR-ready w/ int evidence + timeout-value rationale + exactly-once-on-timeout proof.

**STATUS: dispatched to todlando + deployah on-call notified (2026-06-16). Awaiting todlando PR-ready ping → doyle gate → deployah release.** Resident-broker deploy caveat: reaches fleet only on next daemon restart/update (new binary carries the bound).


Update the MEMORY.md index pointer (check for an auto-seeded line first):


Bash

Check MEMORY.md for v083 index line


3:- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — orchestrating the B-half fix (counter 19, PATCH): doyle design+gate, todlando exec, deployah release. Branch v0.8.3-broker-quic-deadline. REQ-HAZARD-BROKER-QUIC-DEADLINE. Bound nethost dial/open_stream/send_stream so a dead peer errors ORDINARY (non-TimedOut, <30s) → pump redials not wedges; exactly-once preserved on timeout. Dispatched, awaiting todlando PR-ready


Edit

- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — orchestrating the B-half fix (counter 19, PATCH): doyle design+gate, todlando exec, deployah release. Branch v0.8.3-broker-quic-deadline. REQ-HAZARD-BROKER-QUIC-DEADLINE. Bound nethost dial/open_stream/send_stream so a dead peer errors ORDINARY (non-TimedOut, <30s) → pump redials not wedges; exactly-once preserved on timeout. Dispatched, awaiting todlando PR-ready

- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — pump-IPC B-half (PATCH): REQ-HAZARD-BROKER-QUIC-DEADLINE. NetHost::bounded_block_on (tokio timeout, 10s default <30s brain) wraps dial/open_stream/send_stream → dead peer errors ORDINARY (non-TimedOut) INSIDE apply_once (no phantom) → pump redials not wedges. **PR #19 base main PR-READY**: 3 commits, gate-bar green (clippy/traceable EXIT0/seam-sweep/docs-drift), pinged doyle, AWAITING GATE. deployah does CARGO.LOCK+bump at release


<tool_use_error>File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.</tool_use_error>

Error: File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.


3	- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — orchestrating the B-half fix (counter 19, PATCH): doyle design+gate, todlando exec, deployah release. Branch v0.8.3-broker-quic-deadline. REQ-HAZARD-BROKER-QUIC-DEADLINE. Bound nethost dial/open_stream/send_stream so a dead peer errors ORDINARY (non-TimedOut, <30s) → pump redials not wedges; exactly-once preserved on timeout. Dispatched, awaiting todlando PR-ready


- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — orchestrating the B-half fix (counter 19, PATCH): doyle design+gate, todlando exec, deployah release. Branch v0.8.3-broker-quic-deadline. REQ-HAZARD-BROKER-QUIC-DEADLINE. Bound nethost dial/open_stream/send_stream so a dead peer errors ORDINARY (non-TimedOut, <30s) → pump redials not wedges; exactly-once preserved on timeout. Dispatched, awaiting todlando PR-ready

- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — pump-IPC B-half (PATCH): REQ-HAZARD-BROKER-QUIC-DEADLINE. NetHost::bounded_block_on (tokio timeout 10s<30s brain) wraps dial/open_stream/send_stream → dead peer errors ORDINARY (non-TimedOut) INSIDE apply_once (no phantom) → pump redials not wedges. **PR #19 base main PR-READY**: 3 commits, gate-bar green (clippy/traceable EXIT0/seam-sweep/docs-drift), pinged doyle, AWAITING GATE. deployah CARGO.LOCK+bump at release


The file C:\Users\decid\.ccs\instances\bigscreen\projects\C--Users-decid-Documents-projects-spt-core\memory\MEMORY.md has been updated successfully. (file state is current in your context — no need to Read it back)

- [pre-flight clippy --workspace](ci-clippy-preflight-workspace.md) — CI denies warnings workspace-wide (`clippy --workspace --all-targets -D warnings`); a `-p <crate>` local check misses sibling-crate lints → CI red round-trip (M11-W1: `-p spt` missed a `useless_vec` in spt-daemon's act-gate test). Pre-flight the exact CI invocation. CI only fires on PR (push branches=main/dev-freeform)

- [shared-seam change → run ALL seam tests](shared-seam-change-run-all-seam-tests.md) — a behavior change to a SHARED runtime seam can break SIBLING tests exercising it; targeted preflight on only the new tests misses them (CI's full suite catches it). v0.8.2 F-010 residency broke daemon_lifecycle_real_brain (NOOP fast-exit psyche) — ran the livehost E2Es but not that spt-daemon sibling. Grep+run ALL seam tests (run_brain/spawn_live_host/psyche_init/daemon run). Test-analog of [[ci-clippy-preflight-workspace]]

-- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — orchestrating the B-half fix (counter 19, PATCH): doyle design+gate, todlando exec, deployah release. Branch v0.8.3-broker-quic-deadline. REQ-HAZARD-BROKER-QUIC-DEADLINE. Bound nethost dial/open_stream/send_stream so a dead peer errors ORDINARY (non-TimedOut, <30s) → pump redials not wedges; exactly-once preserved on timeout. Dispatched, awaiting todlando PR-ready

+- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — pump-IPC B-half (PATCH): REQ-HAZARD-BROKER-QUIC-DEADLINE. NetHost::bounded_block_on (tokio timeout 10s<30s brain) wraps dial/open_stream/send_stream → dead peer errors ORDINARY (non-TimedOut) INSIDE apply_once (no phantom) → pump redials not wedges. **PR #19 base main PR-READY**: 3 commits, gate-bar green (clippy/traceable EXIT0/seam-sweep/docs-drift), pinged doyle, AWAITING GATE. deployah CARGO.LOCK+bump at release

- [peer-pump stall = deferred B-half](peer-pump-stall-bhalf-confirmed.md) — HFENDULEAM v0.8.2 pump STALLED (~93min frozen heartbeat, brain gen0 never restarted) CONFIRMED = DEFERRED.md:42 broker-side unbounded QUIC op to a DEAD roster peer (ENLYZEAM ~26h stale), A-half bounds only brain reads not broker await; KH 7.6 Win reader-park. NOT new bug. Interim=restart spt-core daemon (safe vs legacy-owl perches); real fix=mint REQ broker-side QUIC bound (broker-update batch)

- [v0.8.2 templating+residency](v082-templating-residency.md) — doyle delegation (I own waves+exec, gates→counter 18, NON-blocking perri-dogfood quality). F-009 TEMPLATE-ARGV-FILL: tokenize template FIRST then fill each token (1 value=1 argv elem, no split/injection); preserve errors+{{/}}+install-dir resolve. F-010 LIVEHOST-NONRESIDENT: host_one residency-confirm (child dead within N s → stamp parent psyche_host_error, no phantom online perch). Linked: F-009 split→F-010 early-exit. Branch v0.8.2-templating-residency @3cd5e6f. FLAKE-LEDGER rider folds here

- [v0.8.1 livehost boot-race](v081-livehost-bootrace.md) — doyle delegation (I own waves+exec, doyle gates→counter 17): net-less node, live agent goes online but daemon never hosts Psyche (no LIVEHOST_PSYCHE). VERIFIED: spawn_live_host @brainproc:230 IS reached net-less (broker-connect is local) → H1 refuted. Explore report's "registry race" theory SHAKY (same-slice inconsistency). True failure runtime-only → W1 = real-detached-daemon E2E (non-negotiable gate) reproduces it. Likely REQ-INSTALL-11 psyche-binary-not-found. Branch v0.8.1-livehost-bootrace @2aab895


Memory recorded. Now verify the PR is mergeable and CI kicked off (per the unmergeable-PR-blocks-CI lesson — I branched off current main HEAD so it should be clean):


Bash

echo "commits behind main: $(git rev-list --count HEAD..origin/main)"; gh pr view 19 --json mergeable,mergeStateStatus -q '"mergeable=\(.mergeable) state=\(.mergeStateStatus)"' 2>&1; echo "=== checks ==="; sleep 8; gh pr checks 19 2>&1 | head -20

Check PR mergeability + CI checks


commits behind main: 0
mergeable=MERGEABLE state=UNSTABLE
=== checks ===
test (self-hosted, Windows, hfenduleam)	pending	0	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148139
n1-gate (self-hosted, Linux, kitsubito)	pass	1m13s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148123
n1-gate (self-hosted, Windows, hfenduleam)	pass	1m39s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148060
test (self-hosted, Linux, kitsubito)	pending	0	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148074
traceability	pending	0	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148087


PR #19 **MERGEABLE** (0 behind main), CI running normally — n1-gate already green both runners; test + traceability pending. Watch CI to completion in the background (single notification when done):


gh pr checks 19 --watch --interval 30 2>&1 | tail -12; echo "=== final exit: $? (0=all pass) ==="

Watch PR #19 CI to completion


Command running in background with ID: bxezqk8o3. Output is being written to: C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\bxezqk8o3.output. You will be notified when it completes. To check interim output, use Read on that file path.


v0.8.3 built end-to-end and submitted. Standing by for CI + doyle gate.

**v0.8.3 — broker-side QUIC-op bound (pump-IPC-deadline B-half)** — PR #19, base main, PR-READY.

Root cause cured: dead roster peer → broker's QUIC await unbounded → pump wedge (the 2.2h hfenduleam wedge, recurred 2026-06-16). Fix bounds the broker so a dead peer fails as an **ordinary** error the broker replies, not the brain's TimedOut → pump redials, never wedges/restarts.

What shipped:
- **3 commits**: mint `69af744` → impl+unit+int `cece4a6` → docs `f4dc053`
- **impl**: `NetHost::bounded_block_on` (tokio timeout, 10s default < brain's 30s) wraps `dial`/`open_stream`/`send_stream`; timeout fires *inside* `apply_once` → no phantom conn/stream id
- **tests**: unit (wrapper) + int netbroker (black-hole → ordinary err in bound + exactly-once-on-timeout) + int pump (heartbeat advances, no `PEER_PUMP_RESTART`)
- **docs**: KNOWN-HAZARDS 7.8 new + 7.6 reworded fixed + DEFERRED:42 RESOLVED + CHANGELOG

Gate bar all green locally: clippy `--workspace -D warnings` clean · traceable EXIT 0 `[doc,impl,unit,int]` · seam-sweep green (netbroker/pump/mesh/replicate/wanmsg/attach/daemon_lifecycle_real_brain + 314 lib) · docs-drift OK.

CI: MERGEABLE, n1-gate green both runners; test+traceability pending (watching). Pinged doyle with rationale + exactly-once proof. **doyle gates → deployah releases (counter 19). CARGO.LOCK+bump = deployah's at release.** Perch live.


<task-notification>
<task-id>bxezqk8o3</task-id>
<tool-use-id>toolu_01Cu65Xy9doYsSubX7g7gRwV</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\bxezqk8o3.output</output-file>
<status>completed</status>
<summary>Background command "Watch PR #19 CI to completion" completed (exit code 0)</summary>
</task-notification>


<owl_reachability_notice>
You have an active owl perch. When spawning subagents or doing work, use run_in_background: true so you stay reachable for incoming messages.
</owl_reachability_notice>


CAVEMAN MODE ACTIVE (full). Drop articles/filler/pleasantries/hedging. Fragments OK. Code/commits/security: write normal.


CI watch exited 0 — all checks pass. Confirm:


1	n1-gate (self-hosted, Linux, kitsubito)	pass	1m13s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148123
2	n1-gate (self-hosted, Windows, hfenduleam)	pass	1m39s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148060
3	test (self-hosted, Linux, kitsubito)	pass	5m10s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148074
4	test (self-hosted, Windows, hfenduleam)	pass	6m4s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148139
5	traceability	pass	8s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148087
6	twohost-a	skipping	0	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817936935
7	twohost-b	skipping	0	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817937006
8	n1-gate (self-hosted, Linux, kitsubito)	pass	1m13s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148123
9	n1-gate (self-hosted, Windows, hfenduleam)	pass	1m39s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148060
10	test (self-hosted, Linux, kitsubito)	pass	5m10s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148074
11	test (self-hosted, Windows, hfenduleam)	pass	6m4s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148139
12	traceability	pass	8s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148087
13	=== final exit: 0 (0=all pass) ===
14

n1-gate (self-hosted, Linux, kitsubito)	pass	1m13s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148123
n1-gate (self-hosted, Windows, hfenduleam)	pass	1m39s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148060
test (self-hosted, Linux, kitsubito)	pass	5m10s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148074
test (self-hosted, Windows, hfenduleam)	pass	6m4s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148139
traceability	pass	8s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148087
twohost-a	skipping	0	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817936935
twohost-b	skipping	0	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817937006
n1-gate (self-hosted, Linux, kitsubito)	pass	1m13s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148123
n1-gate (self-hosted, Windows, hfenduleam)	pass	1m39s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148060
test (self-hosted, Linux, kitsubito)	pass	5m10s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148074
test (self-hosted, Windows, hfenduleam)	pass	6m4s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148139
traceability	pass	8s	https://github.com/SaberMage/spt-core/actions/runs/27665039500/job/81817148087
=== final exit: 0 (0=all pass) ===


CI fully green both runners — `n1-gate`, `test` (Linux 5m10s, Win 6m4s), `traceability` all pass; twohost skipped (no `[twohost]` tag, expected). Notify doyle.


$OWL send doyle <<'EOF'
v0.8.3 PR #19 CI GREEN — both runners pass: n1-gate (kitsubito+hfenduleam), test (Linux 5m10s, Win 6m4s), traceability 8s. twohost skipped (no [twohost] tag, expected — net-seam change isn't twohost-gated). MERGEABLE, 0 behind main. All yours to gate.
EOF

Notify doyle CI green


Command running in background with ID: b3wu5i7vt. Output is being written to: C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\b3wu5i7vt.output. You will be notified when it completes. To check interim output, use Read on that file path.


<task-notification>
<task-id>b3wu5i7vt</task-id>
<tool-use-id>toolu_01TEEWDAPvu8FRkhT5zcTojG</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\b3wu5i7vt.output</output-file>
<status>completed</status>
<summary>Background command "Notify doyle CI green" completed (exit code 0)</summary>
</task-notification>


v0.8.3 complete and submitted — CI green, doyle pinged twice (PR-ready + CI-green).

**Status: HOLDING for doyle's gate.**

Done this session:
- Revived todlando (gen 55→56)
- Confirmed v0.8.2 published (counter 18)
- Took doyle's v0.8.3 dispatch → built the **broker-side QUIC-op bound** (pump-IPC-deadline B-half) end-to-end
- PR #19 base main, **CI green both runners**, gate-bar clean, exactly-once + timeout rationale relayed to doyle

Next (not mine to drive):
- doyle gates PR #19
- on gate-PASS → deployah releases counter 19 (CARGO.LOCK targeted first-party spare + version bump = deployah's at release)

Perch live, listening. Will respond to doyle's verdict, perri reports, or any incoming message.


CI-green ping delivered to doyle (exit 0). All work submitted.

**v0.8.3 HOLDING for doyle gate.** Perch live, listening. Nothing more to do until doyle's verdict or an incoming message.


<task-notification>
<task-id>bzoq0kglt</task-id>
Monitor event: "« spt event »"
<event><EVENT-PART seq="1/5" id="ea8929e4" type="msg" from="doyle">GATE PASS — v0.8.3 PR #19. Full source code-read, not a rubber-stamp. Verified all 4 invariants at the source + both int tests non-vacuous:

1. ORDINARY non-TimedOut, full chain confirmed: bounded_block_on→io::Error::other→dispatch Err→send_error→KIND_ERROR frame→brain net_dial/open/send map BrokerEven</EVENT-PART>
<EVENT-PART seq="2/5" id="ea8929e4">t::Error→io::Error::other=ErrorKind::Other→peer_outcome ordinary arm. Broker fires at 10s, so the brain's OWN recv-deadline TimedOut (brain.rs:1141, only at 30s) never trips. The subtle heart of the fix — correct.
2. 10s &lt; 30s, 20s margin, justified + test-overridable. Good.
3. exactly-once: timeout INSIDE apply_once closure →</EVENT-PART>
<EVENT-PART seq="3/5" id="ea8929e4"> effect()? before applied.insert. netbroker int proves it: !is_applied, applied_count 0, conn_count 0, re-drive same OP re-errors (no phantom dedup). All 4 facets.
4. happy path zero-latency: unit confirms ready op transparent.

INT NON-VACUOUS (the v0.8.2 lesson): pump test captures `first` heartbeat (written loop-top, BEFORE the dia</EVENT-PART>
<EVENT-PART seq="4/5" id="ea8929e4">l), requires ADVANCE, then run_peer_pump→Ok. Pre-fix the first dial wedges forever → loop never re-tops → heartbeat frozen → assert fails. Genuinely catches today's live freeze. netbroker black-hole = real native deadlock (B accepts handshake, never answers seed-proof). Solid.

Docs clean: CHANGELOG version-framed (no codes), KH </EVENT-PART>
<EVENT-PART seq="5/5" id="ea8929e4">7.6 reword + 7.8 new + conformance row, DEFERRED:42 RESOLVED. traceable [doc,impl,unit,int] tagged on real evidence. CI green both runners, seam-sweep green, clippy-workspace clean.

Excellent execution — every invariant landed exactly. Handing to deployah for release (counter 19). You're clear; nothing pending. Thanks.
-- doyle</EVENT-PART></event>
</task-notification>


<task-notification>
<task-id>bn7z60m9c</task-id>
<tool-use-id>toolu_01LQvkbTvSEYfHu2PyxUNUg6</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\bn7z60m9c.output</output-file>
<status>completed</status>
<summary>Background command "Ack doyle gate-pass" completed (exit code 0)</summary>
</task-notification>


doyle **GATE PASS** v0.8.3 — full source code-read, all 4 invariants verified at source, both int tests confirmed non-vacuous. Handed to deployah for release (counter 19). Clear, nothing pending.

Ack doyle + update memory.


$OWL send doyle <<'EOF'
ACK gate-PASS v0.8.3 PR #19 — thorough read appreciated (esp. catching the full ORDINARY-error chain + the non-vacuous heartbeat-before-dial point). Clear, standing down on this. deployah owns release counter 19 (CARGO.LOCK targeted first-party spare + bump). On call if anything surfaces.
EOF

Ack doyle gate-pass


Command running in background with ID: bn7z60m9c. Output is being written to: C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\bn7z60m9c.output. You will be notified when it completes. To check interim output, use Read on that file path.


Prompt:
<task-notification>
<task-id>bn7z60m9c</task-id>
<tool-use-id>toolu_01LQvkbTvSEYfHu2PyxUNUg6</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\1e7c582d-c03a-4db0-bd84-c7b3b7959ea0\tasks\bn7z60m9c.output</output-file>
<status>completed</status>
<summary>Background command "Ack doyle gate-pass" completed (exit code 0)</summary>
</task-notification>


Ack delivered. Update memory to GATE-PASS / handed-deployah state.


Edit

description: v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate

description: v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), doyle GATE-PASS, handed deployah for release counter 19


<tool_use_error>String to replace not found in file.
String: description: v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate
(note: Edit also tried swapping \uXXXX escapes and their characters; neither form matched, so the mismatch is likely elsewhere in old_string. Re-read the file and copy the exact surrounding text.)</tool_use_error>

Error: String to replace not found in file.
String: description: v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate
(note: Edit also tried swapping \uXXXX escapes and their characters; neither form matched, so the mismatch is likely elsewhere in old_string. Re-read the file and copy the exact surrounding text.)


1	---
2	name: v083-broker-quic-deadline
3	description: "v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate"
4	metadata:
5	  node_type: memory
6	  type: project
7	  originSessionId: 1e7c582d-c03a-4db0-bd84-c7b3b7959ea0
8	---

---
name: v083-broker-quic-deadline
description: "v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate"
metadata:
  node_type: memory
  type: project
  originSessionId: 1e7c582d-c03a-4db0-bd84-c7b3b7959ea0
---


description: "v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate"

description: "v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), doyle GATE-PASS, handed deployah for release counter 19"


<tool_use_error>File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.</tool_use_error>


9
10	v0.8.3 (PATCH 0.8.2→0.8.3) = the deferred **B-half** of REQ-HAZARD-PUMP-IPC-DEADLINE ([[peer-pump-stall-bhalf-confirmed]], DEFERRED.md:42). doyle DISPATCH 2026-06-16 (I own end-to-end exec, doyle gates, deployah releases). Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19, base main, PR-READY — pinged doyle with rationale+proof, awaiting gate.**
11
12	Minted **REQ-HAZARD-BROKER-QUIC-DEADLINE**. Root cause: a DEAD roster peer → broker's brain-facing QUIC op (dial/open_stream/send_stream) awaits unbounded; A-half bounds only the brain READ → 30s stall + pump restart re-dials same dead peer + re-wedges. Recurred hfenduleam 2026-06-16.

v0.8.3 (PATCH 0.8.2→0.8.3) = the deferred **B-half** of REQ-HAZARD-PUMP-IPC-DEADLINE ([[peer-pump-stall-bhalf-confirmed]], DEFERRED.md:42). doyle DISPATCH 2026-06-16 (I own end-to-end exec, doyle gates, deployah releases). Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19, base main, PR-READY — pinged doyle with rationale+proof, awaiting gate.**

Minted **REQ-HAZARD-BROKER-QUIC-DEADLINE**. Root cause: a DEAD roster peer → broker's brain-facing QUIC op (dial/open_stream/send_stream) awaits unbounded; A-half bounds only the brain READ → 30s stall + pump restart re-dials same dead peer + re-wedges. Recurred hfenduleam 2026-06-16.


Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19, base main, PR-READY — pinged doyle with rationale+proof, awaiting gate.**

Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19 base main = doyle GATE-PASS (2026-06-16, full source code-read, all 4 invariants verified at source + both int tests confirmed non-vacuous, CI green both runners). Handed to deployah for release counter 19. todlando CLEAR — nothing pending.**


The file C:\Users\decid\.ccs\instances\bigscreen\projects\C--Users-decid-Documents-projects-spt-core\memory\v083-broker-quic-deadline.md has been updated successfully. (file state is current in your context — no need to Read it back)

---
name: v083-broker-quic-deadline
description: "v0.8.3 PR#19 — broker-side QUIC-op bound (pump-IPC-deadline B-half), PR-ready awaiting doyle gate"
metadata:
  node_type: memory
  type: project
  originSessionId: 1e7c582d-c03a-4db0-bd84-c7b3b7959ea0
---

v0.8.3 (PATCH 0.8.2→0.8.3) = the deferred **B-half** of REQ-HAZARD-PUMP-IPC-DEADLINE ([[peer-pump-stall-bhalf-confirmed]], DEFERRED.md:42). doyle DISPATCH 2026-06-16 (I own end-to-end exec, doyle gates, deployah releases). Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19, base main, PR-READY — pinged doyle with rationale+proof, awaiting gate.**

Minted **REQ-HAZARD-BROKER-QUIC-DEADLINE**. Root cause: a DEAD roster peer → broker's brain-facing QUIC op (dial/open_stream/send_stream) awaits unbounded; A-half bounds only the brain READ → 30s stall + pump restart re-dials same dead peer + re-wedges. Recurred hfenduleam 2026-06-16.

FIX: `NetHost::bounded_block_on` wraps the 3 QUIC await sites in `tokio::time::timeout` under `quic_op_timeout` (default `BROKER_QUIC_OP_TIMEOUT_MS`=10s; test-override `set_quic_op_timeout`, off NetConfig like set_roster_exchange). On elapse → future DROPPED (cancels op, nothing half-registered) → non-TimedOut io::Error → broker REPLIES ordinary error frame.

4 invariants: (1) ordinary err not TimedOut — brain maps BrokerEvent::Error→io::Error::other=ErrorKind::Other → peer_outcome per-peer arm, NOT brain's own recv-deadline TimedOut (A-half poison path). (2) 10s < brain's 30s PUMP_PEER_IO_TIMEOUT so broker fires first (20s margin). (3) exactly-once: QUIC call is INSIDE apply_once closure → timeout→closure Err→effect()? before applied.insert → no phantom conn/stream id. (4) happy path zero added latency.

Tests: unit nethost (never-completing→prompt non-TimedOut err; ready untouched); int netbroker (membership-mismatch black hole: A=membership Some, B=None → A's prove_membership hangs → broker ordinary err in bound + exactly-once-on-timeout: !is_applied, applied_count 0, conn_count 0, redial clean); int pump (production pump vs dead peer → heartbeat monotonic-advances + run_peer_pump exits Ok, no PEER_PUMP_RESTART; pre-fix freezes ≥30s, 20s window catches). Membership-mismatch = the documented native black hole (nethost docs: "both peers must agree or the side expecting the control stream would hang").

**doyle GATE PASS @ PR#19 (full source code-read, not rubber-stamp) → deployah RELEASE GO (counter 19).** Verified all 4 invariants at source: (1) ordinary-error chain end-to-end (bounded_block_on→Error::other→send_error→KIND_ERROR→brain Error::other=Other→peer_outcome ordinary arm; broker fires 10s so brain's own recv-deadline TimedOut @brain.rs:1141 never trips); (2) 10s<30s margin; (3) exactly-once timeout-inside-apply_once (int proves !is_applied/applied_count0/conn_count0/clean-redial); (4) happy-path transparent. INT NON-VACUOUS confirmed (v0.8.2 lesson): pump test captures `first` heartbeat written loop-top BEFORE dial → requires ADVANCE → pre-fix dial wedges forever→loop never re-tops→frozen→assert fails (genuinely catches today's freeze). Linchpin verified: every net handler Err→send_error frame (broker.rs:735-756). CI green both runners, mergeable, seam-sweep green, clippy-workspace clean. Docs version-framed (no codes). Relayed VETTED CHANGELOG body + [0.8.3] intro to deployah. doyle on-call for hash check.

3 commits: mint 69af744 → impl+unit+int cece4a6 → docs f4dc053. Docs: KNOWN-HAZARDS 7.8 NEW + 7.6 B-half-fixed reword + conformance row, DEFERRED:42 RESOLVED, CHANGELOG [Unreleased]. Gate bar preflighted: clippy --workspace -D warnings clean · traceable EXIT 0 [doc,impl,unit,int] · seam-sweep green (netbroker/pump/mesh/replicate/wanmsg/attach/daemon_lifecycle_real_brain + 314 lib) · docs-drift OK (CRLF-only). CARGO.LOCK bump = deployah's at release.

-v0.8.3 (PATCH 0.8.2→0.8.3) = the deferred **B-half** of REQ-HAZARD-PUMP-IPC-DEADLINE ([[peer-pump-stall-bhalf-confirmed]], DEFERRED.md:42). doyle DISPATCH 2026-06-16 (I own end-to-end exec, doyle gates, deployah releases). Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19, base main, PR-READY — pinged doyle with rationale+proof, awaiting gate.**

+v0.8.3 (PATCH 0.8.2→0.8.3) = the deferred **B-half** of REQ-HAZARD-PUMP-IPC-DEADLINE ([[peer-pump-stall-bhalf-confirmed]], DEFERRED.md:42). doyle DISPATCH 2026-06-16 (I own end-to-end exec, doyle gates, deployah releases). Branch `v0.8.3-broker-quic-deadline` off main@v0.8.2. **PR #19 base main = doyle GATE-PASS (2026-06-16, full source code-read, all 4 invariants verified at source + both int tests confirmed non-vacuous, CI green both runners). Handed to deployah for release counter 19. todlando CLEAR — nothing pending.**


Update the index line to GATE-PASS state.


3	- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — pump-IPC B-half (PATCH): REQ-HAZARD-BROKER-QUIC-DEADLINE. NetHost::bounded_block_on (tokio timeout 10s<30s brain) wraps dial/open_stream/send_stream → dead peer errors ORDINARY (non-TimedOut) INSIDE apply_once (no phantom) → pump redials not wedges. **PR #19 base main PR-READY**: 3 commits, gate-bar green (clippy/traceable EXIT0/seam-sweep/docs-drift), pinged doyle, AWAITING GATE. deployah CARGO.LOCK+bump at release


→ pump redials not wedges. **PR #19 base main PR-READY**: 3 commits, gate-bar green (clippy/traceable EXIT0/seam-sweep/docs-drift), pinged doyle, AWAITING GATE. deployah CARGO.LOCK+bump at release

→ pump redials not wedges. **PR #19 base main = doyle GATE-PASS (full source read, 4 invariants + non-vacuous int verified, CI green both runners). Handed deployah → release counter 19. todlando CLEAR.** deployah CARGO.LOCK+bump at release


The file C:\Users\decid\.ccs\instances\bigscreen\projects\C--Users-decid-Documents-projects-spt-core\memory\MEMORY.md has been updated successfully. (file state is current in your context — no need to Read it back)

-- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — pump-IPC B-half (PATCH): REQ-HAZARD-BROKER-QUIC-DEADLINE. NetHost::bounded_block_on (tokio timeout 10s<30s brain) wraps dial/open_stream/send_stream → dead peer errors ORDINARY (non-TimedOut) INSIDE apply_once (no phantom) → pump redials not wedges. **PR #19 base main PR-READY**: 3 commits, gate-bar green (clippy/traceable EXIT0/seam-sweep/docs-drift), pinged doyle, AWAITING GATE. deployah CARGO.LOCK+bump at release

+- [v0.8.3 broker-QUIC-deadline](v083-broker-quic-deadline.md) — pump-IPC B-half (PATCH): REQ-HAZARD-BROKER-QUIC-DEADLINE. NetHost::bounded_block_on (tokio timeout 10s<30s brain) wraps dial/open_stream/send_stream → dead peer errors ORDINARY (non-TimedOut) INSIDE apply_once (no phantom) → pump redials not wedges. **PR #19 base main = doyle GATE-PASS (full source read, 4 invariants + non-vacuous int verified, CI green both runners). Handed deployah → release counter 19. todlando CLEAR.** deployah CARGO.LOCK+bump at release


v0.8.3 **DONE** — doyle gate-PASS, handed to deployah for release counter 19. Memory updated.

**Session summary:**
- Revived todlando (gen 55→56), confirmed v0.8.2 published
- Built **broker-side QUIC-op bound** (pump-IPC-deadline B-half) end-to-end from doyle's dispatch
- `REQ-HAZARD-BROKER-QUIC-DEADLINE`: `NetHost::bounded_block_on` (10s < brain's 30s) wraps the 3 QUIC await sites → dead peer fails ORDINARY (non-TimedOut) inside `apply_once` → pump redials, never wedges
- 3 commits, full gate-bar green, CI green both runners
- **doyle GATE-PASS** (full source read, all 4 invariants verified, both int tests non-vacuous)

todlando **CLEAR** — nothing pending. deployah owns release counter 19 (CARGO.LOCK first-party spare + bump at release). Perch live; standing by for deployah publish confirm, perri reports, or any message.


<command-message>spt:commune</command-message>
<command-name>/spt:commune</command-name>
<command-args>with immediate next steps and broad summary of the project's status + end goal. we'll resume in the next session</command-args>