Skip to content

fix: replay undo histories that exceed the rollback boundary - #939

Merged
rynfar merged 2 commits into
mainfrom
codex/fix-undo-history-gap
Sep 4, 2026
Merged

fix: replay undo histories that exceed the rollback boundary#939
rynfar merged 2 commits into
mainfrom
codex/fix-undo-history-gap

Conversation

@rynfar

@rynfar rynfar commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Undo previously resumed at a matching prefix and delivered only the final user message even when the request contained edited intermediate turns. Those turns disappeared from the SDK input. Require the preserved prefix to cover every message before the final user turn, and replay the full request otherwise. If the adjacent rollback UUID is unavailable, use the existing full-replay fallback instead of an older checkpoint that omits intervening turns.

Adds content-free undo-gap diagnostics, five pure regression tests, four HTTP cases, and a repeatable real-SDK E2E gate. Ordinary undo retains its rollback behavior; unsafe boundaries incur a fresh replay to preserve the supplied history.

Validation:

  • Before the fix, the canonical-path real-SDK fixture returned the original fact after the request supplied an edited intermediate fact; the revised fact was absent from SDK input. Four new pure regression cases also failed.
  • After the fix, ordinary undo, edited intermediate history, and a missing adjacent UUID pass with real Claude Max in both streaming and non-streaming modes. The gate checks SDK input, model answers, an actual ordinary rollback, and source-session immutability. Its source session is created through supported SDK APIs and seeded into Meridian with valid historical UUIDs.
  • All four E41 passthrough combinations pass: sequential/parallel tool calls, streaming/non-streaming.
  • npm test: 3,306 passed, one existing skip, zero failures. npm run typecheck and npm run build passed.

CI also exposed an existing test race: the cancellation test assumed request setup finished within 40 ms. A separate test-only commit reproduces it with a 75 ms delayed body, waits for actual SDK queue admission before cancelling, and always releases the holder. The delayed case failed before that correction and passes afterward. The final full local suite again passes all 3,306 tests (one existing skip).

Fixes #817.

@rynfar
rynfar merged commit 4135922 into main Sep 4, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Undo delivery drops history when the prefix overlap doesn't reach the final message

1 participant