@@ -201,7 +201,10 @@ the TUI exists ends the launch gracefully and leaves no record — nothing was
201201observed — while a stop after it exits through the ordinary terminal-write
202202path — and the stop handler installs before ANY child is spawned, the
203203hook-trust preflight's detached app-server included, so a stop in that window
204- cannot leak a server around a dead wrapper. A projected transition whose
204+ cannot leak a server around a dead wrapper. Observability never kills a
205+ launch: a claim that cannot be written degrades to a token-only writer with
206+ a warning, a TUI that fails to spawn writes a real terminal record (ended,
207+ launch-error) over the claim placeholder, and a projected transition whose
205208record write fails does not count as evidence: it is retained as pending and
206209retried on EVERY pump pass (only the heartbeat is presence-cadence work), so
207210a stale on-disk state is never kept fresh in contradiction of the latest
@@ -242,12 +245,16 @@ survive every materialization, while st2's own prior entries — recognizable
242245by the hook root they reference — are superseded on a hook-set upgrade
243246rather than accumulated. Hook writes carry the wrapper's exported
244247incarnation token, so a hook finishing after the wrapper reaped Claude
245- cannot replace the terminal record. A hooks-only seat (the maintained
246- hand-authored example launches claude directly) gets transitions and
247- blocked-on-you but no heartbeat owner and no terminal record: a live-but-
248- idle seat ages to ` unknown ` and an exit leaves its last state to age out —
249- indeterminate, never wrong — until the seat is routed through the session
250- wrapper.
248+ cannot replace the terminal record. Legacy ` deliver "mcp" ` seats render the same
249+ canonical registration — they run under claude-session too, and a wrapper
250+ that claims and ends a record nobody transitions would be worse than no
251+ record. A hooks-only seat (the maintained hand-authored example launches
252+ claude directly) gets transitions and blocked-on-you but no heartbeat owner
253+ and no terminal record: its ` SessionStart ` performs the written claim so
254+ session succession works (guarded — a wrapperless claimer never supersedes
255+ a live wrapper-kept record, only fellow wrapperless tokens, terminal
256+ records, and staleness), while a live-but-idle seat still ages to ` unknown `
257+ and an exit leaves its last state to age out — indeterminate, never wrong.
251258
252259## pi producer (OHS-R05, OHS-R08)
253260
@@ -294,9 +301,11 @@ evidence (`/session/status` omits idle sessions, so an empty map over a live
294301server is the idle proof, re-read on every SSE (re)connect). Asks open across
295302a reconnect are recovered from both pending listings — ` GET /permission ` and
296303` GET /question ` , each measured on 1.18.19 — with their ids kept so the
297- id-matched exits still release them; the seed counts as successful only when
298- the status level and both listings all succeed, otherwise evidence stays off
299- and the seed retries, and an unrecognized ` session.status ` word is not level
304+ id-matched exits still release them; the seed builds a fresh projection and
305+ swaps it in whole only when the status level and both listings all succeed —
306+ a mid-seed failure leaves nothing half-seeded, a successful re-seed clears
307+ stale entries whose exits passed during the outage, and otherwise evidence
308+ stays off and the seed retries — and an unrecognized ` session.status ` word is not level
300309evidence (a future word must not prove idle on a quiet server). The ` /doc `
301310subset gate names every consumed arm, exit events and pending listings
302311included, so a release renaming an exit is refused up front rather than
0 commit comments