---
name: v0306-published
description: v0.30.6 counter 57 @d73e19e PUBLISHED — update-wedge ROUND-4 (final) bounded broker writes; restart-required; 3-cut release saga
metadata: 
  node_type: memory
  type: project
  originSessionId: 6a623999-3605-40e4-8991-c27d0467ffc0
---

v0.30.6 = **counter 57 @d73e19e PUBLISHED** (Latest, isDraft=false, 10 assets; update-set version:57 product_version:0.30.6 channel:stable, 3 platforms). Published 2026-07-10 via `xtask release-publish --tag v0.30.6 --key-id rel-primary-2026 --version 57` (SPT_RELEASE_SEED in profile env). Closes the update-wedge saga's ROUND-4 — see [[v0305-published]] (round-3), [[update-wedge-2-resume-steal]].

**Fix (round-4, Option C — the durable class fix round-3 deferred):** root (hertz RCA) = a broker controller writer held the conn's serialized send gate ACROSS an UNBOUNDED OS write; on Windows `WriteFileEx`+`SleepEx(INFINITE)` has no write timeout, so an `rc --take` consumer that stops reading blocks the write INDEFINITELY (~128s field capture, PTY-freeze-under-load). Fix = broker-owned `BrokerConn` (crates/spt-daemon/src/conn.rs): serialized write gate + non-escaping send half + idempotent poison + an INDEPENDENT per-conn watchdog at an absolute deadline covering gate-wait AND OS-write completion. On deadline/partial/cancel: poison, abort read+write (CancelIoEx+DisconnectNamedPipe / shutdown(Both)), never reuse. REQ-HAZARD-SHAREDSEND-NO-BLOCKING-WRITE-UNDER-LOCK [doc,impl,int], KNOWN-HAZARDS 7.38. **⚠️ RESTART-REQUIRED apply** (broker-side, daemon.rs:368 = persistent broker → `fetch --apply` lands via full daemon restart, NOT seamless like v0.30.3/5).

**3-CUT RELEASE SAGA (lessons):**
- Base rule: r4 fix branch f10e5e9 was based on STALE main (5555648, pre-round-3) — a direct cut would REGRESS round-1/2/3. Correct base = origin/main (v0.30.5 tip) + MERGE f10e5e9. doyle trial-merged; I found a hidden DUP id git didn't flag (REQ-HAZARD-SHAREDSEND in main as deferred SEED [] + f10e5e9 as activated) → bounced to todlando (not a rerun/merge-resolve — a REQ-registry decision). todlando produced pre-merged 53cfab5 (dedup'd).
- PR #75 (base 53cfab5): CI caught a REAL fail — round-3's best-of-K flood-starvation guard is stale-BY-DESIGN under r4 Option C (non-blocking writes → subscriber no longer starves). doyle ruled retire→deterministic daemon_resume_leaves_zero_brain_subscribers guard. Re-gate @3a4335c.
- PR #76 (base 3a4335c): kitsubito Linux reds — first the INCIDENT BOX (resident spt 0.6.0 daemon busy-spinning 146%CPU 3d9h = PAIR_MEET_UP loop + brain PEER_PUMP_FAIL; operator upgraded 0.6.0→0.30.5). doyle proved r4-clean: pre-r4 main CI (run 29063765059... actually 29063755424) already failed 7 of the same e2e class. Then the clean-box rerun caught a REAL clippy lint: conn.rs:215 needless_return, Linux-only (cfg(windows) strips the block → guard return becomes fn-tail). NOT toolchain drift (my wrong theory) — it was INCREMENTAL-CACHE lint-suppression on earlier CI + doyle's gate ran WINDOWS clippy (cfg hid it). Fix = cfg_attr(unix, allow) 5-line. doyle added a mandatory fresh-target LINUX clippy gate leg. Re-gate @e0bd8b9.
- PR #77 (base e0bd8b9): ALL GREEN (Linux test 12m9s, Windows test 13m55s money-test, n1-gate ×2, traceability). Merged @d73e19e, tagged, published.

**KEY LESSONS:** (1) "0 CI runs" ≠ idle box — ground with `ssh reavus@kitsubito uptime` (I mis-called idle at load 24.83). (2) NEVER inline a msg body with backticks/parens/$() under `spt send` — bash evaluates + mangles it; use `spt send <t> < file`. (3) A git merge can hide a duplicate REQ id at different file offsets (no textual conflict) — check traceable after merging. (4) Incremental-cache masks clippy on CI; a fresh-target rebuild lints anew. (5) On CI red: discriminate exact signature vs known-flake buckets; real code/test contradiction → HOLD+bounce, never rerun-to-mask.

✅ FIELD-ACCEPTED PASS 2026-07-10 — UPDATE-WEDGE SAGA CLOSED (rounds 1-4). doyle blackhole rig (2 disposable claude-spt:ccs endpoints, blackhole-controller.ps1 armed undrained rc --take controllers, real PTY output via injects): CONN_WRITE_POISONED fired at the 15000ms bound; re-take/re-wedge/re-poison churn each retired the conn ("never reused"), daemon absorbed 5+ min; NO broker freeze (status responsive, messaging live, other sessions streamed); killed black-holes → fresh `spt rc --take` attached instantly + streamed 27KB, NO daemon restart; no BRAIN_SUBSCRIBER_STALL_EVICT (poison retires the physical conn ahead of the logical stall-evict). Operator applied via `spt update apply --finish` = full daemon restart (new pid, broker image 0.30.6). Counter from published metadata (56→57). Two NON-blocking follow-ups flagged to doyle's triage (NOT round-5): ambient CONN_WRITE_POISONED log-churn correlated 1:1 with PUMP_PEER_FAIL submit-dials to offline peers (log-noise/mislabel on the dial-path write, no wedge); mobile-gw alive=false after restart = live F-038.

Prior: [[v0305-published]] 56 @0a306c9, [[v0304-published]] 55 @b0d7719 (FIELD-BROKEN), 30.3=54 @3136702.
