---
name: rc-render-truth-progress
description: "RC-RENDER-TRUTH milestone — operator GO 2026-07-18; triage main @9cce22d (ADR-0042/0043/0044, KH 7.46-7.48, 13 REQs); W1 dispatched to todlando; W2 lease, W3 render queued."
metadata: 
  node_type: memory
  type: project
  originSessionId: a22952c3-910b-4b6e-8504-e0f3c46c237e
  modified: 2026-07-22T00:28:28.738Z
---

**RC-RENDER-TRUTH — ACTIVE MILESTONE (operator GO 2026-07-18: plan + build + drive to release publish).**

**v0.38.1 FAST-FOLLOW WAVE (W4) — IN FLIGHT 2026-07-18/19.** hertz v0.38.0 field verdict: 4 legs PASS, 1 "FAIL" later RECLASSIFIED NOT-A-DEFECT (see ruling v3), 2 repros traced. todlando was DOWN (their own perch = the immortal-hybrid field evidence) — doyle brought them up fresh (session b785f40) after hertz released the state; branch build/rc-render-truth-w4-v0381.

**THE RULING-V3 SAGA (binding lesson):** hertz's FAIL leg (plain same-node rc never reaches the W2 ladder — client current_driver guidance blocks it because loopback attaches stamp driven_by=own-hex) was first ruled a defect → REQ-DRIVEN-BY-OWN-NODE-NORMALIZE minted (normalize own-hex→None at stamp). Operator/hertz CORRECTED: plain rc refusing a controlled endpoint IS the design; --take = opt-in. Operator ordered CONTEXT.md verify → CONTEXT:382-389 decisive (:386 "Control to a CONTROLLED endpoint is refused with guidance — never silent-displace"; driven_by = controller NODE, no remote-only qualifier; same-by successor re-take = recovery carve-out only). RULING V3 (main @ebb5c9c REQ rewrite + @7b524d0 ADR-0044 note): v0.38.0 shipped behavior CORRECT; own-hex latch TRUTHFUL; normalization WITHDRAWN; leg 1 = cosmetics/truth only (own-node guidance copy "controlled from another window on this machine", stamp-comment + KH 7.15 reconciliation, refusal pins incl --view/--take bypass); ladder untouched at recovery seams (reconnect/re-serve enter below the client gate). LESSON: doyle must CONTEXT-ground every design-fork RULING, not just gates — the ladder ruling missed :386.

**W4 legs:** L1 guidance-copy/comment truth — **✅ REWORKED @bd858b7 + doyle SOURCE-READ PASS**: normalization ABSENT (stamp_driven_by back to plain controller_by() passthrough, unit flipped to latches_own_node_hex_verbatim_like_remote asserting Some(own_hex), driver_phrase names own-node "another window on this machine", pre_broker_busy_guidance fires for ANY driver, info.rs docs reconciled to CONTEXT:386). Coherence traced: client own_hex(nodeid) == broker local_node_hex == loopback attach `by` = single local nodeid, so driver_phrase actually matches own-node. L2 REQ-RC-SINGLE-PUMP-BRAIN — **✅ impl @4ddd5a2 + int @f5b3d6b + doyle SOURCE-READ PASS**: into_brain carry sound (None on every probe-skipping path incl reconnect/reheal, fresh resolve on carried conn), int asserts PUMP_IPC_READER==1 in offline_row_over_live_session_attaches. L3 REQ-HOSTING-AUTHORITY-CONTROLLABLE — **✅ BUILT @98323be** (controllable=Some(true)=broker-PTY authority; restart_resume_gate drops state arg, keys online+controllable+belts; reconcile routes non-live+controllable!=true→PID-model, controllable=true→broker-session truth; cmd_bind Option-B online-earn on persisted controllable + manifest param removed; ADR-0041 amendment note = the topology split; 4-case int matrix i-iii endpoint_survival + iv startup; endpoint_survival reclassified HEAVY ×3 = latent miscategorization). Display sweep (leg-1 fold) **✅ @bbdbe39**: shared roster::is_own_node_hex predicate; picker control_line "controlled locally" via EndpointRow.driven_by_is_self (driven_by STAYS populated → View+Kick still offered); reporting derive_attached_node self-attributes own-node; per-surface units; secondary remote-only model-claim comments reconciled. **PREFLIGHT: clippy workspace 0, traceable EXIT 0 no-findings, xtask OK, targeted+reconcile-adjacent+int-matrix nextest ALL GREEN; full Phase-A light suite running.** Pushed origin. GATE-READY — pinged doyle for whole-branch isolated battery.

**⭐ DOYLE WHOLE-BRANCH GATE @622eb84 IN PROGRESS 2026-07-19.** SOURCE-READ COMPLETE — PASS all 6 commits: L1 bd858b7 (normalization absent), L2 4ddd5a2/f5b3d6b (single-pump carry), display bbdbe39 (shared roster::is_own_node_hex; reporting derive_attached_node own-node self-attributes {self_label,self_key}; view control_line "controlled locally" via driven_by_is_self, driven_by STAYS populated → View+Kick preserved), comment sweep 32e3533 (CONTEXT:386 reconcile, 2 survivors subnet/Wake legit), L3 98323be (restart_resume_gate drops state arg keys online+controllable+belts; reconcile routes state!=live && controllable!=Some(true)→PID-model else fall-through to broker-session truth block :773-820 which terminal-offlines sessionless controllable+dead-custody, NO Psyche in reconcile=ready stays no-Psyche; cmd_bind Option-B reads-back persisted controllable else BIND_ONLINE_REFUSED; establish_perch:379 rec.controllable=controllable.or_else(prior) NEW-ARG-WINS so case iv holds; int matrix i real-broker resume + ii pure reconcile offline; ADR-0041 amendment note = faithful ruling render), B2 622eb84 (stale "ready ignored" assertion updated: re-seeded controllable=Some(false) live-pid listener stays online, controllable=true offline moved to endpoint_survival ii). 3 flags assessed OK: endpoint_survival HEAVY reclassify byte-identical all 3 strings (nextest.toml+ci PhaseA-neg+PhaseB, alpha slot endpoint_lifecycle|endpoint_survival|handoff, partition preserved); manifest param dead removed (clippy --all-targets GREEN confirms 11 call sites); driven_by_is_self cli.rs false benign (only feeds display_status which ignores). BATTERY run 1: clippy --workspace --all-targets GREEN (0, 1m16s) + traceable EXIT 0 no-findings = source+ALL test targets compile, all REQs satisfied. BUT build+nextest EXIT 101 = rustc INCREMENTAL ICE (STATUS_STACK_BUFFER_OVERRUN 0xc0000409) on ~10 test crates (controller_lease/twohost/wanmsg/input_ack_deadlock/live_adapt_*/shell_*/trial_drain/live_bind_firsthost/list_json_parity) + rlib-not-found knock-on (swarm_discovery/papaya/seize) — the KNOWN Windows incremental gotcha (memory-documented), NOT code (clippy --all-targets already compiled them clean). RERUN 2 (incremental off): hit DISK FULL — LNK1180 out-of-disk (C: 1.9T 100%, 2.5G free), mass link fail ~12 crates. NOT code (hfenduleam-disk-full-ci class). Reclaimed 29G stale gate-2a110ee-target (orphaned prior-gate target in claude temp root) → 32G. RERUN 3: reused poisoned target → LNK1285 corrupt PDB (rc_attach_truth.pdb, truncated by run-2 disk-full mid-link). UNPOISON: deleted debug/deps/*.pdb + incremental (kept .rlib deps) → freed 25G of debuginfo=2 PDBs → 38G free. Swept 7 orphaned worktrees (4 still pinned: gate-73b29b8/ad7fde8/c3eb3da/f4727cd — retry). DECISION: full --tests --workspace regenerates ~25G PDBs → would disk-full AGAIN (box can't host a 2nd full clean build). PIVOT to SCOPED clean-artifact gate = entire W4 change surface + composing substrate (spt-daemon+spt lib units [B2/restart_gate/reconcile_routing/stamp_driven_by/cmd_bind/picker/reporting/rc/roster] + int endpoint_survival/rc_attach_truth/controller_lease/driven_by_selfheal/endpoint_lifecycle/redispatch_stall/render_lifecycle/bind_*_e2e/run_no_dup/livehost_bootgate/list_json_parity), bg task bs4jilq8k log scratchpad/gate-622eb84-scoped.log. GATE-EVIDENCE CHAIN (disk-realistic, rigorous): source-read PASS(6 commits) + clippy --workspace --all-targets 0 (clean checkout = FULL compile incl all test targets) + traceable EXIT 0 + scoped-clean-runtime + todlando full-suite preflight 1803/1804(1 fixed). ✅ SCOPED GATE PASS: 597/597 tests (4 leaky = benign brainproc known-class, not W4), NEXTEST_EXIT=0. WHOLE-BRANCH GATE VERDICT = **PASS** @622eb84. Evidence chain: source-read PASS(6 commits) + clippy --workspace --all-targets 0 (clean checkout=full compile) + traceable EXIT 0 + scoped-clean-runtime 597/597 (W4 surface+substrate: endpoint_survival L3 matrix, B2/restart_gate/reconcile_routing units, L1 stamp_driven_by, L2 rc_attach_truth, cmd_bind e2es, display units, controller_lease/redispatch_stall/render_lifecycle/driven_by_selfheal) + todlando preflight 1803/1804. DEPLOYAH v0.38.1 PATCH GO SENT (queued) 2026-07-19: branch build/rc-render-truth-w4-v0381 @622eb84, counter-from-published(last 66), bump-in-PR, end-user CHANGELOG 3 surfaces (own-node "controlled locally" not raw hex; no doubled pump banner; spt-hosted-over-listener stays online+resumes across daemon restart, dead hybrids don't linger). CLEANUP PENDING: gate worktree .worktrees/gate-622eb84 + scoped target (scoped-kill leaked daemons first); 4 still-pinned orphan worktrees gate-73b29b8/ad7fde8/c3eb3da/f4727cd retry later. NOTE: hfenduleam chronically disk-starved (1.9T 99% even post-reclaim) — todlando's "Phase-A re-run killed" likely disk too; SEED for backlog: box needs disk hygiene (stale gate targets accumulate 15-29G each in claude temp + orphan worktrees). Pinned worktrees to sweep post-gate: .worktrees/gate-622eb84 (+ earlier gate-c3eb3da,fix-main,fix2/3-main if still present).

**⭐ DOYLE GATE FINDING (source-read, RESOLVED @bbdbe39) — own-hex driver mis-renders on DISPLAY siblings; IN-SCOPE v0.38.1, folded under leg 1; handed to todlando (scratchpad gate-finding-ownhex-display.txt).** Post-W1 the own-hex latch is truthful (ruling v3) but only rc.rs learned to humanize it (driver_phrase). Two sibling surfaces still read own_hex as a REMOTE driver and print raw 64-char hex: (1) picker/view.rs:558 control_line `Some(node)=>"controlled by {node}"` → "controlled by <64hex>" not "controlled locally" (display_status COLOR safe — model.rs:659 keys on driven_by.is_some()||controlled → still blue); (2) api/reporting.rs:894 derive_attached_node Some-arm → attached_node.key=own_hex, label=resolve_label(own_hex)=likely None (own node not in gossip registry) → endpoint-info shows null-label raw hex instead of self-attributing. REACHABLE = the exact hertz v0.38.0 FAIL field shape (same-node rc → serve_attach → own_hex); field re-verify screenshots picker → would read as rc-render-TRUTH regression. RULING: humanize own-hex at both surfaces mirroring driver_phrase (own==self → local/self-attribute); extend REQ-DRIVEN-BY-OWN-NODE-NORMALIZE title to name all own-node display surfaces + unit per surface (no int); SECONDARY reconcile stale "driven_by remote-only KH7.15" model-claim comments (picker model/view, registry.rs, registryhost.rs, reporting.rs, control_stamp_lifetime.rs) to CONTEXT:386; WATCH control_stamp_lifetime.rs:295 driven_by==None assert (confirm path not stale). NOT blocking L3.

**⭐ DOYLE RULING — cmd_bind online earn-predicate = OPTION B (CONTEXT+code-grounded, scratchpad ruling-cmd-bind-online-earn.txt; feeds L3 ADR-0041 amendment doc stage).** todlando's L3 tension: cmd_bind's "read persisted state, not the arg" clause vs case (iv) "spt-hosted bind over ready_agent => controllable=true+ONLINE+resumes". RULING: earn online on persisted **controllable==Some(true)**, NOT persisted state==live_agent. Grounding: (1) listen_online_gate (startup.rs:534-544) refuses live-capable-over-ready_agent to block controllable=FALSE *capability-only phantoms* — L3 case is controllable=TRUE = real broker-owned PTY (cmd_bind:746-748) = earned hosted state, HONORS ADR-0041 dec-1 spirit not violates it. (2) The immortal hybrid was UNHEALED not "born online"; todlando already fixed the heal (restart_resume_gate keys online+controllable; reconcile routes controllable=true→broker-session truth) so the row is now managed — online-ness was never the bug. (3) Option A (refuse online) = TRUTH bug: legit live bind persisted OFFLINE (contra CONTEXT:194 daemon-authoritative) + restart_resume_gate(keys online) Skips → STRANDS the bind. (4) leg thesis = controllable is authority; all 3 seams must agree. "Parity with cmd_listen" = the DISCIPLINE (earn from persisted record, never raw arg — fixes current arg-keyed stamp at startup.rs:785 = the birth seam), NOT a literal shared predicate; earn-predicate is authority-specific: listen=persisted state==live_agent (messaging, UNCHANGED), bind=persisted controllable==Some(true) (broker-PTY). IMPL: read-back persisted record post-establish_perch, stamp online iff controllable==Some(true), DROP arg-keyed endpoint_type test + psyche_init coupling FROM online predicate (psyche_init still gates Psyche-host at livehost:196, state==live_agent). INVARIANT: online signal == restart_resume_gate resume predicate (both key controllable → agree by construction, no online-but-unresumable perch). Case (iv) = REAL cmd_bind-drives-it e2e assertion (stronger than A's precondition-seed). ADR-0041 amendment substance: online-earn authority SPLITS by topology (listen=state, bind=controllable); same discipline, different hosting-authority datum; controllable=true ≠ the controllable=false phantom hole listen_online_gate closed.

**SHARED-CHECKOUT RACE (this wave):** todlando's REQ activation swept into doyle's @0f20d43 push → main check-red → doyle reverted @8973928 via detached worktree; activation rides the build branch. THIRD strike of the class today — branch-first is binding.

**⭐ GATE PASS @622eb84 2026-07-19 (doyle):** whole-branch build/rc-render-truth-w4-v0381 — 597/597 scoped clean-artifact tests (W4 surface+substrate; 4 leaky = benign brainproc known-class), clippy --workspace --all-targets 0, traceable EXIT 0, source-read PASS all 6 commits (both rulings landed faithfully, case iv holds via establish_perch:379 new-arg-wins). Runtime confirm SCOPED not full --workspace (hfenduleam disk-starved — a 2nd full clean regenerates ~25G PDBs + disk-fulls; scope covered every changed crate + composing substrate, clippy-all-targets covered full compilation; documented). Gate snags were TOOLCHAIN/DISK not code: rustc incremental ICE (cleared + CARGO_INCREMENTAL=0) THEN disk-full LNK1180 (stale 29G orphaned gate-2a110ee-target in claude temp; reclaimed) — see [[hfenduleam-disk-full-ci]] 2026-07-19 update. **todlando opened PR #32 (build->main) + notified deployah (v0.38.1 PATCH GO, counter 66->67, end-user CHANGELOG surfaces handed over) + asked doyle to merge #32 per W1-W3 pattern.** Build lane PARKED at merge.

**⭐⭐ v0.38.1 COUNTER 67 PUBLISHED @9ec831c 2026-07-19 (deployah) — Latest flipped, RC-RENDER-TRUTH W4 SHIPPED CLEAN, no release-lane snags.** kitsubito test passed clean (registry_lifecycle flake didn't fire, no rerun). CHANGELOG (end-user voice, doyle ruling): controlled-locally label + spt-hosted resume/dead-hybrid heal as Fixed; duplicate attach banner collapsed to ONE Internal line. Build @610027e → release @9ec831c. **ONLY hertz field re-verify from Latest remains to CLOSE the milestone** (banner==1, own-node reads 'controlled locally'+self-attributes, plain-rc REFUSAL expected, dead-hybrid heals+resumes, two-window probes).

**⭐ W4 BUILD LANE CLOSED 2026-07-19 — PR #32 MERGED to main @610027e (merge commit, per-leg tagged commits preserved).** All 3 legs + display sweep + comment sweep on main. Linux registry_lifecycle red PROVEN pre-existing (main @7b524d0 reds identical assertion registry_lifecycle.rs:371 — not W4, not the merge; seeded for registry-int-hardening: bounded-poll the oneway-rounds rig, in [[spt-core-findings-backlog]]). Remaining: deployah cuts v0.38.1 off main + hertz field-verify → milestone CLOSE.

**Remaining sequence:** ✅ BUILD CLOSED @610027e — deployah cuts release/v0.38.1 off main (bump-in-PR, tag on merge, counter 67) → hertz field re-verify (banner==1, own-node reads 'controlled locally'+self-attributes, plain-rc REFUSAL expected, dead-hybrid heals+resumes, two-window probes) → milestone CLOSE. Post-gate worktree sweep (doyle): .worktrees/gate-622eb84 + earlier gate-c3eb3da/fix-main/fix2/3-main if present. HISTORICAL: ✅ ALL 3 LEGS BUILT @622eb84 (L1 rework, L2 int, L3 hosting-authority) + display sweep + comment sweep, PUSHED, preflight-green, doyle PINGED for whole-branch gate → NEXT: doyle gates W4 (isolated worktree; verify normalization ABSENT, T6 + lifecycle substrate green, leg-3 4-case int matrix, own-node display humanization) → deployah v0.38.1 PATCH GO → hertz field re-verify (banner==1, hybrid heals+resumes, own-node reads 'controlled locally'+self-attributes, plain-rc REFUSAL expected, two-window probes) → milestone CLOSE. Pinned worktree dirs to sweep: .worktrees/{gate-c3eb3da,fix-main,fix2-main,fix3-main}.

**⛔⛔ 2026-07-21 (post-v0.39.3) — SECOND REOPEN: hertz POST-FIX RCA, field STILL RED with CLI+broker both 0.39.3, broker_stale=false. RCA ACCEPTED IN FULL, all cites doyle-verified own-eyes.** ROOT (source-certain, the code SAYS it): REQ-RC-RESIZE-GEOMETRY-EPOCH shipped a PARSE-MODEL barrier only — broker.rs ResizeTransition doc (:699-704) states append "still rings + fans out every chunk exactly as before" holding bytes ONLY from grid.advance; settle_before_resize doc (:1007-1008) repeats it ("only the grid parse is deferred"). So the LIVE controller/viewer path receives old+new-geometry differentials across an already-resized client viewport — the v0.39.3 capture (live attached view, width-1 ASCII deletion/merge/displacement) is exactly that surface. **CLASSIFICATION: REQUIREMENT-SCOPE defect — gate held against documented design; the REQ scoped the barrier to the wrong surface (doyle owns it). Cold-repaint oracle definitionally cannot see the live path.** SECOND WEAKNESS (confirmed, not the current driver): mark_resize_issued (:4934) BEFORE session.resize (:4935); 20ms-quiet/250ms-cap epoch split is a heuristic not an emission boundary — RESIZE_SETTLE_CAP eprintln (:1028-1032) admits old-geometry bytes may land in the new epoch. HERTZ DISCRIMINATOR DISCIPLINE KEPT: capture proves the shipped barrier missed the live surface; does NOT prove/disprove a no-resize second root — stays open, not assumed.
**FIX SHAPE (hertz 1-5 accepted as triage skeleton):** (1) PRESENTATION barrier — during transition keep ring recording but suppress/buffer controller+viewer raw Output delivery too; (2) epoch-replay held bytes into grid, land at target geometry, then ONE synthesized full-screen repaint at target geometry to every attached sink as the sync frame — never replay mixed-geometry raw bytes to clients; (3) repaint enqueued under the same OutputLog serialization before fanout resumes, size-notify/repaint ordering explicit for viewers; (4) regression drives the REAL live controller writer (independent terminal at client target geometry, full untrimmed row equality post-sync-repaint) — cold-repaint oracle insufficient by construction; (5) heuristic strengthening SEPARATE, only if cold model stays field-red after fanout repair. **BINDING GATE LEGS (hertz-enumerated, doyle-accepted):** explicit disposition for EVERY non-grid byte class dropped by repaint substitution (OSC title, cursor visibility, …) — enumerate at triage, rule defer-vs-drop each; cursor-of-record advances past suppressed frames as-if-written (repaint supersedes); resume-across-resize leg (ring still holds raw mixed-geometry bytes — resume-from-cursor must not replay the suppressed corruption back in). **SEQUENCING: displaces NOTIF-TRUTH as next triage (field-red live operator surface > GO'd-unstarted milestone). Doyle writes ADR amendment + REQ succession (presentation-barrier requirement), todlando builds, release note that claimed the fix gets quote/gap/closure correction in the shipping cut.** ⚠ LIFECYCLE SEAM: hertz answered directly — NOT YET RUN on 0.39.3 (their 0.39.0 exercise FAILED as expected, pre-fix; emphasys repro same). ⭐ HERTZ PREMISE CORRECTED (doyle grounded first): hertz believed REQ-LISTEN-PRESERVES-HOSTING-TOPOLOGY "awaits its implementation wave" — WRONG, it SHIPPED v0.39.1 (PR #44 fold, on main: HostingAuthority startup.rs:177-205, reap-survival broker.rs:1996/unit :6819) and is in their 0.39.3 binaries. Fixed-build bind→listen→control→detach run on 0.39.3 = the milestone's lifecycle-close leg, stands alone, does NOT wait on the new resize wave; hertz to run when convenient.

Triage main @9cce22d 2026-07-18. Three waves, one release. All legs doyle-seam-verified from hertz RCAs 2026-07-16..18 (see [[spt-core-findings-backlog]] entries for full RCA text). Plan of record: `docs/RC-RENDER-TRUTH-DISPATCH.md`.

- **W1 rc attach truth** (ADR-0042, KH 7.46) — **✅ GATED PASS + MERGED main @f9039df 2026-07-18 (doyle): full source read clean (all design calls accepted, OwnerDial sole-consumer verified, reconnect closure keys req_endpoint), CI FULL GREEN first try both platforms + both n1-gates, isolated-worktree confirm 311/311 (fresh target, env-scrubbed, zero leaks). PR #28 @f69f815.** Commits: 9107ea3 REQ flips (4×["doc","impl","unit","int"] + hazard ["doc","int"]; doc tags rode triage) / beae3ba impl+units / 4fc4df3 int+HEAVY / f69f815 doc-lint fixup. Preflight: units 6/6, int 6/6, FULL battery 1932/1932 FIRST TRY (9 leaky known class, 1 skip twohost), clippy workspace 0, traceable 538/0/0, xtask OK.
  **W1 MECHANICS (todlando's calls, flagged in PR body):**
  (a) L1: SessionProbe::session_truth tri-state (HonestLive/ClaimedZombie/Absent) + pure attach_gate BEFORE offline fast-fail; zombie → "defunct session" refusal, never attach never reap; falsified doc-comments rewritten same commit.
  (b) L2: spt-store resume_unbound_stamp (offline→UNBOUND, returns observed-sid rollback token) + rollback_unbound_stamp (CAS still-UNBOUND + same-sid); wired pre-launch in cmd_endpoint_run; rollback on spawn-fail AND the CreateConflict no-mutation arm. DESIGN CALL: stamp fires on ANY launch over an existing-offline perch, not only --resume (ADR: fresh/resume-invariant).
  (c) L3: harness-only preflight from BOTH carriers — pure harness_only_row (ONLINE-gated) + new wansend::resolve_visible_owner_instance (no-dial gossip resolve, own-node excluded, Active|Dormant refuse); truthful "online but harness-hosted" copy; stale-row guess stays for unknown ends. No old-copy assertions in tests/ci (grepped).
  (d) L4: canonical_wire_id on every machine surface (perch/probe/driver/local-resolve/AttachRequest); DESIGN CALLS: local-first + local-row gates PLAIN-target-only (a qualified spelling is the resolver's answer — no same-id local hijack of id@other); NEW OwnerDial::LocalOwner arm — qualified-local target attaches its LOCAL session (old own-node→NotFound false refusal; wansend unit updated).
  (e) Int: tests/rc_attach_truth.rs 5-row e2e matrix (HEAVY at birth ×3 strings) + in-crate rc::tests::qualified_targets_attach_with_bare_wire_id two-broker loopback-QUIC rig (FLAKE-LEDGER #14 override extended). True twohost remote leg NOT built (in-crate rig is the wire proof) — flagged.
  **RIG FINDING (seed, not built): `spt endpoint stop` terminal-normalizes the row offline but does NOT reap the live broker session → follow-up `run --resume` dup-guards ENDPOINT_ALREADY_LIVE over a "stopped" endpoint. Flagged to doyle.**
  Field evidence: hertz's organic pre-edit perri row `C:/Users/decid/.omp/state/spt-endpoint/perri-info.pre-unbound-manual.json` (perri's LIVE row is hand-edited UNBOUND — not evidence).
- **W2 controller lease truth** (ADR-0044, KH 7.48) — **✅ GATED PASS + MERGED main @0cb4833 2026-07-18 (doyle): source read clean (ladder exact, revoke authoritative+ordered incl Superseded arm, fence pure RC-scoped, guidance pinned; production gen mint verified = attach.rs now_ms() at viewport open — same-ms equal-gen edge noted acceptable), CI FULL GREEN first try, isolated-worktree 636/636 incl T6 unmodified + full redispatch substrate. PR #29 @c3eb3da. Gate-worktree dir pinned by handle post-prune — sweep at next gate.** Commits: e5798e4 REQ flips / efbdd67 impl+units / 6ddc72e int+HEAVY / 160cbcf merge of doyle's @222d8b5 ladder ruling / c3eb3da ladder fix + emphases.
  **THE LADDER SAGA (the milestone's first gate-ruling conflict):** first build shipped literal "distinct-lease Control = Busy" → FULL battery caught redispatch_stall T6 red (240s timeout, in-seam): stale replay wins freed slot → live replacement viewport (same by, newer gen, plain Control) Busy-locked behind a zombie-stream worker = fix-6 order-independence regression / post-restart lockout. BLOCKED-on-ruling to doyle with 3 options; doyle ratified (a) = GENERATION LADDER @222d8b5: same-by equal-gen silent successor / strictly-newer gen (Control OR Take) loud+fenced supersession via full W2 revoke (Take→TookControl, Control→Controller) / older Busy; different-by unchanged. Deliberate UX: second same-node window's plain rc loudly displaces. T6 named gate leg, green unmodified (2.5s).
  **W2 MECHANICS:** (a) revoke architecture — droppable old.tx.try_send REMOVED; mark_revoked stamps incumbent sink; the incumbent WRITER emits terminal KIND_DISPLACED as final frame on exit (behind drained backlog); wedged conn → existing per-write watchdog poison+sever; CtrlMsg::Control variant deleted. (b) input fence: pure rc_input_rejected — ONLY Minter::Rc from non-controller conn rejected (conn identity = lease surrogate, decision 4); shell/legacy untouched; rejection error also terminates stale serve worker. (c) NO wire changes (by+gen already on SubscribeReq; N-1 via gen==0 legacy arm). (d) client current-driver guidance pinned untouched (pure pre_broker_busy_guidance + unit — different-by only per KH 7.15).
  Int (controller_lease.rs, HEAVY ×3): supersession loud+terminal BOTH intents; equal-lease replay silent (bounded absence); fence steps 5-6 + shell-injection-lands; wedged-incumbent terminal BOTH intents (SPT_BRAIN_WRITE_DEADLINE_MS=700). Preflight: units 5/5, int 6/6, battery 1942/1942, clippy 0, traceable 538/0/0, xtask OK.
  GOTCHAS: doyle's ruling edits briefly rode my checkout (he reverted clean, routed via main worktree); merge-conflict resolve script grabbed '=======' as title once (caught by git diff --check, repaired from origin/main before push); one rustc incremental ICE (STATUS_STACK_BUFFER_OVERRUN) → clear target/debug/incremental; 3× scoped spt.exe orphan sweeps (6 each).
- **W3 terminal render lifecycle** (ADR-0043, KH 7.47) — **✅ GATED PASS + MERGED main @13ddd5c 2026-07-18 (doyle): source read clean, 3 flagged calls RULED ACCEPTED (quiescence witness 300ms/5s — join structurally impossible, residual documented; marker-frame int + wire-exact-at-unit-seam; tty-gated DisplayGuard), reap-first reorder tightens the W2 relatch window as bonus; CI FULL GREEN first try, isolated-worktree 757/757 incl render_lifecycle + full substrate + spt-term. PR #30 @cbf1925. ALL THREE WAVES CLOSED — zero gate rounds, three first-try-green CI runs. Release GO next.** Commits: 0f87723 flips / a172673 build / +all_sinks cleanup. Preflight: FULL battery 1950/1950 FIRST TRY, clippy 0, traceable 538/0/0, xtask OK (orphan sweeps as usual).
  **W3 MECHANICS + 3 FLAGGED CALLS:** (1) leg-1 exit waiter: remove-first (decision-4 kept) → drain-completion via bytes_forwarded QUIESCENCE (300ms/5s — drain.join IMPOSSIBLE: parked ConPTY read needs pseudo-console close, forbidden while shared writer lives; join wedged the waiter forever, proven live) → Exit enqueued BEHIND queued output per sink (CtrlMsg::Exit via controller writer = W2 machinery composed; viewers via Envelope channel; EXIT_QUEUE_FALLBACK bounded degrade; all_sinks deleted). (2) int payload deviation: pty layer CONSUMES typed escapes → wire-exact ESC payload proven at writer-queue UNIT seam; production-path int = marker frame + broker kill (render_lifecycle.rs HEAVY ×3). (3) DisplayGuard tty-only (piped e2e bytes clean); separate from RawGuard, drop order postlude→mode-restore; parting_prose extracted byte-identical; teardown matrix int = dirty sink × 7 final classes + unwind. Picker: purge_endpoint_core structured/silent (confirm injected, CLI copy byte-identical) + terminal.clear() baseline reset + recording-backend int (out-of-band cell corruption through the backend → complete reconstruction). DECSTBM replay before final cursor (explicit ESC[r for default) + emulator-contract unit.
  herdr v0.7.4 = AGPL ideas-only (zero code). P2 deferred seeds: Exit{after_seq} watermark, semantic baseline.

Sequence: todlando builds W1 → doyle gates (isolated worktree) → W2 → gate → W3 → gate → deployah release (bump-in-PR, end-user CHANGELOG, counter from published metadata — deployah OFFLINE right now, notify at GO) → hertz field-verify (owns split-brain repro + stale-glyphs screenshots + perri box).

Wave-rank rationale: W2 control-integrity P0 (live split-brain) outranks W3 render; W1 first because W2 revoke composes with W1 session-confirmed attach machinery.

**PR #32 (build→main) MERGE — doyle taking it (W1-W3 pattern). CI: Windows test PASS (16m52s, disk-reclaim worked), n1-gate both PASS, traceability/changes PASS. Linux(kitsubito) test FAILED 1 test = spt-daemon::registry_lifecycle::oneway_rounds_plateau_rows_seats_and_a_refresh_replays_nothing (expected (1,0) got (0,0), historical row didn't land before refresh). DIAGNOSED FLAKE not W4: Windows passed identical code; W4 touched registry.rs/registryhost.rs COMMENT-ONLY (CONTEXT:386 sweep) + registry_lifecycle.rs UNTOUCHED; heavy timing-replay test, (0,0)/(1,0)=setup race. Re-ran failed Linux job (gh run rerun 29672329723 --failed), watching (bg b5sgujvc5). MERGE HELD until green. SEED for REGISTRY-STALL backlog: registry_lifecycle oneway_rounds Linux-flaky under CI load.**

**✅ PR #32 MERGED to main @610027e 2026-07-19 (doyle, merge commit — per-leg tagged commits preserved). W4 build lane CLOSED.** Linux registry_lifecycle flake RESOLVED as PRE-EXISTING (not a merge blocker): reran twice, failed both at DIFFERENT assertions (rs:377 then rs:371) = genuinely flaky rig; DECISIVE — main @7b524d0 (already on main, direct-push doc commit) reds the IDENTICAL test at rs:371 "fresh dispatcher re-applies ZERO historical feeds", Windows passed all runs, W4 registry changes comment-only + registry_lifecycle.rs untouched. Normal `gh pr merge --merge` went through past the flake (branch protection permits). DEPLOYAH release GO re-sent (queued): main @610027e, counter 66→67, bump-in-PR, 3 CHANGELOG surfaces, flagged the pre-existing Linux flake will hit their release PR too (not a blocker). NEXT: deployah cuts v0.38.1 → hertz field re-verify (banner==1, own-node "controlled locally"+self-attribute, plain-rc REFUSAL, hybrid heals+resumes) → milestone CLOSE. ⭐ NEW MILESTONE CANDIDATE queued in [[spt-core-findings-backlog]]: SCREENGRID-WIDTH (hertz ScreenGrid Unicode-width RCA, doyle CONFIRMED+grounded, build-ready: REQ-SCREENGRID-WIDTH + REQ-DSR-SINGLE-CPR, width policy pinned = ratatui unicode-width 0.2.0/ambiguous=1/non-CJK workspace-shared, independent-emulator regression oracle) — awaits v0.38.1 close + operator GO. Registry-int-hardening seed (bounded-poll oneway-rounds rig) also queued.

**✅ v0.38.1 RELEASE PR #33 (deployah, counter 67) — doyle PRE-MERGE CHECK PASS + GO 2026-07-19.** Ceremony verified: counter 67 from published metadata (v0.38.0=66), bump exactly 12 version lines (Cargo.toml workspace + 11 first-party lock), ZERO third-party churn, only 3 files (CHANGELOG/Cargo.toml/Cargo.lock, no stray), CHANGELOG ladder contiguous + end-user voice + 3 surfaces accurate, xtask no-drift. DOYLE RULING on deployah's Fixed-vs-Internal question: doubled-banner surface COLLAPSE TO INTERNAL (diagnostic-log hygiene not user-facing behavior; label + resume surfaces stay Fixed) — suggested "Internal: spt rc builds a single attach pump per session instead of two". GO after that edit (deployah applies, no re-review). Flake plan confirmed (rerun --failed once if blocks, no re-tag). NEXT: deployah merges #33 + tags → v0.38.1 published → hertz field re-verify → milestone CLOSE.

**⛔ 2026-07-21 — hertz FIELD VERDICT ARRIVED AND THE MILESTONE DOES *NOT* CLOSE. RC-RENDER-TRUTH STAYS OPEN on a NEW P0 that falsifies a SHIPPED v0.39.0 release claim.** The long-awaited field-verify (the only open loop for BOTH this milestone and TEARDOWN-AUTHORITY) came back with four defects, not an acceptance. **The one that reopens this milestone: RC-RESIZE-GEOMETRY-EPOCH.** Operator-visible symptom is exactly the v0.39.0 release-note claim failing — right-margin scraps + left-shifted Claude Code rows, on a node where CLI *and* broker are both 0.39.0 (`broker_image=0.39.0`, stale=false). ROOT (doyle re-grounded verbatim against main @1e30626, statically provable, NO repro box needed): `broker.rs::dispatch_resize` calls `session.resize(...)` at **:4557-4559** and only THEN `recover_log(&log).set_size_and_notify(...)` at **:4560**, which reaches `self.grid.resize(rows, cols)` at **:1492** — **TWO SEPARATE `recover_log` acquisitions**, so the reader thread's append/parse interleaves between them by construction. ConPTY emits a full repaint asynchronously ON the resize; the reader parses it into ScreenGrid at the OLD geometry; the top-left-preserving `grid.resize` then faithfully preserves an ALREADY-MISWRAPPED model; cold attach repaint emits the shift. **W3's width work is NOT falsified — it is running UNDER a broken geometry transition.** hertz's discriminator is what proves it: `cargo test -p spt-term --test screengrid_width_oracle` 5/5 GREEN while the field is red ⇒ the oracle never crosses the `ConPTY resize emission → ScreenGrid geometry → attach repaint` seam, and the surface mock structurally cannot. ⚠ **DOYLE CORRECTION TO hertz's OWN RECOMMENDED FIX (they accepted it; on record so nobody builds the wrong thing): "set grid geometry BEFORE invoking ConPTY resize" is INSUFFICIENT** — safe on a GROW, unsafe on a SHRINK, because bytes already in flight at the old WIDER geometry get parsed at the new narrow width and wrap early. **Neither pure ordering is correct: the defect is not the ORDER, it is the absence of a BARRIER — the grid has no notion of "these bytes were emitted under the old geometry."** Required shape = quiesce/gate the drain across the ordered transition + an explicit **geometry epoch** (bytes always parsed at the geometry they were emitted under) + rollback/refetch on resize failure. Regression accepted as filed: Windows **real** ConPTY, resize emits a dense frame, compare the subsequent synthesized attach repaint against an INDEPENDENT terminal authority (never ScreenGrid vs itself — the standing oracle rule from the SCREENGRID-WIDTH spec). Needs no operator GO: it is a regression against a shipped claim, not new scope. Full four-defect text + the other three rulings (#2 ONLINE - MESSAGE ONLY product ruling, #3 `api listen` OVERWRITING hosting topology at startup.rs:191-195/:379, #4 `api end` stored-online → routed to DAEMON-LIFECYCLE) live in [[spt-core-findings-backlog]]. ⭐ **PROCESS NOTE WORTH KEEPING: the field-verify that was supposed to be a rubber-stamp close is what caught a shipped-claim regression — and it caught it because hertz ran a DISCRIMINATOR (green oracle + red field) rather than reporting the symptom alone.** See also [[teardown-authority-progress]]: hertz explicitly did NOT verify that milestone's claims, so it stays open on an answer rather than on inference.

**⭐ 2026-07-21 SUPPLEMENT — THIRD corruption shape, and the reason it is the SAME root is a DISCRIMINATION, not the prediction.** Operator field-confirmed on the same fully-0.39.0 node: stale characters surviving **INSIDE nominal whitespace between words** (`isnsettled`, `fulllyacaptured`), not only right-margin scraps or whole-row left shifts. hertz classified it as more evidence for #1 (RC-RESIZE-GEOMETRY-EPOCH) and was right, but doyle refused to accept it on the prediction — *a root that predicts a symptom is exactly the tidy-story shape the digest-hub attribution taught us to distrust.* **THE COMPETING ROOT THAT HAD TO DIE FIRST: an un-normalized erase across a wide half**, which would have been a SECOND defect inside W3's own surface rather than support for #1. It does not survive the code — `screen.rs` splits lead/continuation in `clear_cell_keep_pen` (~416/~420), normalizes both ends of a span (~440-443), normalizes at the `delete_chars`/`insert_chars` seam (~617-620), and `erase_across_a_wide_half_leaves_no_orphan` (~1391) passes. **THE DECISIVE OBSERVATION, and it was sitting in the captures the whole time: the debris is pure ASCII, every glyph width-1** — so no width-table or wide-half defect can reach it at all (the width model is a NO-OP on that text), and `isn`+`settled` collapsing across a space is the same shifted-by-N placement as the whole-row shift, seen at WORD scale. Geometry-mismatched placement + partial differential overwrite: later differential output and EL operations address the CORRECT geometry and therefore do not necessarily clear cells the mis-widthed repaint contaminated; the synthesized cold repaint then faithfully re-emits them. hertz accepted the stronger discrimination. **ORACLE BROADENED (REQ amended @e4274bc, traceable exit 0): compare EVERY CELL including expected-BLANK interior cells** — never row starts / right margins / text presence alone; the dense resize frame must carry erased interior spans and repeated spaces. ⭐ **BINDING CONSTRAINT, worth more than the assertion: NO whitespace special-casing and NO extra clears — the barrier must restore ONE geometry authority for placement AND erasure. A fix that passes by clearing harder satisfies the test and leaves the defect** (doyle will fail that at gate; todlando told to come back rather than add a clear). **OPEN DISCRIMINATOR (recorded, nobody hunting it):** interior debris in a session that PROVABLY never resized over its whole lifetime ⇒ a SECOND root this fix will not clear. hertz will report it if one turns up; current field evidence does not establish resize-count either way and hertz explicitly refused to infer.

**⭐ 2026-07-21 SCOPE CHANGE — OPERATOR-RULED FOLD: REQ-LISTEN-PRESERVES-HOSTING-TOPOLOGY now RIDES THE RESIZE WAVE. Both ship in one release.** doyle had refused the fold TWICE that day (once to todlando, once to emphasys) on the grounds that a two-seam wave is where a red in one leg gets blamed on the other. Reversed by the OPERATOR, directly, with the tradeoff in front of them. TRIGGER + the process bit worth keeping: emphasys escalated with *"User explicitly requested RCA then build/publish fix — implement core P1 now"*, while hertz independently logged that in THEIR conversation the operator had said only `/diagnose and report to doyle` — no build/publish GO — and refused to reinterpret a peer assertion as authorization. **doyle neither complied with the relay nor refused it: asked the operator directly with four options (own wave / queue behind the P0 / refuse as overreach / fold). Operator chose FOLD.** Outcome matched emphasys's ask, on real authority; the relay itself was still not authorization and emphasys was told so. See [[no-version-floor-before-it-ships]] for the standing rule. **GATE DISCIPLINE TIGHTENED IN RESPONSE (binding on todlando, since the answer to being overruled is a tighter gate, not relitigation):** SEPARATE COMMITS per seam, no interleaving (each revertable alone); **SEPARATE INT LEGS WITH NO SHARED RIG** — the resize oracle (real ConPTY, independent emulator, every-cell) and the bind→listen→control→detach regression must not share setup, or a lifecycle flake reds the render leg and costs a day of arbitration; both REQs activated on the build branch; if the seams turn out to TOUCH (not expected — broker.rs/screen.rs vs api/startup.rs) todlando reports BEFORE resolving ([[dispatch-on-overlap-not-on-merge]]). ALSO REFUSED and restated so it is not built by accident: emphasys's detach-callback / release-control primitive — no adapter-facing API comes out of this wave. Lifecycle seam grounding + the claude-spt discriminator (equivalent detach reads plain ONLINE ⇒ the downgrade needs `api listen --session-id` over an ALREADY-BOUND perch = the published sequence, so the contract stamps the wrong value and the adapter did nothing unusual) is in [[spt-core-findings-backlog]] #3. Preferred fix held: represent listener custody separately from PTY hosting authority; the weaker "preserve controllable=true when a broker-hosted session exists" leaves listen guessing and needs justifying in the PR body. **One genuine upside of the fold: hertz field-verifies both seams in a single pass.**

**⭐ 2026-07-21 RESIZE SEAM BUILT @0f149ee (todlando, branch fix/rc-resize-geometry-epoch) — doyle INTERIM SOURCE-READ done, 2 findings, battery deferred until the lifecycle seam lands.** SHAPE BUILT (accepted): close barrier → settle drain (bounded) → issue surface resize → replay each held segment at ITS OWN geometry with the grid resized BETWEEN epochs → commit + bump epoch + size frame. Failed surface resize rolls back: `abort_resize` re-tags EVERY segment (incl. post-issue) to the OLD geometry, leaves grid geometry/stored size/epoch untouched, pushes NO size frame (a refused resize must not tell viewers the letterbox moved). `RESIZE_HOLD_OVERFLOW` drops from the GRID ONLY (ring + subscribers unaffected), loud, self-heals on next output. **DOYLE'S GATE ADDITION ANSWERED IN CODE, not just the PR body: NO second quiescence authority** — barrier lives in OutputLog under the lock the drain already takes, settle reuses the W3 exit-waiter witness shape (monotonic counter going still, bounded, never a join), and it gates the GRID PARSE ONLY so ring/controller-handoff/viewer fan-out run full speed inside a transition. **VERIFIED BY doyle rather than taken on report: `settle_before_resize` sleeps OUTSIDE the log mutex and re-acquires per poll (~977-995) ⇒ KH 7.12 holds** (checked specifically — "settle the drain" is the shape that usually smuggles a sleep under a lock). Bounds 20ms quiet / 5ms poll / **250ms cap** with a loud `RESIZE_SETTLE_CAP` degrade ⇒ worst case 250ms on the controller conn thread, never parks, not a stall class.
⚠ **FINDING 1 (MUST FIX before battery): `SPT_TEST_RESIZE_WINDOW_MS` is read from PRODUCTION code with NO build gate** (`test_widen_resize_window` ~1000-1010, called ~4862 between surface resize and commit). Unset = no-op and the mechanism is legitimate (widens a window that GENUINELY EXISTS — ConPTY's repaint is async — rather than fabricating one), but a shipped RELEASE broker will read it and sleep if anything exports it. **This is the [[SPT_INJECT_VERIFY_ECHO env-poison class]] arriving from the OTHER DIRECTION**: there a live-agent shell exported a var that test brokers inherited; here a stray export reaches the operator's REAL broker. FIX: `#[cfg(debug_assertions)]` + no-op release twin (nextest builds debug, int leg unaffected); also consider the existing env-scrub set, since a dev-shell export would poison every debug-build broker on hfenduleam (gate box AND CI runner).
**FINDING 2 (answer, maybe no change):** `begin_resize` returns Err "a resize transition is already in flight" (~1683-1686) which `dispatch_resize` propagates as a user-visible resize failure. If controller-conn frames are sequential the arm is unreachable/defensive (then prefer a debug_assert or a comment saying so); if a controller handoff or second conn CAN resize inside the 250ms window it is reachable, and **drag-resize is exactly the workload that emits back-to-back resizes** — then coalesce the newer target into the in-flight transition rather than erroring.
⭐⭐ **THE PART WORTH KEEPING FROM todlando'S OWN REPORT: THE INT LEG PASSED AGAINST THE UNFIXED CODE ON ITS FIRST VERSION AND THEY DID NOT ACCEPT THE GREEN.** Pre-fix the window was two lock acquisitions wide, so from a test the async repaint landed in it only by scheduler luck — *a leg that goes red only by luck is a leg that goes green for the wrong reason.* They added the widener, got red-first on BOTH shapes (interior debris on rows the authority had cleared + word-scale collision), and their UNITS discriminate BOTH wrong answers separately: shrink reds if pre-issue bytes parse at the NEW width (doyle's rejected reorder) AND if post-issue bytes parse at the OLD one (the pre-fix interleave). **That evidence is stronger than the greens.** Greens for the record: spt-daemon 752/752 nextest, spt-term 67/67, xtask OK, clippy clean, `resize_geometry_epoch` HEAVY at birth in all 3 strings. NO FILE OVERLAP confirmed by both sides (broker.rs/screen.rs/tests vs api/startup.rs) ⇒ seams independent inside the one wave.

**⛔ 2026-07-21 WHOLE-BRANCH GATE ROUND 1 — BATTERY HELD on a doyle source-read finding. Branch fix/rc-resize-geometry-epoch, 3 commits (0f149ee resize / c52b7b6 gate-findings / 014fed9 lifecycle).** Findings 1+2 VERIFIED FIXED: `test_widen_resize_window` now `#[cfg(debug_assertions)]` with a release twin that does not read env at all, PLUS added to the daemon-startup scrub as `TEST_TIMING_ENV_VARS` (reachability hole closed both directions); `begin_resize_serialized` WAITS outside the lock, bounded 1s, 5ms poll — and finding 2's path turned out **REAL, not defensive**: one conn's frames are sequential so a drag-resize can't overlap itself, but the CONTROLLER SLOT MOVES and `serve_attach` forwards a viewport's Resize on whichever stream holds control, so a takeover landing inside another transition's 250ms window passes the controller-exclusive gate and arrives second. Now last-writer-wins, no coalescing. Lifecycle seam built as the PREFERRED fix: `HostingAuthority{BrokerPty,ListenerOnly,NonAgent}` in the TYPE SYSTEM, only BrokerPty contributes a stamp, `resolve_controllable(hosting, prior)` carries prior for the other two — **no broker-session-present column at all, because that column is the WEAKER fix's input.** doyle RATIFIED todlando's judgement call to add NO persisted custody field (nothing reads one; a speculative record change is a contract you then owe someone) — follow-up explicitly cancelled.
⛔ **BLOCKING FINDING (doyle, grounded before claiming): THE FIX REMOVED AN INCORRECT DEMOTION WITHOUT ADDING THE CORRECT ONE.** Path: endpoint bound spt-hosted (`api bind` earns controllable=Some(true)) → its broker PTY session ENDS → a harness-hosted `api listen` establishes a relay over the same id → ListenerOnly contributes None → **the perch KEEPS Some(true)**. That row then routes by livehost.rs's gate `state != live_agent && controllable != Some(true)` (pinned at ~2382-2400) — controllable==Some(true) of ANY state falls through to **BROKER-SESSION TRUTH**, and the B2 keystone (~1213-1218) marks an spt-hosted online perch with NO live broker session **OFFLINE**. ⇒ **a live, message-reachable listener gets stamped OFFLINE.** Pre-change that row carried Some(false), was EXEMPT from the broker-session arm, and stayed online on the PID model — *the right answer reached by the wrong means*; the seam removed the wrong means and nothing replaced the right answer. ⭐ **SAME DEFECT CLASS, INVERTED: we started with a record reading amber when it should read green; this would read OFFLINE while alive and answering.** doyle did NOT propose reverting to a listen-side stamp (it must not assert). OPEN QUESTION handed back: WHO demotes hosting authority when the PTY dies — the broker-session-truth arm (demote instead of offline) or SESSION TEARDOWN at the point the PTY actually goes away (doyle leans here: *the path that KNOWS should be the path that speaks*, the same reasoning as the seam itself). DISCRIMINATOR requested before the battery: bind spt-hosted → kill broker session → `api listen` same id → run reconcile → read status.
⭐ **PROCESS LESSON — GREP FINDS ASSERTIONS, NOT PREMISES.** todlando's behavior-change sweep correctly found the ONE unit that ASSERTED `listen -> Some(false)` and called it "the defect written down as a contract". It could NOT find `reconcile_routing_controllable_falls_through_to_broker_session_truth`, whose assumption lives in its LABELS ("listen-born ready listener → PID model", `Some(false)` hardcoded as INPUT) rather than in an assertion about the changed seam. The unit still passes — it is a pure predicate table — but "listen-born" no longer implies Some(false). Extends [[behavior-change-grep-tests-not-comments]]: after grepping assertions, ask which tests' INPUTS encode the old behavior as a premise.

**⭐ 2026-07-21 SEVERITY RAISE + ORACLE AMENDMENT (hertz field capture #3, doyle-triaged against the code before answering — half the ask was ALREADY SATISFIED and the other half carried a trap).** NEW EVIDENCE: corruption is NOT confined to blanks/residue — existing valid ASCII is CLOBBERED, MERGED, DISPLACED, SUBSTITUTED **mid-row** (`ReQ2`, `ROADMAPnsayh'credertigls`, `Recommend:gdirect REST`, `thii reqw st`, `resdluuion`). **Semantic corruption of rendered content, not cosmetic debris.** Same accepted root, stronger ASCII discrimination: wrong-geometry placement + later differential writes OVERWRITE valid cells, not merely fail to clear blanks. Severity raise accepted — does NOT change scheduling (already the blocking P0) but DOES raise the FIELD-VERIFY bar: post-fix pass exercises READABLE PROSE and verifies exact visual cell fidelity, not absence of margin scraps.
**ALREADY SATISFIED BY CONSTRUCTION (doyle checked the test before passing the ask along — todlando told not to rework it):** hertz asked the oracle compare nonblank glyph identity+position as well as blank interiors. `resize_geometry_epoch.rs` already asserts **FULL-ROW STRING EQUALITY, UNTRIMMED, EVERY ROW**, against an independent `avt::Vt` authority, plus equal row counts. That cannot miss deletion/insertion/substitution/merge/displacement of a width-1 cell — any one changes the row string. No fuzzy/normalization/presence assertion exists to remove. hertz recorded agreement.
⚠ **THE REAL DELTA IS THE FIXTURE — AND THE TRAP doyle DEFENDED:** todlando deliberately chose a **narrow, unwrapped** pre-resize screen (no line reaches either margin, no row lost) and said why in the test header — it makes wrap/reflow POLICY a no-op. **avt and ConPTY do not necessarily agree on reflow semantics when a line reaches the margin and geometry changes; a fixture that depends on reflow would RED ON POLICY DIVERGENCE between the two emulators rather than on our defect**, and the gate would be spent arbitrating which emulator is right. BINDING SHAPE: ordinary prose with repeated words + punctuation (realistic text is where clobber/merge hide — a displaced fragment lands somewhere still plausible), must fail on any of the five mutations, no normalization/presence assertions, **but the fixture stays inside the region where the two emulators AGREE (no wrap/reflow dependence)**, reason recorded. Sufficient because clobber/merge/displacement are PLACEMENT-AND-OVERWRITE defects, not reflow defects — hertz's own captures show them MID-ROW. A reflow-crossing case needs the wrap policy PINNED between authority and ConPTY first, as its OWN work — explicitly not smuggled into this wave.
⭐ **EPISTEMIC LINE HELD BY BOTH SIDES, worth keeping:** doyle told hertz plainly that the new captures are *consistent with* the accepted root but do NOT prove it exclusive, and carried the amendment as a STRENGTHENING of the root rather than as proof it is settled. hertz recorded the same: *"Root remains strongly consistent, not proven exclusive; a provably no-resize corruption still establishes a second root."* The open no-resize discriminator stays the thing that would flip it.

**⭐ 2026-07-21 GATE ROUND 2 — IN FLIGHT AT CONTEXT RESET. Branch fix/rc-resize-geometry-epoch @94fcae0, FOUR commits (0f149ee resize / c52b7b6 findings 1+2 / 014fed9 lifecycle / 94fcae0 demotion+fixture).**
**⭐⭐ MY PREFERRED FIX WAS WRONG AND THE SUITE SAID SO — keep this, it is the wave's best lesson.** doyle's blocking finding was REAL (todlando's discriminator reproduced it verbatim: `offlined:[deadpty], controllable:Some(true)` — a live listener marked dead). But doyle LEANED toward "clear the authority at the broker's reap" (*the path that KNOWS the PTY ended should speak*) and todlando built that FIRST. **It was falsified inside one run: that surviving `Some(true)` is the ONLY thing letting the reconcile recognise "spt-hosted endpoint whose harness died" and offline it. Clearing at reap made every such row EXEMPT — a killed harness never went offline.** dummy_harness_e2e, rc_attach_truth, attach_wedge_e2e all red; dummy_harness's own diagnostic named it (`went_offline=false`); confirmed green pre-change so it was the change, not a flake. **THE REAP KNOWS ONLY HALF THE QUESTION** — it knows the PTY ended, not whether anything still holds the endpoint. Both facts are only in hand in the reconcile = doyle's FIRST candidate. *The reasoning that made the second one smell right to BOTH of us is exactly what the B2 keystone was built on.*
**SHIPPED FIX:** in the sessionless arm, an endpoint with a REGISTERED RELAY ADDRESS (`spt_store::registry::resolve_address`) is DEMOTED not offlined — the same "a relay means harness-hosted BY DEFINITION" belt `restart_resume_gate` already trusts, not a new guess; nothing holding it → B2 offlines exactly as before (that unit untouched). **Demoted to `None`, NOT `Some(false)`**: the daemon observes no broker PTY exists, not that a harness owns the process, and `Some(false)` would route the row into `hybrid_self_heal_due`'s pid probe, sound only for pids core never spawned (**KH 7.50**). NON-TERMINAL — a later spt-hosted bind re-earns `Some(true)`. A unit pins the NEGATIVE at the reap (`a_reap_clears_the_control_stamps_but_never_the_hosting_authority`) so the wrong intuition can't be relearned. Int leg runs a **REAL listen loop, not `--once`** (`--once` tears its relay address down on exit ⇒ the one-shot version proved nothing about a live listener).
⚠ **FINDING 3 — OPEN, doc-only must-fix, sent to todlando:** `livehost.rs:673-674` still states the FALSIFIED approach as shipped design — *"The authority is retired by the path that KNOWS it ended: the broker clears it to `None` when it reaps the session."* broker.rs says the opposite explicitly and the new unit asserts `Some(true)` SURVIVES. Leftover from the abandoned attempt, sitting on the function it misdescribes, and persuasive enough to hand the next reader the exact wrong intuition that cost a build cycle. W1's falsified-doc-comment rule.
**⭐ DOYLE RULING (todlando asked rather than shipped — right call): cold attach DURING a transition renders the PRE-transition screen (held bytes not yet parsed). ACCEPT + DOCUMENT for this wave; DO NOT block the repaint.** REFUSED explicitly: making the repaint wait on an in-flight transition — that puts a user-facing attach behind settle + a surface call (and behind the cap / 1s serialize wait pathologically); attach latency is what W1/W2 spent effort keeping honest. **DECIDING ARGUMENT: compare to what SHIPPED — pre-fix that same attach rendered a MISWRAPPED (corrupt) screen; post-fix it renders a STALE BUT COHERENT one. A residual that strictly IMPROVES on shipped behavior does not block the fix for shipped behavior.** MUST BE RECORDED HONESTLY in code + REQ: the window is bounded in TIME (settle + one surface call) but **NOT in VISIBILITY** — on a QUIET child the stale screen persists until something outputs. FOLLOW-UP SEED (not this wave, do not build): on commit, push a fresh synthesized repaint to viewers that attached during the transition — the commit already touches viewers for the letterbox size frame, so the seam exists and it closes the gap without putting attach behind anything.
**⭐ 2026-07-21 PRESENTATION-BARRIER TRIAGE PUBLISHED main @e916d41 + todlando DISPATCHED (SENT live).** Three artifacts: ADR-0031 **Amendment II** (presentation contract: suppress controller+viewer delivery during transition, ring keeps recording; commit = size-frame-first to viewers then ONE sync frame [render_repaint@target ++ deferred non-grid bytes] to EVERY attached sink under the same OutputLog lock; watermark seq = highest suppressed seq advances cursor as-if-written; abort uniform minus size; presentation floor → resume below it gets cold-attach shape never raw replay); **REQ-RC-RESIZE-PRESENTATION-BARRIER** minted registry-first `required_stages=[]` (todlando activates on branch); DISPATCH doc "Second reopen" section (5 legs + binding gate legs). **Grounding CORRECTED the assumed drop-list:** render_repaint (screen.rs:803-881) already replays title/alt-screen/cursor-vis/DECSTBM/pen — the REAL drop classes are the parser ignore-arms. Disposition table: tracked=SUPERSEDED (unit-pinned per class); untracked-stateful (2004/mouse/1004/DECCKM/DECAWM/keypad/DECSCUSR/OSC-color/charset) + one-shots (BEL/OSC52/OSC9) + queries (DA/DECRQM/XTWINOPS) = DEFER verbatim inside sync frame; OSC8 hyperlinks + DCS = DROP balanced. DSR in no class (drain strips pre-append; mid-transition CPR stale = accepted bounded residual). MECHANISM BINDING: classification in the ONE parser authority (vte::Perform capture mode at replay), never a second scanner. Absorbed seed: commit-time sync frame IS the repaint-transition-era-attachers follow-up (visibility-unbounded caveat dies; residual text updates ride the build). Fenced separate: heuristic epoch-split strengthening. Release-note quote/gap/closure correction (v0.39.0+v0.39.1 Fixed claims) rides the shipping cut. Branch: fix/rc-resize-presentation-barrier. NEXT: todlando builds → doyle whole-branch battery (leg 0 = cargo build --workspace throwaway) → release → hertz field-verify with readable-prose exact-cell bar. ⚠ hertz lifecycle-seam attempt 2026-07-21: fixture failed (omp-spt adapter launched OUTSIDE an OMP-owned session context → row instantly dead, never reached bind — NOT a lifecycle verdict, purged); local int 1/1 on 0.39.2 workspace = supporting-not-substitute; verdict stays NOT YET RUN, hertz to re-run from a real OMP-owned session on installed 0.39.3.

**⭐ 2026-07-21 UNEXPECTED-SEAM RULING — SYNC WIRE FLAG (todlando held per plan rule, doyle ruled ACCEPTED with 4 pins).** Their real-wire int leg exposed a CLIENT seam the triage table missed: sync frame at watermark W hits strict reject-gap (brain.rs:822-827) on every attached-throughout controller → refetch ladder (attach.rs:165-199) → ControllerIrrecoverablyBehind → marked truncation ON EVERY RESIZE. Cold-attach precedent had a client half (baseline_next_output :815-818, armed only by from_seq==0) that the sync frame lacked. RULING: additive OutputEvent `sync: bool` (resume_seq additive-field precedent), broker sets on commit/abort sync frames + repaint_initial batches; client accepts-and-baselines FLAGGED FORWARD jumps on both dedup paths, unflagged stays strict byte-for-byte (B2 intact — the flag makes repaint_initial's implicit supersession assertion explicit on the wire). PINS: (1) forward-only, flagged-backward = dedup-drop, never baseline backward (rewind kills exactly-once), unit-pinned; (2) baseline_next_output STAYS untouched = old-broker×new-client compat, flag is additive not replacement, retirement is N-2 seed at most; (3) four rejected alternatives ratified-rejected on record (unconditional baseline / empty-frame delivery / seq-rebase / cold-reattach-on-second-gap); (4) N-1 new-broker×old-client = resize in mixed-version window ends attach with MARKED truncation (honest termination vs pre-fix silent corruption — accepted, MUST ride release notes: "update CLI and broker together"). Paperwork on branch (gate verifies faithful render, ladder-ruling pattern): ADR-0031 Amendment II wire-contract paragraph + REQ title amendment with new unit legs. ⭐ PROCESS: the finding VINDICATES the real-wire int leg — the cold oracle was structurally blind to this client seam too; and todlando's hold-and-ask on an unexpected seam (int rig written+HEAVY-registered but uncommitted, zero client code touched) is exactly the dispatch discipline working.

**⭐⭐ 2026-07-21 PRESENTATION-BARRIER WHOLE-BRANCH GATE = PASS @dad6ff2 (doyle). Verdict SENT to todlando — open the PR.** Branch fix/rc-resize-presentation-barrier, 7 commits (56bec76 activation / 98ec5d8 legs 1-3 / 9258066 floor / 432716a capture / b9ef74e wire flag / c6cbf5e int rig / dad6ff2 quote fix). SOURCE-READ PASS all 7: suppression pre-frame-build + eviction exemption both halves; CtrlMsg::Sync→advance_delivered vs live contiguous_advance split; next_seq==0 poison edge; floor predicate w/ B2 at/above byte-for-byte + skip-to-live not inflated; capture mode w/ split-sequence carry, RIS-preserve, original OSC terminator, bare-ST remnant excluded (todlando found red: DCS tail emitted unpaired ESC-backslash); wire flag all 4 pins + ADR wire paragraph verbatim-faithful; int rig = control-run avt authority at target geometry, cell-for-cell incl. blanks, never grid-vs-itself; HEAVY 3-string registration byte-identical. BATTERY (isolated worktree, throwaway target, FULL workspace — 99G free so NO scoped caveat this time): leg 0 build --workspace PASS, clippy --all-targets -D warnings 0, traceable EXIT 0, nextest 2033/2033 (1 skip twohost known, 8 leaky benign brainproc/timeout class), resize_presentation_barrier 2/2 + resize_geometry_epoch 2/2 in-run. SEED (non-blocking, told todlando to backlog): multi-param private-mode CSI mixing tracked+untracked (ESC[?25;2004h) honors first param only — pre-existing set_mode limitation, now with small capture-loss face. CLEANUP: throwaway target deleted; gate-dad6ff2 worktree DEREGISTERED but dir handle-pinned (crates/spt-daemon held) — retry delete at next sweep. ⚠ SHARED CHECKOUT = todlando's branch (OCCUPIED, left alone). NEXT: todlando PR → CI → doyle merges (W1-W4 pattern) → deployah GO with changelog surfaces: fix + v0.39.0/0.39.1 quote/gap/closure corrections + 'update CLI and broker together' N-1 line.

**✅ 2026-07-21 PRESENTATION-BARRIER BUILD LANE CLOSED — PR #51 MERGED main @d957326 (doyle, merge commit, per-leg commits preserved). CI green both boxes FIRST TRY (test 15m19s/15m46s, both n1-gates, no port-5474 recurrence, baseline reap-flake absent, registry_lifecycle quiet). DEPLOYAH RELEASE GO SENT (SENT live):** cut off @d957326, patch-shape on 0.39 line (deployah ceremony verifies), counter self-verified from published (latest 71/v0.39.3), dedicated-release-PR-only + release-lane worktree. FOUR changelog surfaces handed over: (1) Fixed headline in behavior words (resize no longer garbles live view; one clean repaint at new size); (2) BINDING correction section — v0.39.0 AND v0.39.1 resize-corruption Fixed claims get quote/gap/closure ([[v0393-published]] template; gap = model-only fix, live terminals still got mixed-geometry output; closure = barrier extended over delivery; NO epoch/barrier vocab); (3) Known mixed-version line (update CLI+broker together; old CLI across a new-broker resize ends attach cleanly, re-attach resumes); (4) Internal one-liner for the additive sync marker. Post-publish: hertz field-verifies BOTH seams from Latest (readable-prose exact-cell bar) + still-pending lifecycle leg from a real OMP-owned session. Multi-param mode-CSI seed filed to [[spt-core-findings-backlog]] in todlando's phrasing. **⭐ v0.39.4 CUT (counter 72) — deployah GROUNDING STOP honored + doyle CORRECTION-QUOTES RULING 2026-07-21:** deployah refused to invent a v0.39.0 resize quote (v0.39.0 has NO literal resize Fixed claim — doyle's GO phrasing was loose, deployah caught it). RULING: quote TWO, framed differently — v0.39.1's resize claim = direct quote/gap/closure (true of the MODEL, delivery ungated); v0.39.0 Fixed (c) wide-char = SYMPTOM-SCOPE correction NOT retraction (fix stands for its root; second cause of same visible symptom remained — claim-class≠evidence, the v0.39.3 lesson); EXCLUDE (b) connect-time (different symptom family, would blur attribution). Published text wins over any paraphrase. **✅ RELEASE PR #52 @1cabbb1 — doyle PRE-MERGE CHECK PASS + GO SENT 2026-07-21:** 3 files, 1 toml line, 11 first-party lock lines zero third-party (quick-xml coincidental-0.39.4 third-party untouched), ladder contiguous, counter 72, both Corrected quotes VERBATIM-verified against published bodies in-file, all four surfaces faithful, no barrier vocab. deployah merges on green → tag → sign/publish 72 → doyle notifies hertz for two-seam field verify.

**⭐⭐ GATE ROUND 2 VERDICT: WHOLE-BRANCH PASS @b6bd80a (doyle, 2026-07-21). Verdict SENT to todlando (SENT live) — open the PR.** Branch grew two doc-only commits after the battery started (bccace5 = Finding 3 fix, b6bd80a = cold-attach-residual recording); doyle verified BOTH against the rulings before passing them (bccace5: authority-survives-reap doc + pointers to broker.rs:1995 stamp_reaped comment and unit broker.rs:6829, all present and accurate; b6bd80a: residual at repaint_initial + REQ text, accepted/refused/seed all verbatim). Doc-only delta confirmed ⇒ battery coverage carries 94fcae0→b6bd80a. **Battery results + the two snags that were NOT the branch:** (1) daemon+term leg 1171/1172 — the one red (`spt-daemon::xfer fetch_lands_byte_identical_with_progress_both_ends`, 2.5s) is environmental: zero seam overlap (xfer never enters resize/OutputLog paths), 20/20 green on a 10x loop after; six leaked main-target spt.exe daemons were live on the box during that window. (2) spt-crate leg: 25 fail-fast e2e reds = **RIG DEFECT bite #6** — battery never prebuilt fixture bins into the throwaway target, `mock-session.exe` missing, every mock-adapter e2e died at spawn in <0.2s. Leg was UNJUDGED, not red. After `cargo build -p mock-adapter -p spt`: all 25 + api::startup::a_listener_over_a_dead_pty + both xfer = **33/33 PASS**. [[gate-rig-mechanisms-not-remembered-steps]] updated: leg 0 of every battery is now `cargo build --workspace` (clippy check profile emits NO exes — a green clippy leg proves nothing about fixture presence). Pre-existing heads-up passed to todlando: main's last CI run (#43) is red on `reap::tests::job_reaps_enrolled_child_and_grandchild` (single 0.5s flake-shape, not this branch's problem, but it may red the PR baseline). Cleanup: gate-a3bb6bb worktree removed; gate-94fcae0 remnant was conhost-pinned (2 orphans, dead parents — the backlog's conhost RCA shape, found via findcwd.ps1 PEB probe) → scoped-killed + deleted; throwaway target deleted. Cleanup COMPLETE. **✅ PR #44 MERGED to main @c6770bd 2026-07-21 (doyle).** CI round 1 at b6bd80a: 3 reds — 1 OURS (rig race: the dead-PTY listener rig keyed on relay address, but listen writes relay→establish_perch-rewrite→online-stamp, so a reconcile in the window skips the row at the status gate; product self-heals next tick; fixed test-only @1e003d8, doyle verified test-only) + 2 environmental (shell_e2e ENOTEMPTY teardown race Linux; port-5474/leaked-daemon class Windows — todlando swept the six 03:11 daemons). CI round 2 at 1e003d8: TWO LEGS GREEN, all checks, baseline reap-flake absent both runs. **BUILD LANE CLOSED.** **✅ RELEASE PR #45 (v0.39.1, counter 69) — doyle PRE-MERGE CHECK PASS + GO 2026-07-21.** deployah verified the relayed GO DIRECT (standing rule held), counter 69 self-verified from published metadata. Two doyle changelog rulings: (1) NEW '### Known' subsection KEPT — operator-accepted cold-attach residual published in user-observable words only (no epoch/barrier vocab); (2) meta-reference to 0.39.0's NOTES dropped — continuity carried in behavior words ('a resize could STILL leave the screen garbled… damage persisted into later attaches'), no citation. Ceremony verified on the diff: 3 files, Cargo.toml + 11 first-party lock lines zero third-party, ladder contiguous, 3 Fixed + 1 Known + 1 Internal (#43 correctly in-range — merged after 0.39.0 published). deployah merges on green → tag → sign+publish 69 → **hertz field-verify BOTH seams in one pass from Latest (readable-prose exact cell fidelity + bind→listen→control→detach).**
