Skip to content

fix(claude-sdk-oauth): harden persisted restart checkpoints - #954

Closed
code-yeongyu wants to merge 1 commit into
mainfrom
fix/issue-6981-headless-continuity-final
Closed

fix(claude-sdk-oauth): harden persisted restart checkpoints#954
code-yeongyu wants to merge 1 commit into
mainfrom
fix/issue-6981-headless-continuity-final

Conversation

@code-yeongyu

@code-yeongyu code-yeongyu commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • replace unbounded persisted message/assistant arrays with a fixed-size prefix digest checkpoint
  • restore restart continuity only when the newest checkpoint is well-formed, followed by its committed assistant ledger entry, and matches the current branch prefix
  • durably invalidate persisted continuity after assistant rewrites, compaction, forks, and tree navigation
  • keep reload-time live bindings authoritative while clearing stale process state on startup/resume
  • strengthen the real two-process probe so full-history replay cannot be mistaken for successful continuation

Why

PR #943 fixed headless Claude SDK OAuth continuation across separate CLI processes. This follow-up hardens that persisted state against stale or malformed checkpoints, branch-history changes, unbounded session growth, and incorrect boundary reuse.

Validation

  • npm run check
  • focused Claude SDK OAuth binding, continuity, reattach, lifecycle, and issue #6981 regression tests
  • real two-process headless restart probe
  • full coding-agent suite from packages/coding-agent with bounded parallelism:
    • 989 test files passed, 4 skipped
    • 8,155 tests passed, 36 skipped
  • unrelated timing-sensitive failures seen under unconstrained workstation contention all passed independently:
    • Cursor process-group transport: 8/8
    • footer reftable debounce: 9/9
    • cross-process OAuth refresh race: 2/2

Relationship

Security and durability follow-up to #943 and issue #6981.


Summary by cubic

Hardened headless claude-sdk-oauth restart continuity by replacing unbounded persisted state with a bounded, ledger-verified checkpoint. Previously we restored from any latest binding array; now we restore only when a well‑formed checkpoint is immediately followed by its committed assistant and the branch prefix digest matches, otherwise we fail closed to avoid stale or cross‑branch resumes (issue #6981).

  • Persist a fixed-size checkpoint: {sdkSessionId, sentCount, sentPrefixHash, lastAssistantUuid, accountName, modelId, systemPromptHash, toolsetHash}; remove persisted sent-hash arrays and assistant maps.
  • Restoration rules: require SHA‑256 fields, bounded text, and the next ledger entry to be the committed assistant; reject malformed entries, rolled-back history, divergent prefixes, and inherited branches.
  • Invalidate persistence on assistant rewrites, compaction, forks, and tree navigation; append durable invalidation entries instead of guessing a boundary.
  • Keep reload-time live bindings authoritative; on non-reload start, clear stale process bindings unless a valid checkpoint exists.
  • Continuity decisions use sentPrefixHash to reattach only the new turn; fallback to flatten with explicit reasons when verification fails.
  • Strengthen the two-process restart probe to fail when history is replayed; add focused tests for persistence, decisions, reattach cloning, and regression #6981.
  • Internal API notes: new sentHashPrefixDigest in session-sync.ts; checkpoint schema changed in session-binding.ts; wiring persists invalidations in session-registry-wiring.ts. No migration required for users.

Written for commit 8f41e06. Summary will update on new commits.

Review in cubic

Persist only bounded, ledger-verified restart checkpoints and fail closed across malformed state, branch rewrites, compaction, forks, and tree navigation. Strengthen lifecycle coverage and the two-process restart probe so full-history replay cannot pass unnoticed.
@code-yeongyu

Copy link
Copy Markdown
Owner Author

Superseded by #959: the five-lane review of this implementation surfaced blocking persisted-state security findings (untrusted session-file lineage authority, fork inheritance, drift reattach, provider-switch persistence). #959 carries the corrected private-sidecar design and closes the same issue.

@code-yeongyu
code-yeongyu deleted the fix/issue-6981-headless-continuity-final branch August 18, 2026 15:11
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.

1 participant