fix(forwarder): preserve checkpoint history integrity - #261
Conversation
Store checkpoint turns as validated blobs and restore prefetched parent turns so forked conversations retain their replay history and rewind prefix. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep imported Blob references closed across persistence and rewind, while projecting only stable completed steps so restored conversations remain forkable without reviving historical activity.
|
Thanks for the contribution! I’m not sure which awesome developer is behind it. Also, the previous fix for the At this point, I think we should be cautious about changes related to checkpoints. I previously submitted a fix for chat forking, which was actually a checkpoint fix, but the solution wasn’t ideal. I’ll review this PR carefully. Feel free to discuss it here! |
|
Thanks for the follow-up work on checkpoints. After reviewing the latest main, #260, #269, and especially #284 now cover most of the original scope of this PR: Blob-backed checkpoint publication, prefetched Blob import and SHA-256 validation, Blob-only fork restoration, imported turn ID persistence, rewind-prefix handling, completed tool-call merging, and idempotent checkpoint recovery. I’m closing this PR as largely superseded by the upstream checkpoint work. Thanks again for incorporating and extending the fork-context handling. |
Summary
state.json, validate Blob IDs with SHA-256, and restore it across reloadsThinkingMessagesteps and unfinished tool calls from stable checkpoints, while retaining completed tool calls with structured resultsContext
PR #239 added Blob-backed checkpoint turns and fork-context restoration, but imported turn IDs were persisted without the referenced Blob contents. After a restart or later checkpoint update, Cursor could receive turn references whose user-message or step Blobs no longer existed, resulting in errors such as:
Missing user message blob id ...The checkpoint projection also recreated historical reasoning and initial tool-call steps without a stable completed state. Cursor interpreted those restored steps as active, causing completed Thinking or Editing activity to appear as running again in later turns.
This follow-up keeps the original fork-context behavior while enforcing a closed content-addressed Blob graph and projecting only stable completed history.
Verification
go test ./internal/backend/forwardergo vetgit diff --checkRelated to #260; this PR additionally covers imported Blob persistence, legacy dangling-reference recovery, rewind pruning, and stable historical step projection.
Created with Cursor.