fix: rewind vs compaction boundaries + failed requests as timeline runs (v0.21.0)#51
Merged
Merged
Conversation
Two session-view truth bugs from one real trace pair (2026-07-22):
A /rewind displayed as "compacted": the post-spine anchor walk accepted
a msg[0]-to-msg[0] match with zero verified context — msg[0]'s content
sig is the injected <system-reminder> prefix, identical for every
request in a session — so a rewind-to-start (71 -> 2 turns, only the
first message shared) classified as a fold. The anchor now rejects that
degenerate hit, and the boundary classifier reads index geometry: a
fold's surviving tail aligns at shifted indices (history above it
shrank into a summary), a rewind's shared content is a same-index
prefix. With no anchor at all, a same-sig thread that was never
reunified classifies rewind too — every observed compact shape rewrites
msg[0] and splits the sig (merged continuations are stamped _cont).
The boundary row says "rewound · N -> M turns" with an honest hover;
the real-wire compaction fixture pins fold/rewrite unchanged.
Failed requests (no response / HTTP 4xx-5xx) transiently claimed the
successful retry's turn at strength 1 and then piled up as orphan
"err" rows at the thread tail — a kimi 429 storm rendered 82 unordered
rows. They now collect per timeline position (t.failed), never claim
turns, and render as one collapsed run where the storm hit ("21 failed
requests · 429 engine_overloaded_error"), red dot on the rail, first
wire pair linked, plus a red-edged line in the conversation pane.
Co-Authored-By: Claude Opus 4.8 (1M context) <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.
Two session-view truth bugs reported from one real trace pair, both reproduced and fixed against the actual wire data.
1. A /rewind displayed as "compacted"
The post-spine anchor walk accepted a msg[0]-to-msg[0] match with zero verified context. msg[0]'s content sig is the injected system-reminder prefix — identical for every request in a session — so a rewind-to-start (71 -> 2 turns, only the first message shared, everything after divergent) classified as a fold compaction.
Fix, in two parts:
The boundary renders "rewound · N -> M turns" (rail row + convo divider) with a hover that says what actually happened. Fold and rewrite are unchanged; tests/session-compaction.test.ts (real wire shapes) pins all of it.
2. Failed requests vanish or dump at the tail
Transport/HTTP failures transiently claimed the successful retry's turn at strength 1, then piled up as orphan "err" rows at the thread tail — a real kimi 429 storm rendered 82 unordered rows. Now they collect per timeline position (t.failed), never claim turns, and render as one collapsed run at the exact position the storm hit: "21 failed requests · 429 engine_overloaded_error", red dot on the rail, first wire pair linked, matching red-edged line in the conversation pane.
Verification
Releases as v0.21.0.
🤖 Generated with Claude Code