step-backs survive the wake boundary — reply gate + digest line - #14
Open
Octember wants to merge 5 commits into
Open
step-backs survive the wake boundary — reply gate + digest line#14Octember wants to merge 5 commits into
Octember wants to merge 5 commits into
Conversation
Live 2026-08-10: a fresh wake posted into a thread she'd stepped out of 33 minutes earlier, contradicting a decision two humans had just settled, without reading it. Every wake is a fresh session; nothing carried her own choice to leave, and nothing made her look before speaking. - reply now bounces the first send into a stepped-back thread with her recorded why and the thread's current tail (threadTailBefore, reused); a repeat send is her informed call and goes through, re-engaging as any post does. Same shape as the §5.5 withhold, keyed on thread state instead of batch timing. - stepped_back effects ride outboundEffectsSince, so the next wake's [what you did recently] and the ear's own-voice digest both show she just left a conversation, and why. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
First-principles pass over the 2026-08-10 incident surfaced two more holes, one of them in the fix I shipped an hour ago: - The retry loop reused one toolset across attempts, so a step-back bounce consumed by a dead attempt disarmed the gate for the retry — a fresh session that never saw the bounce would post straight through. Toolsets now build per attempt (each retry re-decides against re-armed tools); shared wake state (effects, stream, answered, checklist holder) is hoisted and survives rebuilds. Test proven to fail against the old code. - The deeper asymmetry: since 2026-07-30 the ear reads every batch with the already-heard tail of the threads it touches, but the wake that SPEAKS still judged bare lines — at 18:10 that was two lines of new chatter and no surrounding conversation. The tail builder is extracted (threadTailContext) and now rides both prompts; the correction she contradicted would have been in her context. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nthesis) Product of a 21-agent workflow: 5 ground-truth readers (SPEC/design-doc audit, wake dataflow inventory, ledger state-smear map, live VM traffic numbers, patch archaeology), 4 independent architects on divergent theses, 12 adversarial judge passes replaying the full 12-incident catalog against each design. All four architects converged on the same spine: the conversation as the ledger unit (per-conversation watermarks replacing both global cursors), judgment co-located with delivery (holds as rows, not discarded verdicts), one renderer for both readers with her own posts in the event stream. The doc records what survived, what the judges killed and why (so it doesn't get relitigated), the bankruptcy list of ~15 mechanisms retired, and a 4-phase migration where P0 is an afternoon and needs no schema. PROPOSAL status — SPEC.md unamended until the operator blesses it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e envelope Two afternoon-sized changes the redesign judges found carry most of the measurable wake/failure cost, independent of everything else in the proposal: - An identical repeat of a task's previous worker report still lands durably in events (rides the next wake — nothing dangles) but no longer forces a wake. A stuck task re-reporting "waiting on a human" cannot drag the mind out of bed for it (2026-08-10: that exact wake posted stale into a settled thread). - Envelope turns now carry the existing stall watchdog (turns.stall_timeout_ms, default 45s): a runtime with no activity dies early as a FAILED attempt the retry loop covers, while honest streaming work keeps the full envelope. One number was measuring "gateway blackholed" and "long job" — opposite conditions (2026-07-27 starvation, 2026-08-10 full-envelope burns). Fail-safe: a session without msSinceLastActivity never stalls. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…delivery consumes First structural cut of the one-room redesign (specs/2026-08-10-one-room-redesign.md). New ledger unit: one row per (identity, venue, thread root) with per-conversation delivered/judged watermarks (CHECK judged >= delivered — cursor skew unrepresentable), a holds count, a BOUNDED hold-why history (never a single latest-wins why), and the ear's wake-why. - An ear hold writes the row instead of dying with the verdict. A wake consumes each batch conversation's accumulated judgment in the same transaction that advances its watermark: a wake structurally cannot take a conversation's messages and leave the reads that held them behind. The 18:10 shape — four discarded "this is settled" holds, then bare lines delivered to a fresh session — is now a regression test. - Wake-whys with a venue land on the row (durable) instead of the consumed-once RAM earNotes map; the RAM path survives only for venue-less notes. - Migration v12 seeds rows from existing events at the global cursors: nothing re-delivers on upgrade. P1b flips delivery itself onto the per-conversation watermarks and moves her own posts into the event stream; P2 retires the PR #14 gate for the rendered-set bounce. Net-code trend: this table is what makes resident_cursor, ear_cursor, thread_participation, earNotes, unsentDrafts, and both digests deletable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What happened (live, 2026-08-10)
A resident wake posted "these aren't duplicates… 4782 should be reopened" into a thread where two humans had just settled the opposite — 33 minutes after she herself had stepped out of that thread with the reason "a stale reply would reopen settled triage." The wake was a fresh session: the step-back wasn't in its digest, nothing gated the post, and her own post cleared the step-back bit (
threads.tsre-engage-on-post).Full trace in the session ledger/rollouts: wake triggered by an unrelated task update; batch carried two raw lines with no thread context; one
linear_read; reply queued without ever reading the thread.Fix
Two of the four gaps from the incident (the ear-hold delivery annotation and task hygiene are follow-ups):
Reply gate on stepped-back threads (
toolset.ts): the firstreplyinto a currently stepped-back thread doesn't send — it returns her recorded step-back reason plus the thread's current tail (threadTailBefore, reused from the ear). Sending again is her informed call and goes through, re-engaging the thread as any post does. Same shape as the §5.5 withhold, keyed on durable thread state instead of batch timing. One bounce per thread per turn.Step-backs ride the digest (
turns.ts,service.ts):stepped_backeffects now come back fromoutboundEffectsSince, so the next wake's[what you did recently]and the ear's own-voice section both show she just left a conversation and why.Prompt/tool-side only — the harness still never posts.
Tests
resident.test.ts: bounce carries why + tail, bounced text never lands, informed re-send posts; mention re-engagement skips the gate; step-back appears in the next wake's digest.threads.test.ts:steppedBackStatelifecycle (engaged → stepped back → cleared by re-participation).turns.test.ts:outboundEffectsSincerecovers posted/reacted/stepped_back.bun run checkgreen (391 tests). Note: neededbun installlocally —node_moduleshad agent-tools 0.4.0 against the 0.5.0 lockfile.🤖 Generated with Claude Code