fix(server): preserve interrupted Claude context after revert#25695

merged3
main
fix/issue-25510
opened2d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 1d ago

Problem

After reverting a Claude thread, interrupting a later run could leave the old conversation head pinned. The next run lost the interrupted run's context, and reverting again could make subsequent messages fail with “No message found with message.uuid”.

Change

Clear the pinned Claude conversation head when a stopped turn has written an assistant message to the transcript. Preserve the head when interruption happens before assistant output. This lets the next query resume the updated transcript without discarding the interrupted run.

Scope and approval

Fixes https://github.com/pingdotgg/t3code/issues/25510

Triaged bug via the automated issue flow. GitCafe: #25510.

Verification

  • Red regression test failed on main because the interrupted turn retained the pinned head. Added a second regression covering interruption without assistant output.
  • vp test run apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts: 238 passed. Scoped checks passed after merging main into the branch.
  • Integrated reproduction: Linux, Chromium web client against the real dev server, Claude CLI 2.1.303. Before: interrupted content was forgotten and the next revert produced the missing-message error. After: interrupted content remained available, reverting and sending succeeded, and immediate interruption preserved the prior head.
  • Both isolated reviews returned MERGE; proof audit returned SUFFICIENT. Server-only change; render matrix is empty. No client rendering changes.

Evidence: index and exact revisions, sanitized runtime transcript, red/green test proof. These are the completed preparation run's records; publication did not rerun them. Other providers and native clients were not independently exercised; the implementation changes only the Claude server adapter.

Implementation: claude-opus-5-5 via Claude Code; review and publication: gpt-6.1-sol via Codex and claude-opus-5-5 via Claude Code.

Checks

23 successful · 16 skipped
All checks passed
50f4f0b

Added 3 commits

  • Merge remote-tracking branch 'origin/main' into fix/issue-2551050f4f0b
  • test(server): reproduces issue 25510, interrupted turn keeps stale Claude resume head99e6bcc
  • fix(server): interrupted Claude turn after rollback no longer resumes at the stale headbd826c6
Synced from GitHub

Approvability

Verdict: Approved at 50f4f0b

Macroscope's review found this PR approvable — This is a localized Claude orchestration fix that prevents interrupted turns with emitted output from resuming against a stale rollback head. Focused regression tests cover both output and no-output interruption paths, with no product-default or static-analysis changes.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB−7 B (−0.1%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB−7 B (−0.6%)2.0 KiB✅
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB0 B (0.0%)29.3 KiB✅
ClaudeLive turn messages220 (0.0%)8✅

Baseline: d73fd12 · PR result: 50f4f0b · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

External image Recent review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between d73fd1279a9cbf3ef4677b88b4ad82f0a55583c7 and 50f4f0bb413e59e14c2cd9e5dd2f47a6d3727cd4.

External image Files selected for processing: 2
  • apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts
  • apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.

Walkthrough

The Claude adapter now clears a pinned conversation head after a turn completes or records a native message cursor. Added tests verify head handling and subsequent resumption when an interrupted turn does or does not produce assistant output.

Changes: Claude rollback resumption

Layer / File(s)Summary
Pinned head handling and resumption tests
apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts, apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts
The adapter clears a non-null conversation head when a turn completes or records a native message cursor. Tests check that an interrupted turn with assistant output clears the head, while an interrupted turn without assistant output retains it, and verify how the next turn resumes.

Priority: External image Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: t3dotgg, maria-rcks

Merge Risk: External image Minimal · up to 50f4f

No actionable merge-blocking risk was identified in the rollback-resumption change. It is ready for normal merge checks.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the main change: preserving interrupted Claude context after a revert.
Description checkPassedThe description includes complete Problem, Change, Scope and approval, and Verification sections. It documents the issue, implementation, test results, reproduction results, limitations, evidence, and…
Linked Issues checkPassedIssue [#25510] requires Claude turns that write assistant output before interruption to stop using the stale pinned head, preserve the interrupted context on the next send, and avoid the later missing…
Out of Scope Changes checkPassedThe pull request changes only the Claude server adapter and its focused regression tests. The implementation directly addresses issue [#25510]. The tests cover both required head-clearing and head-pre…
Full details: Description check

Explanation

The description includes complete Problem, Change, Scope and approval, and Verification sections. It documents the issue, implementation, test results, reproduction results, limitations, evidence, and agent details.

Full details: Linked Issues check

Explanation

Issue [#25510] requires Claude turns that write assistant output before interruption to stop using the stale pinned head, preserve the interrupted context on the next send, and avoid the later missing-message failure. ClaudeAdapterV2.ts now clears nativeConversationHeadRef when the turn completes or when nativeMessageCursor is non-null. The added regression test verifies that an interrupted turn with assistant output clears the head and that the next turn omits resumeSessionAt. A second test verifies the required no-output case retains the head. The optional rollback-anchor and user-recovery proposals are not required by the issue.

Full details: Out of Scope Changes check

Explanation

The pull request changes only the Claude server adapter and its focused regression tests. The implementation directly addresses issue [#25510]. The tests cover both required head-clearing and head-preservation behavior. No unrelated provider, client, or feature changes appear in the reviewed diff.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.