Skip to content

claude-sdk-oauth: the continuity binding is never persisted, so every restart re-sends the full history (registry_miss) #808

Description

@1vivy

What happened?

session-binding.ts implements branch-local binding checkpoints for restart-time resume:
latestBindingOnBranch() reads claude-sdk-oauth-binding custom entries back off the session
branch, and verifyBindingAgainstTranscript() turns one into a reattach. The extension's
AGENTS.md documents the file as "Branch-local binding checkpoint for restart-time resume
verification".

Nothing calls either function, and nothing ever writes a claude-sdk-oauth-binding entry. The
module's only commit, db8e8cfeb, added the module and its unit test — 2 files, 160 insertions,
no call sites. The unit test is the sole consumer.

The binding store that actually runs is const bindings = new Map() in session-reattach.ts.
Process memory. After a restart both the registry entry and the binding are gone, so
decideNativeContinuity returns { kind: "bootstrap" } and the lane flattens. session-stream.ts
synthesizes the reason as registry_miss because bootstrap carries none, and since firstTurn
is false session-observability.ts reports the kind as flatten.

The user-visible result on a 697-message session: resent the full conversation (registry_miss),
68.0KB, ~60K tokens re-billed, on the first turn after every restart.

Steps to reproduce

  1. Run a claude-sdk-oauth session for several turns.
  2. Restart senpi.
  3. Send one more turn in the same session.
  4. The continuity notice reports a full re-send with reason registry_miss.

grep -c claude-sdk-oauth-binding <session>.jsonl returns 0, confirming no checkpoint was ever
written.

Expected behavior

A restart should resume rather than re-send. The checkpoint is written as the turn commits and
consulted when the in-memory registry misses, so the first turn after a restart is a delta.

This is distinct from #691 (assistant_rewritten from thinking timing) and #790
(sent_stream_diverged from content-less user messages). Both of those fix divergence within a
live process; neither addresses a cold start, and unlike them this one has no workaround.

Version

@code-yeongyu/senpi 2026.8.11-2
@anthropic-ai/claude-agent-sdk 0.3.220
provider claude-sdk-oauth · model claude-opus-5

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions