Skip to content

fix(server): preserve Claude turn boundaries when rewinding - #611

Merged
incognitojam merged 3 commits into
mainfrom
styal/debug-thread-failure
Oct 2, 2026
Merged

incognitojam merged 3 commits into
mainfrom
styal/debug-thread-failure

Conversation

@incognitojam

@incognitojam incognitojam commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

What Changed

Claude rewind reads the complete saved main-session transcript through the SDK import API and validates each retained user or assistant record against the native fork's original-message reference, type, body, and order. Retained turn boundaries are remapped to the fork's new UUIDs, so subsequent rewinds remain exact.

Why

“Edit from here” rejected valid forks because Claude's conversation reader reconstructed a shorter parent chain, omitting records that remained in the saved transcript. The original message-count check failed even though the native fork preserved all retained turns. Upstream PR #11954 handles system-message differences, but still rejects the reported case because assistant records and earlier turn boundaries are missing from that reader's output.

Validation

  • The isolated native SDK regression fails with the original adapter's retained-boundary error and passes with this fix. It covers disconnected saved history, repeated prompts, steering, tool results, repeated rewind, reset, provider-home isolation, and a subsequent message.
  • Invalid missing, changed, reordered, or unrelated retained conversation is rejected. A read-only check of the reported failed fork successfully remapped all ten retained turns; no private transcript data was added to fixtures or this PR.
  • An isolated web app with separate app and Claude homes, the real SDK, and a synthetic Claude executable completed last-turn rewind, repeated rewind, resend, and reset with file restoration. Removed turns disappeared, restored prompts returned to the composer, subsequent messages completed, and all three reverts persisted successfully with zero rollback failures.
  • 180 focused Claude adapter and checkpoint reactor tests passed from a fresh detached checkout with no pre-existing scratch directories. The fixture creates its own worktree-root scratch directory and resolves filesystem symlinks before deriving Claude project paths. Server typechecking and fork ledger validation passed. Targeted lint reported only two pre-existing unused type imports.

The native desktop and mobile shells and relay/tunnel connections were not separately exercised. They use the same server adapter; this change does not alter client controls or wire contracts.


Written by an agent (Codex, GPT-6).

@github-actions github-actions Bot added the size:L label Oct 1, 2026
@incognitojam
incognitojam merged commit cb7061b into main Oct 2, 2026
23 checks passed
@incognitojam
incognitojam deleted the styal/debug-thread-failure branch October 2, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant