# v0.69.0 (#294) golden-head intake baseline — captured deployah 2026-09-09 23:20Z

GREENLIT form = comment 5610035178 + its delta sequence (see DELTAS below) on BigscreenVR/spt-bs-releases#294 (doyle, 23:15Z).
Operator directive under which doyle selected: "P0: root cause and fix request #293. use your
best judgment to pull it + any other problematic or high-priority issues into a bugfix
milestone, then build the fixes and drive to release."

BASE: main de5a44bc338d679f3c63f6d0f68826eb9e575d73 — VERIFIED present locally, == main tip
at capture time. (v0.68.0 = a2f335f81e6a67f9aa9ea4e6e4bdfab44a1f9200, verified.)

## Baseline set — MUST all ride, or each absence gets a reason comment on #294 BEFORE golden
Form list and board sub-issues AGREE exactly, 8/8 after delta 1, zero drift:
  #293  P0  cross-node comms broken after v0.68.0            GREENLIT/BUGFIX
  #289      WAN request reply read has no deadline            GREENLIT/BUGFIX
  #292      brain-only update leaves old serve/docs surface   GREENLIT/BUGFIX
  #287      daemon restart strands persistent shells          GREENLIT/BUGFIX
  #281      registry snapshot write-only for the daemon       GREENLIT/BUGFIX
  #285      zombie reap kills a remembered pid unread         GREENLIT/BUGFIX
  #286      daemon stderr ~100 MB/day brain-conn churn        GREENLIT/BUGFIX
  #295      status names a dead daemon pid (stale daemon.pid)  GREENLIT/BUGFIX  [delta 1]
RIDER (not a request, correctly NOT a sub-issue): IR-92 — spt-hosted inject leg publishes no
MSG_IN (infra register, PR #215 entry).

## NOT PULLED, reason already recorded in the greenlit form (no further comment owed)
  #282                    served-URL port; webserve, not comms-critical
  #267 #263 #254 #243 #244 no restart/comms nexus; next intake
  ideas flagged NEEDS-OPERATOR untouched

## Check to run at hand-off (a DIFF against the above, not a re-derivation)
1. Re-pull sub-issues of #294 + re-read #294 comments after 23:15Z; any add/drop vs the 7 above
   must have its OWN reason comment on #294, posted BEFORE golden starts.
2. A DROP is not discharged by the reason comment alone: it must ALSO be RELOCATED (to an
   existing unbuilt milestone or a new one) or moved BACK to state: eval. Verify the relocation
   landed on the board, do not take the word for it.
3. Confirm each rider/member is actually IN the handed head (commit present), not merely listed.
4. Confirm the head's base is de5a44bc (or a stated, reasoned newer main).
Only then does golden CI run. The check gates the RUN, not just the merge.
Red golden run -> straight back to doyle for triage.

## STEP 0 — before the FIRST gate/CI command, not after
Open memory/GATE-TEST-INDEX.md (and RELEASE-INDEX.md before any tag/publish). Banked trap:
a whole golden gate was once run without opening it and hit a trap it covers, WITH the command.
Trigger is the ACT — first touch of a gate/rig/test-filter/CI log.

## DELTAS to the greenlit form — the form IS the sequence, not its head
DELTA 1 (ADD #295) — reason comment 5610127841 on #294. VERIFIED INDEPENDENTLY, not on word:
  - comment exists, is ON issue 294, GitHub created_at 2026-09-09T23:23:31Z, reasons the add
    (`spt node status` names dead pid 28972; real supervisor 60144 / brain 31856; hertz found it
    while root-causing #293; #285 family, #292/#287 restart path)
  - board re-pulled: totalCount 8, #295 present as sub-issue, state: GREENLIT / type: BUGFIX
  - posted AFTER the form (23:15Z) and BEFORE golden — correct order, rule satisfied
  - No drop, so no relocation/eval-return owed.
  - MINOR: the comment BODY self-stamps 23:30Z while GitHub created_at is 23:23:31Z (~7 min
    ahead). Authoritative stamp is created_at. Immaterial here; matters only if delta ORDER is
    ever adjudicated from self-stated stamps rather than API stamps.
DIFF TARGET IS NOW THE 8-SET: #293 #289 #292 #287 #281 #285 #286 #295 + rider IR-92.

## GATED MEMBERS (head-assembly ledger) — verified by me, not taken on word
#289 — GATED GREEN. sha 6c0fa00be48f6967e7c89aca01c9a8119f7c8820
  - PR #208 headRefOid == that sha exactly; OPEN, MERGEABLE, base main
  - de5a44bc IS ancestor (git merge-base --is-ancestor, rc 0); chain = 5 commits
  - run 34416343641: headSha matches, status completed, conclusion success,
    ATTEMPT 1 read in the SAME command as the conclusion (run-level-vs-attempt rule)
  - 5/5 jobs success AND 5 is the COMPLETE workflow graph, not just what materialized:
    ci.yml at that sha has 4 job keys (changes, unit, lint, traceability) with `unit`
    a 2-cell matrix (Linux kitsubito + Windows hfenduleam) = 5. Nothing unstarted/skipped.
  - patch-ids x5 vs pre-rebase chain a2f335f8..8d974751: IDENTICAL, same order,
    computed here with `git patch-id --stable` (doyle's claim independently confirmed)
  - co-author trailers: 5/5 carry the space spelling `Co-authored by: todlando`,
    0 hyphenated. Audited by RAW BODY grep, never `%(trailers:)` (that returns a
    confident EMPTY on the space spelling).

### FINDING on #289 — flagged, NOT a gate block (form is what I gate on)
4 of the 5 commit BODIES cite PRE-REBASE shas that die with the branch:
  6c0fa00b cites 168c8622 · 349091f3 cites 168c8622 · 12df4826 cites 168c8622
  890dad7c cites f6eaa935 (x2)
Old -> new map: 168c8622->5c78513a · 5ca85851->12df4826 · f6eaa935->349091f3
                54259091->890dad7c · 8d974751->6c0fa00b
The rebase rewrote the objects but not the prose citing them, so once PR #208's branch
is deleted a reader chasing "since 168c8622 refuses an unbounded carrier" gets nothing —
and that sentence is the load-bearing WHY for the whole lane. doyle/todlando's call:
a re-roll costs another gate window (the Windows cell alone ran 24m28s), and if they take
it the gated sha CHANGES and this whole verification re-runs against the new one.

### RULED (doyle, gater, 2026-09-09) — NO RE-ROLL on the #289 body citations
Rationale: the claims are TRUE of the commits they ride; only the citations decay. A re-roll
would re-gate a new sha for prose mid-P0. GATED SHA STAYS 6c0fa00b — my verification above
stands as-is and does not re-run.
Durable record VERIFIED PRESENT by me, both homes, not taken on word:
  - releases#289 comment 5610406214, created_at 2026-09-09T23:51:30Z — carries the full
    five-pair map and the no-re-roll rationale
  - PR #208 body, appended (line ~99) — same block verbatim
TWO INDEPENDENT HOMES, which is stronger than the one asked for: the releases#289 comment
survives even if the spt-bs-core PR/branch is deleted outright, and the PR body survives the
BRANCH deletion that kills the cited objects. Either alone would discharge it.
Note (no action): PR #208's body ALSO keys its own evidence table (rows ~70-73) by the OLD
shas 168c8622/5ca85851/f6eaa935/54259091, and cites f6eaa935 at ~77 and 168c8622 at ~81. The
appended map sits BELOW that table, so a reader meets the stale keys first — but it is the
same document and the map says "Resolve them here", so the decay is discharged in place.

## #293 candidate 0f7e2e28 — STATIC legs pre-verified (NOT yet gated; runtime pending)
doyle diff-gated it; I pre-ran the static half so member-2 intake is a diff, not a derivation.
VERIFIED: de5a44bc ancestor; chain 3 commits (509b561b wip / 5fc12121 test / 0f7e2e28 fix).
  - "read_event zero sites/decls" HOLDS: one non-comment hit, and it is PROSE INSIDE A STRING
    (tests/resume.rs:118). Only fn is read_event_until (the new API).
    ⚠ MY OWN METER ERROR, caught pre-report: `fn +read_event` is not word-bounded and matched
    read_event_until, so my first pass read "1 decl" and would have manufactured a false finding
    against a true claim. Same class as the banned filename-substring grep. Word-bound, then
    read the hit's context, THEN speak.
  - "REQ + 55 tags" EXACT: 1 doc + 52 impl + 2 int; required_stages [doc,impl,int] all covered.
  - Hoist uniform across 10 dispatch.rs sites, each tagged.
  - pump/mod.rs is BYTE-IDENTICAL base..candidate: "both pump sites" = the two int tags in
    tests/pumpdeadline.rs:184,192, NOT src/pump/mod.rs. Pin that wording at gate time.
OPEN QUESTION raised to doyle + todlando (SENT, both): call_deadline() is absolute, hoisted once,
never renewed — right for a reply-wait, but 10 of the sites are serve_*_feed LONG-LIVED streams.
Only cold_start_pump sets io_timeout Some (brain.rs:497). If the pump serves feeds on its
pump-mode brain, a healthy feed gains a bounded lifetime and TimedOut escalates to a SUPERVISED
RESTART — a shape that rhymes with #293's own symptom. Also warned: a fast PR unit SET is
STRUCTURALLY unable to see it (needs a cell outliving io_timeout), so a green there is not an
answer. Awaiting their word; will record closed on it if the answer is "feeds never run on pump".
MINOR, not a block: 509b561b rides as `wip(brain):` into a chain headed for ff-only main.

## #293 — SUPERSEDED SHAS, do not gate either
0f7e2e28 and d79831d1 are BOTH superseded (crossed doyle's amendment). Nothing of mine binds to
them. Amended head adds: explicit None for the nine feed servers + the attach serve loop, a REQ
clause, the wip reword, and a STATIC feed-census cell for hertz (positive control = the
reply-wait sites DO call call_deadline(); no feed body and not the attach serve loop does).
Proven while it was live and still useful: crates/spt-daemon/src tree hash was IDENTICAL
(274fc04c…) at 0f7e2e28 and d79831d1, so that delta was genuinely test-only. Re-run the tree-hash
identity trick on the amended head — it converts "src is untouched" from a claim into a proof and
costs one command.
CORRECTION BANKED (mine): I wrote "10 of the sites are serve_*_feed" and named nine. The tenth is
peek_first_line, a REPLY-WAIT. Conclusion held (all ten resolve to None) but for TWO reasons, and
the distinction is load-bearing for the amendment: the nine feeds must never carry a call budget
at all; peek_first_line is neutral only because its brain happens to be Whole, and SHOULD keep
call_deadline() so it bounds the day that path ever gets a pump-mode brain.

## CHANGELOG for #293 — SETTLED (my binding lane; use verbatim at release)
  - Cross-node messaging now recovers on its own instead of stalling until the service is
    restarted. Previously, one unanswered request could stop this node from advertising itself
    and reconnecting to peers, until other nodes could no longer reach it.
    (doyle adopted the sharpening too — "could no longer reach it", NOT "lost sight of it";
     it names the NO_PERCH the sending side actually met. This is the verbatim final text.)
History worth keeping, because both errors were the SAME class caught one sentence apart:
  - The authored entry leaked four mechanism nouns (peer-pump, pump, broker, "reply deadline")
    and described mechanism rather than observable effect. Rewritten to effect.
  - MY replacement's clause (b) ("block further messages indefinitely") was OVERSTATED — doyle
    measured outbound sends still working from the wedged node (`spt send` = SENT(WAN) at 23:10Z
    with the pump dead). What actually broke: advertising + reconnecting, so PEERS lost sight and
    THEIR sends met NO_PERCH.
  - MY first sentence then named the WRONG END of the wire ("when a peer stops responding"); the
    trigger is the local broker going quiet. Fixed by DELETING the trigger clause: a cause that
    cannot be stated without mechanism nouns is a cause the entry should not state at all.
RULE OUT OF IT: ask for the accuracy check on the WHOLE proposed text, not just the clause you
already doubt. I asked doyle to check clause (b) and he did; the first sentence was wrong too and
only got caught because his correction happened to expose it.

## #293 — OPERATIVE HEAD = 9d71871905766e293322eb94ed0748d04d7aba75
doyle ruling N4U3HFBL (00:12:41Z) supersedes CKELQ7BL: #216 STAYS at 9d718719; the census cell,
the REQ's new `unit` stage and the resume.rs:118 prose fix go to a SIBLING PR, not this one.
MY STATIC CENSUS AT 9d718719 STANDS AND IS GREEN (run above): ancestry, chain 7 w/ refactor
reword, ten explicit-None sites (9 dispatch feeds + attach.rs:543), peek_first_line the only
call_deadline in dispatch, pump/mod.rs byte-identical to base, tags 1/52/2, REQ clause naming
stream loops, CHANGELOG verbatim.
OBJECTION WITHDRAWN, and say why: I argued the traceability green was gating a REQ config about
to change. With the `unit` stage moved to the SIBLING, required_stages at THIS head stays
[doc,impl,int], so the green does describe the head being gated. The concern TRANSFERS to the
sibling: when it adds `unit`, that stage needs evidence tagged to it or the clause is decoration
(doyle banked that rule).
RERUN PROVENANCE — what I will and will not accept at gate time:
Attempt 1 was CANCELLED. A --failed/cancelled rerun keeps run id 34420183767 and produces a
COMPOSITE attempt 2: jobs that succeeded before the cancel are CARRIED (original started_at),
previously-cancelled jobs run fresh.
  ACCEPT: all five jobs green AT SHA 9d718719, each labelled with the attempt its result came
    from. The sha never changed, so a carried success is a TRUE observation of this sha.
  REFUSE: reading a carried job as evidence the rerun RE-TESTED it, or counting one observation
    twice across attempts.
  READ: run_attempt in the SAME command as the verdict; jobs at /attempts/<n>/jobs; never bind a
    terminal-exit check to `status == completed` (already satisfied by the cancelled attempt 1).

## doyle's FOUR RULINGS (CGAQY75Q + CMA5CRPJ) — recorded, bases verified where they are mine
1. PUSH PROTOCOL, binding for the rest of #294: INTENT-TO-PUSH <branch> <full sha>, push only on
   doyle's CLEAR <sha>; he answers within 2 min or CLEAR by default at the 3rd minute, naming the
   clock read. Every amendment is an explicit HOLD on the sha it names until CLEAR is re-issued.
   (Adopted from my three-crossings pattern read — all ordering, no content.)
2. #216 STAYS at 9d718719, gated by run 34420183767 ATTEMPT 2 (rerun). resume.rs:118 prose stays
   in #216; retirement claim reads "0 calls/decls, 1 prose mention" (my phrasing adopted); the
   string moves in the sibling.
3. CENSUS GUARD = an `xtask check` gate, NOT a #[test] over repo source. Precedent in-tree:
   check_heavy_unit_classification / check_heavy_integration_classification
   (crates/xtask/src/main.rs:689/754). Shape: a PURE text predicate + unit cells on SYNTHETIC
   text (positive: fake serve_x_feed calling call_deadline caught; negative: peek_first_line-shaped
   reply-wait NOT caught; retirement: fake `.read_event(` caught), applied by the gate to the real
   sources, refusing with a named line. hertz AUTHORS from 9d718719, todlando WIRES + moves the
   string + adds `unit` to the REQ with [unit->..] on the predicate cells, [impl->..] on the gate.
   ONE sibling PR, base main, "stacks on #216".
4. MY REGISTER QUESTION — RULED AND CLOSED, no IR, and the answer is a distinction I had not
   considered: AGENTS.md's rule binds ENTRIES, not paragraphs. A new `###` heading mints a
   REQ-HAZARD-* and needs a test; an AMENDMENT paragraph under an existing heading binds to
   whichever REQ carries that heading's test.
   VERIFIED BY ME at 9d718719: the #293 paragraph is at line 506 and the nearest `###` above it
   is line 498 = "7.6 Pump brain-IPC reads must be deadline-bounded [REQ-HAZARD-PUMP-IPC-DEADLINE]".
   So it IS an amendment under an existing entry. Ruling's factual basis holds; not looser than
   written, the written rule applied to a paragraph.

## HEAD CHAIN for my diff (doyle, authoritative)
  #289 6c0fa00b -> #293 9d718719 -> census (sha to come) + IR-92 rider + docs lane
Still ungated after that: #292 #287 #281 #285 #286 #295.
My earlier required_stages objection is DISCHARGED for #216 (the `unit` stage rides the sibling,
so 9d718719's traceability green describes 9d718719) and doyle states the rule I wanted stated:
9d718719's green is evidence for 9d718719 ONLY and nothing cites it for the assembled head.

## #293 — GATED GREEN (member 2 of 8). sha 9d71871905766e293322eb94ed0748d04d7aba75
Verified by me, every leg, not taken on word:
  - PR #216 headRefOid == the sha exactly; OPEN, MERGEABLE, base main
  - de5a44bc IS ancestor; chain 7 commits; trailers 7/7 space spelling (raw body grep)
  - run 34420183767: head_sha matches, status completed, conclusion SUCCESS, run_attempt 2 —
    all read in ONE command (run-level-vs-attempt rule)
  - 5/5 jobs success AND 5 is the COMPLETE graph at this sha: ci.yml has 4 job keys
    (changes, unit, lint, traceability), unit a 2-cell matrix = 5. Nothing skipped/unstarted.
  - PROVENANCE, by started_at vs attempt 2's own run_started_at (00:14:32Z):
      FRESH in attempt 2 — unit Linux kitsubito (00:14:36->00:19:28Z)
                           unit Windows hfenduleam (00:14:36->00:39:22Z)
      CARRIED from attempt 1 — changes (00:11:19), traceability (00:11:06), lint (00:11:28)
    All five at the SAME sha, so all five are true observations OF 9d718719. Recorded as
    "2 executed in attempt 2, 3 carried from attempt 1" — never as five fresh.
  - static census (run earlier at this sha) green: ten explicit-None sites, peek_first_line the
    only call_deadline in dispatch, pump/mod.rs byte-identical to base, tags 1/52/2, REQ clause
    naming stream loops, CHANGELOG verbatim.
FORM: #293 is a greenlit member, present, no drop. Intake rule satisfied.

## LEDGER: 2 of 8 GATED
  #289 6c0fa00b  GREEN (run 34416343641 att 1)
  #293 9d718719  GREEN (run 34420183767 att 2)
  ungated: #292 #287 #281 #285 #286 #295 · + census sibling (sha tbd), IR-92 rider, docs lane

## RELEASE CLOSE for v0.69.0 — loaded NOW, before the window, because I got this wrong once
Latest published cut (RELEASE-INDEX ledger): v0.68.0 c104 @a2f335f8, 2026-09-09T09:36:41Z.
So v0.69.0 is the next tag. Base of the milestone: de5a44bc.

⚠ MY OWN v0.67.0 FAILURE, twice, and it is a SHAPE bug not a knowledge gap:
"a step that STRADDLES an irreversible action reads as done AT the action". I drove the
pre-publish cascade, PUBLISHED, verified the publish, and STOPPED — the POST-publish work never
ran. #23 plus 8 members sat CLOSED-but-ACCEPTANCE for ~50 minutes with an empty card until the
OPERATOR caught it. Every check I had still passed, because my checks measure the ARTIFACT and
the miss was on the BOARD. I then reported the arc closed. The verb was documented all along —
measuring the file refuted the "doc gap" story I was handed.
COUNTERMEASURE, applied as a rule not a reminder: treat PUBLISH as a hard boundary. Any step whose
text spans it gets SPLIT INTO TWO TICKS, one before and one after, and after the publish I RE-READ
THE RUNBOOK FROM THE TOP rather than resuming from where I think I was.

POST-PUBLISH, on alchemy-0 (verbs confirmed from `spt shell cmd alchemy-0 help` this session):
  1. `sweep`          — reconciles merge-closed Requests still in an open-loop state to ACCEPTANCE
  2. `release <tag>`  — promotes ACCEPTANCE Requests closed BEFORE the publish time to DONE and
                        answers with the roundup
Neither is optional and BOTH sit after the irreversible act. The board is not done when the
artifact is published.

ALSO CONFIRMED THIS SESSION (RELEASE-INDEX, doyle 2026-08-21) — the intake rule I have been
applying is the STANDING one, not an ad-hoc: "greenlit form = the DELTA SEQUENCE". Fold ALL deltas
in order before comparing head to form, and CITE THE PAIR YOU FOLDED. Precedent: #212's delta 1
said "no member added/dropped/relocated" — true when written — and delta 2 then CUT #153 and
minted #213 into its slot. First-alone refuses a good head; latest-alone loses the baseline.
For #294 I have folded: form 5610035178 + delta 1 (5610127841, ADD #295). Cite that pair.

SEED (binding, this box): publish with SPT_RELEASE_SEED_CMD UNSET so xtask reads the hex
SPT_RELEASE_SEED directly. The _CMD path on Windows double-decodes and panics
"seed is 32 bytes: TryFromSliceError". Do not re-raise the runbook step-4 multi-user-host rule
here — accepted deviation, already ruled, re-raising costs a window.

## PR #217 (census sibling) — STATIC CENSUS DONE, NOT GATED. sha 05e96e11f1213bbb660fc0f51b85e5efc062b57e
Stacks correctly: de5a44bc ancestor YES, contains #293 head 9d718719 YES, 2 commits on top.
Files: xtask/src/brainread.rs (+396 new), xtask/src/main.rs (+13), resume.rs, KNOWN-HAZARDS, toml.

GOOD, and better than what I asked for — record it:
  - TWO LAYERS. (1) generic predicates read_event_sites + feed_bodies_calling_call_deadline
    sweep EVERY .rs under crates/ — a FUTURE tenth feed is caught (cell 1 uses `serve_future_feed`,
    which exists nowhere in the tree, and it IS flagged). (2) named policy_controls pin
    dispatch.rs (nine feeds + peek_first_line), attach.rs (serve_attach), brain.rs (three
    reply-waits: net_stream_send, net_streams, net_stream_retire_with).
  - MY FLAGGED NEGATIVE CELL IS SATISFIED EXACTLY: peek_first_line calling brain.call_deadline()
    is NOT flagged while serve_future_feed and serve_attach ARE (findings asserted at [2,5]).
    The negative is a legitimate reply-wait, not merely a non-feed — which is what I asked for.
  - reply_control_rejects_missing_or_rearmed_deadline GOES FURTHER: hoisted-before-loop = valid,
    re-armed INSIDE the loop = 1 finding, and an EMPTY source = 1 finding. So the hardcoded name
    list going stale (a rename/deletion) produces a RED, not a silent pass. Answers the
    stale-list worry before I raised it.
  - tokenizer robustness: raw strings, nested block comments, '}' char literal; retirement cell
    catches multiline brain\n.read_event(), bare decl, Brain::read_event(), raw-ident r#read_event.
  - REQ required_stages now [doc,impl,int,unit]; tags 1/54/2/4, unit tags on the predicate cells,
    impl tag on the gate fn. resume.rs:118 moved to read_event_until in BOTH the doc line and
    the .expect(. Four remaining tree-wide read_event non-comment hits are ALL string literals
    inside brainread.rs itself (matcher text, diagnostic message, two fixtures) — zero call
    sites, zero decls, retirement claim intact.

⛔ BLOCKING GAP — THE GATE IS NOT WIRED INTO CI. Verified TWO independent ways at this sha:
  (1) `git grep xtask` across ALL of .github/ returns ONLY comment mentions (bench scripts,
      ws272-w0.py). No workflow invokes it. Three workflows exist: ci.yml, golden.yml, release.yml.
  (2) Audited EVERY `run:` in ci.yml: the only external script is ./traceable-reqs (check + lint);
      everything else is an inline block or a direct cargo command (build translate_proof_fixture,
      nextest --workspace -E 'kind(lib)+kind(bin)', clippy). No `cargo run -p xtask`.
  RUNS in CI: the four synthetic unit cells (xtask is a bin crate, so nextest executes them).
  DOES NOT RUN: brainread::check(repo_root()) — the real-tree enforcement.
  CONSEQUENCE = the exact regression the guard was commissioned to prevent: tidy the nine
  explicit-None sites back to brain.call_deadline() and unit cells pass (synthetic text),
  traceable-reqs passes (tags intact), clippy passes. Green tree, hazard restored.
  ALSO UNSETTLED BY IT: check() walks all of crates/ INCLUDING brainread.rs, whose own string
  literals contain read_event. The tokenizer must skip string contents or the guard reds on
  itself. Cell 3 proves it for RAW strings; :186/:189/:355 are ordinary quoted strings. Running
  the gate once on the real tree is what proves it — and nothing does.
  NEEDS: one line in ci.yml in a per-PR job, or doyle ruling the gap accepted with a reason on
  the record. The check gates the run; here the check is what is missing.

## v0.69.0 CLOSE-SWEEP REGISTER — items I OWN at milestone close
1. WAN reply-budget RENEWAL coverage, cases 2-4 (doyle ruled it here, NOT todlando's lane;
   hertz confirmed. Case 1, silence-times-out, is ALREADY covered by wan_reply_bound.rs —
   do NOT duplicate it):
     (2) unrelated-stream traffic cannot renew the budget
     (3) matching-stream progress can extend the exchange beyond the initial deadline
     (4) stalled progress eventually times out
   Context: after the merge takes #289's side in all six wan.rs blocks, the surviving shape is
   the guarded re-arm at wan.rs:353 — `if stream_id == opened.stream_id { deadline =
   reply_read_deadline() }`. Nothing exercises that guard in either direction today.
2. The static-audit EXCLUSION of the six WAN sites must be recorded EXPLICITLY and must NOT
   imply the renewal behaviours are tested (hertz, binding). Excluded-from-guard AND
   untested-behaviourally is the combination that leaves nothing checking them, so the
   exclusion note has to say so in words.
   hertz's reason for excluding rather than extending the guard, worth carrying: the tokenizer
   is not a control-flow proof — finding a stream-id equality NEAR an assignment cannot
   establish that it guards EVERY renewal, and extending it that way risks FALSE ASSURANCE.
3. REQ text amendment (hertz's shape, better than my proposal — mine would have weakened every
   reply-wait): ordinary Brain RPC waits retain ONE FIXED deadline; WAN stream replies use the
   REQ-WAN-REPLY-BOUND progress policy, renewed only by data on the matching stream. Unrelated
   frames renew NEITHER.

## CORRECTION TO MY OWN #217 WRITE-UP (severity was inflated)
`xtask check` IS invoked — golden.yml:619 (Linux) and :638 (Windows), via .github/bench/wrap.
ci.yml has ZERO xtask invocations (re-measured with -c, no pipe). So:
  ENFORCED at golden, on both OSes. NOT enforced in the thin lane.
  My "green tree, hazard restored" scenario was WRONG: a tidied-back feed IS caught, at golden.
  The real gap is thin-lane LATENCY — a regression rides green PRs until golden, costing a
  cycle rather than shipping a defect. #216's changelog drift is that gap made concrete.
CAUSE: `git grep 'xtask' -- .github/ | head` cut at ten lines; nine bench/ci COMMENT hits filled
the window and golden.yml sorted below the cut. I then called it "verified two independent ways"
— but the second pass audited only ci.yml's `run:` lines, a NARROWER proposition. Two checks
corroborate only when they test the SAME statement; one sound narrow check plus one bad wide
check read as strength and were not.

## ASSEMBLY HEAD e9fa4d7bbacb47b4edbe61bc88cbc9acb6ed2d60 — PRE-VERIFIED (not gated)
branch assembly/v0.69.0, also gate/head1. Parents: 48a7d2e5 (de5a44bc + #289 6c0fa00b) and
9d718719 (#293). Found by me from doyle's merged-sha mention, not handed over.
  ✓ wan.rs BYTE-IDENTICAL to #289's — blob 785679c839d450cff784320e32cd4fe4a2ef2a16 at BOTH
    6c0fa00b and the head. Verified by blob hash, not by reading a diff.
  ✓ zero retired `.read_event(` call sites, zero decls. One PROSE mention at tests/resume.rs:118
    (`.expect("resume read_event (no gap-reject)")`) — does NOT match `.read_event(` because of
    the space, so doyle's wording was accurate; #217 commit 1 converts it.
  ✓ required_stages [doc,impl,int] all covered (doc 1, impl 46, int 2). `unit` rides #217.
  ✗ doyle's "still 52 impl tags" is WRONG: it is 46. wan.rs held SIX BRAIN impl tags at 9d718719
    and holds ZERO at the head; 52-6=46 exactly. The resolution is what removes them — they were
    inside the 52 being counted, so it cannot preserve both the resolution and the count. wan.rs
    now carries 13 REQ-WAN-REPLY-BOUND occurrences instead. Head is FINE (treqs needs >=1 per
    declared stage); the hazard was purely the ACCEPTANCE NUMBER producing a false red.

## GATING STANDARD FOR THE FINAL HEAD (hertz, binding — supersedes any carried count)
Do NOT carry 46 or 52 forward. #217 ADDS audit evidence (its gate fn carries [impl->] and its four
predicate cells carry [unit->]), so the count moves again, and the REQ gains a `unit` stage.
AT THE FINAL HEAD: report the SHA-SPECIFIC census and EXPLAIN each addition and removal. Gate on
VALID EVIDENCE and the INTENDED CONTRACTS, never on a stale numeric threshold.
Generalises my own finding: a tag count is sha-specific by construction, so any count carried
across a merge or a landing is stale the moment it is quoted.

## #217 census sibling — GATED GREEN. sha 1ebd03dcd66fcc794ed86b16cefb88621f01f045
NOTE: #217 is a CHAIN ELEMENT, not one of the 8 greenlit members. Gating it does NOT advance the
8-count; the member ledger stays 2 of 8.
  - PR #217 headRefOid == the sha exactly; OPEN, MERGEABLE, base main. Trailers 2/2 space spelling.
  - run 34424166884: sha matches, attempt 1, status completed, conclusion SUCCESS — read in ONE
    command. 5/5 jobs green, ALL FRESH (attempt 1 has nothing to carry).
      traceability 01:07:54->01:08:06 · changes 01:08:08->01:08:14 · lint 01:08:17->01:10:10
      unit Linux kitsubito 01:10:12->01:15:33 · unit Windows hfenduleam 01:08:17->01:34:47
  - COMPLETE GRAPH at this sha: ci.yml has 4 job keys (changes, unit, lint, traceability) with
    unit a 2-cell matrix = 5. Nothing skipped, nothing unstarted behind a needs:.
  - ACCEPTANCE ARM 1 (mine): lint log at 01:10:06.5954548Z carries
    "BRAIN_READ_AUDIT_OK: 501 crate Rust files; nine feeds + attach explicit None; four reply
    controls; zero retired reader symbols" — the enforcement executing in the THIN LANE.
  - ACCEPTANCE ARM 2 (doyle's measurement, recorded by hertz): clean exit 0; MUTANT
    (serve_registry_feed explicit None -> call_deadline, mutation LANDED) exit 1 with BOTH
    predicates firing on the one site (dispatch.rs:1351 body sweep + :1327 named control) and
    SIBLING FEEDS SILENT; restored exit 0, same OK line. The silent siblings are the part that
    proves discrimination rather than blanket reddening.

## HEAD 2 = 79ac8d04 (refs/gate/head2), tree c847ce758fc5f074ff440ed1cb6a9c3a804776a3
Tree hash VERIFIED against doyle's claim — matches exactly.
Delta c7aa5b15..79ac8d04 = the IR-92 register rider (PR #215 @df024887), DOCS ONLY:
  docs/INFRA-REGISTER.md +82, GATE-W2-272-CHECKLIST.md +20. Zero code.
doyle's compile gate on HFENDULEAM 01:46Z: clippy 0 warnings; BRAIN_READ_AUDIT_OK (502 files,
+1 vs 501 — consistent with the docs-only add NOT changing .rs count... CHECK THIS at hand-off,
502 vs 501 means a .rs file appeared somewhere and the delta above says docs only);
full xtask check exit 0; nextest -p xtask 108/108 one Summary; treqs exit 0.
Head remains PROVISIONAL — six members outstanding, no hand-off.

## v0.69.0 RELEASE NOTES — AGREED TEXT (rev 5; todlando + hertz both accepted 2026-09-10 ~02:03Z)
Draft-accuracy review closed. NOT release acceptance. Lands in the tree via the ASSEMBLY head's
release-notes change (doyle owns that edit); #281's sentence in particular goes there, NOT in the
frozen member branch 0966ed71.

### Fixed
- Cross-node messaging now recovers on its own instead of stalling until the service is
  restarted. Previously, one unanswered request could stop this node from advertising itself
  and reconnecting to peers, until other nodes could no longer reach it.                  [#293]
- Sending a message to an agent on another machine no longer waits without limit when the far
  side accepts the connection and then never answers. Previously, such a send could hang
  indefinitely without reporting why.                                                     [#289]
- Persistent shells now restart automatically after the background service restarts, once their
  owning agent is online. Previously, eligible shells could remain offline until relinked by
  hand.                                                                                   [#287]
- A successful `spt shell relink` now reports `binding` while it waits for its handshake,
  instead of a successful launch reading as `offline`.                                    [#287]
- Agents on other machines that were already known are now remembered across a restart of the
  background service, rather than disappearing until peers advertise them again.          [#281]
- Service status and successful update completion now say when the running network layer is too
  old to serve node-prefixed documentation and serve controls, that loading them needs a full
  service restart, and that the restart stops hosted sessions. Successful updates no longer
  unconditionally advise restarting the service.                                          [#292]
- Stale-session cleanup now refuses to stop a process whose identity differs from the recorded
  session, or cannot be verified.                                                         [#285]
### Internal
- Reduced repeated connection open/close records in the background service log.  [#286 PROVISIONAL]
- [#295 — bullet unwritten; in scope, queued after #286.]

BOUNDARIES THAT COST REVISIONS — do NOT relax these when re-editing:
- #292: NO annotation or refusal shipped on the documentation address. A 404 there STAYS a 404.
  The note says "say when", never "now works". And the last sentence is about what was REMOVED
  (an unconditional instruction), NEVER about detecting when a restart is needed — an unanswered
  version query leaves that open.
- #285: NOT "no longer can/risks". broker.rs:447-450 compares birth identity then separately
  calls kill_tree(pid), so a check-to-kill window remains. doyle endorsed the stronger form from
  commit SUBJECTS and RETRACTED after the builder read the code.
- #281: claims REMEMBERING only. Not prune (outside 0966ed71), not reachability, not end-to-end
  user-message classification (the 29-test proof did not exercise it).
- #287: "restart automatically ... once their owning agent is online", "eligible shells" — a
  launch can still fail, so no unconditional "return".
- #289: "indefinitely without reporting why", NOT "until the other process exited" — that was ONE
  measured instance (golden 34239258523), not the only way the wait could end.
- #286: NO post-fix volume figure. None has been measured.

MY ERROR CLASS THIS ROUND, three bullets one defect: I kept converting "X no longer happens" into
"the system now knows when X is unnecessary" (#292 restart advice, #285 "no longer can", #289 sole
escape). Claiming a capability from the absence of a behaviour. Watch for it at the tag.

## #295 FORM ESCALATION — CLOSED, discharged correctly
Raised because #295 was greenlit but unimplemented, and my intake rule refuses a head that ships
7 of 8 while the board says 8. doyle dispatched it to todlando 02:00:47Z, live-IPC PID design
ruled and accepted, queued after #286. IN SCOPE, not dropped -> no reason comment and no
relocation owed. 8-set intact.

## MEMBER BRANCHES PUSHED (frozen for doyle's gates) — my static pre-verification, all PASS
  #292 fix/292-resident-skew      111568f245780615969f6d632771d53b4291d103  1 commit
  #281 fix/281-registry-hydrate   0966ed715e036a9ea5a984f5b96accec6083e9cc  1 commit
  #285 fix/285-zombie-identity    9d1dcf90676cbddab5845daa481a514dc380c0b0  2 commits
  #287 fix/287-persistent-restore fb18e94bd70f3551a8ae6457f455b455fb7c6720  2 commits
All four: de5a44bc IS ancestor; every commit carries exactly one space-spelling co-author trailer
(raw body grep). #286 candidate 19a90979 on fix/286-daemon-stderr, unpushed.

## #285 — SHA SUPERSEDED AND ITS RELEASE SENTENCE REWRITTEN (both after revision 5)
SHA: 9d1dcf90 -> fc5887b147ef313401b37c1047328f90fe1029da. My pre-verification of 9d1dcf90 is
STALE; the new one re-verified: de5a44bc ancestor, THREE commits (88d5cb9e verify spawn identity,
9d1dcf90 collect exited child status, fc5887b1 retire recycled roots), one space-spelling trailer
each. doyle CLEARED it after a full read.
WHY THE SENTENCE CHANGED: doyle's gate question was "identity-mismatch refused = permanent wedge".
Ruled shape (a): a RECYCLED birth clears the stale row and stamps WITHOUT signalling; only
UNPROVEN declines. That splits ONE refusal into TWO outcomes, and both the lane's CHANGELOG entry
AND my revision-5 bullet still described them as one.
⚠ THE MEMBER'S OWN CHANGELOG HUNK IS IDENTICAL AT 9d1dcf90 AND fc5887b1 — the fix moved, the entry
did not. The branch stays frozen; the assembly scope commit replaces it, same rule as #281's
missing entry.
FINAL TEXT (mine, confirmed by doyle from the code, ACKed by todlando who wrote it):
  - Stale-session cleanup no longer signals a process whose identity does not match the recorded
    session; the stale record is cleared instead. If the identity cannot be verified, the request
    declines and leaves the process alone.
todlando ACK: "if the identity cannot be verified" covers BOTH Err causes (pid-unknown AND
identity-unproven); no extra wording needed.
CODE BACKING, verified by me at fc5887b1: enum ZombieReap{Absent, Killed, Recycled{recorded,
observed}} broker.rs:428; two Err("identity-unproven") paths :461 and :463; spawn gate :8165
Recycled -> SPAWN_ZOMBIE_REAP_RECYCLED then falls through, :8173 Absent|Killed -> existing reap,
:8182/:8190 the two DECLINE sites; unit table :10264-10272 covers all four shapes.
STRONGEST EVIDENCE was the author's own doc comment at :434-436 — "A dead root or a different
birth proves the remembered root is gone and permits record cleanup WITHOUT signaling its
remembered number." The user sentence restates the code's STATED INTENT, not my reading of its
behaviour.
MY ERROR IN THE WRITE-UP, corrected by todlando: I described :461 as a recorded birth with no
observation. It is the reverse — an OBSERVED LIVE PROCESS WITH NO RECORDED BIRTH. Release wording
unaffected; the record should be right anyway.

## ⛔ CENSUS BASELINE — THE CANONICAL EIGHT. THIS SUPERSEDES REVISION 5. Compare against THIS.
hertz's point, and it would have bitten me: my hand-off check said "compare against revision 5",
but revision 5 is now STALE in three places. Censusing against it would flag CORRECT text as wrong
for #285 and #286, and would have no standard at all for #295.
  #285 — CHANGED after rev 5 (its FIX changed shape; the two-outcome sentence replaced the
         one-refusal sentence). ACKed by todlando, confirmed from code by doyle and by me.
  #286 — CHANGED after rev 5 (the new one-line Internal replacement supersedes rev 5's wording).
  #295 — DID NOT EXIST in rev 5 (explicitly unwritten). Now final, verbatim from its member entry.
The other five are unchanged from rev 5.

### Fixed
- Cross-node messaging now recovers on its own instead of stalling until the service is
  restarted. Previously, one unanswered request could stop this node from advertising itself
  and reconnecting to peers, until other nodes could no longer reach it.            [#293 rev5]
- Sending a message to an agent on another machine no longer waits without limit when the far
  side accepts the connection and then never answers. Previously, such a send could hang
  indefinitely without reporting why.                                               [#289 rev5]
- Persistent shells now restart automatically after the background service restarts, once their
  owning agent is online. Previously, eligible shells could remain offline until relinked by
  hand.                                                                             [#287 rev5]
- A successful `spt shell relink` now reports `binding` while it waits for its handshake,
  instead of a successful launch reading as `offline`.                              [#287 rev5]
- Agents on other machines that were already known are now remembered across a restart of the
  background service, rather than disappearing until peers advertise them again.    [#281 rev5]
<!-- [doc->REQ-RESIDENT-WEB-SKEW-DIAGNOSIS] -->   <-- TAG MUST RIDE THIS BULLET
- Service status and successful update completion now say when the running network layer is too
  old to serve node-prefixed documentation and serve controls, that loading them needs a full
  service restart, and that the restart stops hosted sessions. Successful updates no longer
  unconditionally advise restarting the service.                                    [#292 rev5]
- Stale-session cleanup no longer signals a process whose identity does not match the recorded
  session; the stale record is cleared instead. If the identity cannot be verified, the request
  declines and leaves the process alone.                        [#285 POST-REV5, todlando ACK]
- Service status now reports the process id of the running service, taken from the running
  service itself; a recorded id that no longer matches is marked stale. Previously, status
  could display an obsolete process id from a file.       [#295 verbatim from member 9547cd49]
### Internal
- Daemon logs now summarize healthy connection activity once a minute instead of recording
  every open and close.              [#286 POST-REV5, PROVISIONAL until both legs green]

CENSUS AT HAND-OFF — four checks, unchanged in shape, corrected in baseline:
 1. every [Unreleased] bullet matches the eight above (NOT revision 5)
 2. the [doc->REQ-RESIDENT-WEB-SKEW-DIAGNOSIS] tag is still attached to #292's bullet
 3. the [0.68.0] section is byte-identical to head 3's
 4. read all four from `git show <head sha>:CHANGELOG.md` — the committed OBJECT, not the worktree
    (doyle asserts pre-commit on the working tree; different layer, and his own resolver assert
    failed on CRLF tonight, which is exactly the class of difference between the two)

## ⚠ CENSUS CHECK 2 CORRECTED — the doc-tag blast radius is TWO tags, not one
I told doyle at head 3 that exactly ONE treqs tag sat in [Unreleased] (#292's). TRUE AT HEAD 3,
and it goes stale as members merge. Full census of every member's CHANGELOG hunk:
  #292 111568f2 -> [doc->REQ-RESIDENT-WEB-SKEW-DIAGNOSIS]      (already in the head)
  #286 19a90979 -> [doc->REQ-CONN-HEALTHY-LIFECYCLE-BOUNDED]    (ARRIVES when #286 merges)
  #281 #285 #287 #295 #293 #289 -> none
Both REQs carry 2 doc tags total, 1 of them in CHANGELOG, so losing either leaves 1 and treqs
STILL PASSES. Same quiet failure as before: it does not red, it silently halves.
EXTRA SURGERY ON #286: its tag rides a THREE-sentence entry under ### Fixed, and my replacement is
ONE line under ### Internal. So that tag has to MOVE SECTIONS with its bullet, not just survive in
place the way #292's does.
CENSUS CHECK 2 RESTATED: BOTH doc tags present in [Unreleased] at the final head —
[doc->REQ-RESIDENT-WEB-SKEW-DIAGNOSIS] on #292's bullet in Fixed, and
[doc->REQ-CONN-HEALTHY-LIFECYCLE-BOUNDED] on #286's line in Internal.

## #286 GATED (both legs) — static half mine, verified
19a9097956de0db898eaeb3a7dc4765189ade874, tree 6f8f59c6c889bc81772ffac0cf0a3cd21bcc0068, IS the
remote tip of fix/286-daemon-stderr by ls-remote, de5a44bc ancestor, one commit, one space-spelling
trailer. New REQ-CONN-HEALTHY-LIFECYCLE-BOUNDED declares [doc,impl,unit] and carries 2/4/3 — every
declared stage covered. doyle's legs: Linux 3128/3128 one Summary + clippy 0 + treqs 0; Windows
964/964 + clippy 0 + treqs 0. Its Internal line is now FINAL in the canonical eight.

## ⚠ #287 fb18e94b IS PROVISIONAL — my pre-verification of it may be STALE
todlando 2026-09-10 ~02:52Z: "#287 remains pending the close-failure respin proof; holding builds
until LOAN OPEN." So fb18e94b may be superseded the way 9d1dcf90 (#285) and 0f7e2e28/d79831d1
(#293) were. My static pre-verification of fb18e94b (de5a44bc ancestor, 2 commits, trailers 1,1)
is bound to THAT sha and does NOT transfer. Re-run it against whatever doyle gates.
PATTERN THIS MILESTONE, worth carrying: FOUR member shas have moved under me so far —
#293 0f7e2e28 -> d79831d1 -> 9d718719, #285 9d1dcf90 -> fc5887b1, #217 05e96e11 -> 1ebd03dc, and
now #287 likely. NEVER report a member's static half without naming the sha it is bound to, and
re-verify on every supersede rather than carrying the earlier reading forward.

## SAME-FORM VERIFICATION at head 9 (578ad38b) — EVIDENCE COMPLETE, ONE AGREEMENT OUTSTANDING
Greenlit form cited = comment 5610035178 folded with delta 1 comment 5610127841 (ADD #295).
ALL EIGHT MEMBERS IN THE HEAD, each a named merge's SECOND PARENT (not a PR-body listing), and
each independently confirmed by merge-base ancestry against head 9:
  #289 6c0fa00b via 48a7d2e5 · #293 9d718719 via e9fa4d7b · #292 111568f2 via 0acbe7fe
  #281 0966ed71 via 80be305e · #285 fc5887b1 via 24fdf006 · #286 19a90979 via 379b80f1
  #295 9547cd49 via 88f91077 · #287 53f63c3a via 117d706d
RIDER: IR-92 df024887 via 79ac8d04 — rides as the form specifies.
SUPPORTING CHAIN ELEMENT, NAMED NOT FOLDED (todlando's wording): #217 census guard 1ebd03dc via
d9db9ff3. NOT a ninth member and NOT an added request — it is enforcement/regression evidence for
member #293's OWN requirement (REQ-BRAIN-READ-BOUNDED-PER-CALL gained its `unit` stage there and
the guard carries that REQ's [impl->] and [unit->] tags). Greenlit member count stays EIGHT, so no
reason comment and no relocation are owed.
AGREEMENTS: hertz EXPLICIT ✓ · todlando EXPLICIT ✓ · doyle OUTSTANDING (his queue has been
QUEUEING all evening — absence here is possibly delivery, not assent).
⛔ I RETRACTED "silence = agreement" after hertz called it: silence from a busy, queued or
unaware peer renders identically to assent, and I had built that into the one check whose purpose
is that nothing rides unexamined. FORM IS NOT RECORDED VERIFIED UNTIL DOYLE SAYS SO EXPLICITLY.
Also disclosed to all three: my reading favours a lane I created by refusing to gate #293's guard,
so I am the last person whose unchallenged word should settle it.

## GOLDEN RUN PROCEDURE — read from golden.yml at head 9, so it is not reconstructed under pressure
TRIGGERS (golden.yml :6-14): push to branches `golden/**`, OR workflow_dispatch with a boolean
input toggling the two-host seam ("disable only when intentionally isolating other golden
evidence" — so leave it ON for a real golden).
JOB KEYS, 6: changes · test · twohost-b · twohost-a · traceability · notify.
  -> the complete-graph check at golden is against THESE SIX plus whatever matrix cells `test`
     expands to. Do not assume 5 the way ci.yml does.
⛔ PUSH THE OBJECT, NEVER A BRANCH NAME (banked hazard, cost this project a golden at a stale tree):
  git push origin <FULL-40-SHA>:refs/heads/golden/<lane>
  then VERIFY BEFORE reading any run id:
    - `git ls-remote origin refs/heads/golden/<lane>` returns that exact 40-sha
    - the remote ref's TREE matches the head's tree
    - record BOTH, plus the sha, BEFORE the run id exists
  A hand-tracked branch is a snapshot of the last assembly it was moved to; `branch --contains`
  coming back empty is a FINDING, not a formality.
AT THE RUN: read `run_attempt` in the SAME command as the conclusion; jobs at
/attempts/<n>/jobs; never bind a terminal check to `status == completed`. Carried vs fresh is
decided by `started_at` vs THAT ATTEMPT's `run_started_at`, never by run_attempt (relabelled).
RED GOLDEN -> hands straight back to doyle for RCA-first triage per the intake runbook. I do not
triage it myself.
