Repository navigation
Cursor ref-less checkpoint lookup can reuse another conversation's state #2559
Description
Client or integration
Codex App and other Responses clients using the Cursor provider adapter
Area
Provider adapter
Summary
On current dev (e1fb6755951c82fc0fc137820d2b40208d79e918), a request without an explicit checkpointRef can reuse a live Cursor checkpoint from a different conversation.
getCursorCheckpointForPrefix(...) requires a unique prefix digest and matches the system digest, covered-message count, credential identity scope, and model affinity. It does not match conversationId. resolveCursorCheckpoint(...) then enforces conversation equality only when an explicit ref exists.
At the same time, resolveCursorConversationId(...) generates a fresh provider conversation ID when neither _cursorConversationId nor a stable client-thread owner is available. The generated conversation can therefore import the sole matching checkpoint from another conversation.
The checkpoint is provider conversation state rather than a content-addressed prompt cache. Reusing it can carry prior conversation structure, summaries, tool/subagent state, and file-related state into an unrelated request.
Expected safety boundary:
- An explicit checkpoint ref keeps the existing conversation, identity, model, lineage, and health checks.
- Ref-less prefix lookup is allowed only when the request already has a stable owner: a remembered
_cursorConversationId, a non-empty parent_clientThreadId, or the existing bounded process-local HMAC derived from the complete Desktopsession-idandthread-idpair. - The selected snapshot must match the resolved request
conversationId. - A ref-less request with no stable owner fails closed to full replay; content-prefix uniqueness alone is not ownership authority.
- Isolated helper turns do not reuse parent or sibling checkpoints.
- The Desktop fallback is Cursor-only: it does not widen Responses replay scope or persist raw headers.
This is the still-applicable first P1 finding left on merged PR #2277: #2277 (comment)
Reproduction
- Under one Cursor credential scope and model, complete conversation A whose first user message has a unique prefix, then commit its
ConversationStateStructurecheckpoint. - Start unrelated conversation B without a continuation ref or stable client-thread identity.
- Give B a history beginning with the same user prefix plus a later suffix.
- Observe B enter
checkpointmode with A's checkpoint bytes even though B has a different generatedconversationId.
Regression coverage for the fix should:
- reject a unique matching prefix from a different conversation;
- preserve ref-less reuse for stable
_cursorConversationId, parent-thread, and bounded Desktop session/thread owners; - preserve forced-fresh recovery with the Desktop owner;
- select the owned snapshot when multiple conversations share one prefix;
- avoid refreshing TTL/LRU for unrelated same-prefix snapshots;
- full-replay when no stable owner exists; and
- preserve explicit-ref behavior and helper isolation.
Version
dev at e1fb675
Operating system
Cross-platform adapter logic; reproduced in source-level tests on Windows 11
Provider and model
Cursor / gpt-5.6-sol (the ownership bug is model-independent)
Logs or error output
No runtime error is emitted. The incorrect state reuse is observable through continuationMode=checkpoint and checkpoint bytes belonging to another conversation.Screenshots and supporting files
No screenshot is required for this non-GUI state-isolation defect.
Redacted configuration
{
"provider": "cursor",
"credentialScope": "same-account",
"checkpointRef": null,
"stableClientThreadOwner": null
}Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
github-actions commentedon Aug 25, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
lidge-jun commentedon Aug 25, 2026
Landed via #2563 at 516f566