Files
turnstone/scripts
Patrick Buckley fac2393967 fix(#894): re-derive the render gate on DOM-live signals; drop the busy conflation
Review round 5 step-back (fix-era critical): the r4 gate's busy term
conflated 'a turn is executing' with 'this DOM holds live turn state'.
_editAndResend flips busy BEFORE its POST and /rewind emits only
clear_ui (no state_change), so the busy term skipped the truncation
render the rewind exists to produce and appended the resent bubble onto
the PRE-rewind transcript; /retry's regenerated turn likewise raced its
own clear_ui refetch.  The seam was re-derived once against the caller
x state matrix; the gate reads DOM-live signals only, split by scope:

- UNIVERSAL: dispatch seq (refetchSeq — overlapping fetches resolve
  last-DISPATCH-wins; an older snapshot landing late can neither
  double-render nor clear the latch over newer truth) and the content
  refs (skipping always beats stranding a ref; seeded callers null
  theirs before fetching, so it never blocks them).
- SEEDLESS-ONLY (keyed on the seedCursor arg): the
  .conv-batch--running DOM marker for the tool phase (NOT activeBatch —
  that is the pending-APPROVAL tracker, set only for opts.pending
  batches; ruled at-site), coordSend's busySource === 'optimistic'
  flavor (the one busy that marks un-committed DOM), and
  stream-OPENness (CONNECTING keeps the handle with a frozen cursor
  and a pending replay; handle-existence was not liveness — also
  applied to the retry's fire guard).  Seedless-only because the
  SEEDED resync renders over these deliberately: after a node dies
  mid-batch the --running class is dead residue no result will ever
  strip, and the resync's render IS the recovery — a universal term
  wedged the coord-restart scenario outright (family-run find; the
  r5 finders missed the seeded-path interaction).

Backstop comment corrected (r5): fresh/truncated SSE replays DO carry
a synthetic state_change (replay_ok does not) — a latched pane pays one
refetch per reconnect, bounded by reconnect jitter/backoff and #884's
server single-flight; heal-caused triggers remain structurally
impossible.  Caller fire-time ref guards demoted to the efficiency
layer at-site.  Contract test re-pins the gate: term presence in
comment-stripped CODE, universal-vs-seedless placement, wipe between
failure guard and latch-clear, no plain busy.  The edit-resend commit
gap under a second actor's clear_ui is accepted at-site (re-appears at
settle heal).  G4's honesty note names the tool-phase branch it
behaviorally detects; G5 wording replay_ok-precise.  Full coord family
(C + G1-G5) green; 136 pins green; 5 static mutants + the G4
behavioral control caught.
2026-07-24 15:04:31 -07:00
..