Skip to content

fix(sessions): resume lands on a usable account and finds its conversation (v0.469.3) - #897

Merged
vikasprogrammer merged 1 commit into
mainfrom
feat/resume-orphan-transcript
Nov 10, 2026
Merged

vikasprogrammer merged 1 commit into
mainfrom
feat/resume-orphan-transcript

Conversation

@vikasprogrammer

Copy link
Copy Markdown
Owner

Problem (instawp, 2026-11-10)

An expired runtime account (vikas) was re-added under the same name. Every session that had run on it broke on resume:

  • Blank conversation. The guided login moved the old credential dir aside to vikas.orphan-<ts>, taking the transcripts with it. Nothing searched that dir, so claude --resume found nothing and the launcher fell back to --session-id, which re-seeded the original prompt. A 4-day, 102-turn session re-opened empty.
  • "Not logged in · Please run /login". Credentials bind at launch, so every resurrect replayed CLAUDE_CONFIG_DIR=…/vikas even though vikas had left the pool. Two healthy accounts sat idle meanwhile.
  • The pre-flight didn't catch it. The re-added dir's .credentials.json held only mcpOAuth. With no expiry field it read as healthy.

Fix

  • refreshTranscriptRoots also registers runtime-accounts/<runtime>/*.orphan-*.
  • New POST /api/resume-prepare (session-secret loopback, fails open), called by claude-launch.sh on every RESUME=1 before the credential pre-flight:
    • repinResumeAccount: if the pinned dir has no pool owner, its account is disabled, or it holds no usable login, pick a usable oauth account, rewrite the launch env and the row, and audit runtime.account.rotated with reason: resume: …. The launcher exports the returned dir.
    • stageResumeTranscript: copy the newest transcript into the target dir when it's missing there. It never overwrites a copy in place, and it writes only into a pool dir or the box default. Audits session.transcript.staged / session.transcript.missing.
  • isDeadCredential: a record with neither an access nor a refresh token is dead (expiresAt: 0).

Verification

  • scripts/resume-transcript-stage-test.cjs: 29 checks, added to test:governance.
  • Full npm run test:governance green, plus typecheck and both bundles built.
  • Live: both affected instawp sessions were repaired by hand (transcript restored, env repointed) and resumed with full context.

🤖 Generated with Claude Code

…ation (v0.469.3)

Re-adding a runtime account moved its old credential dir aside to
`<name>.orphan-<ts>`, stranding every transcript made under it, and
every resume stayed pinned to the dead account. Sessions came back as
"Not logged in · Please run /login" or as a blank conversation under
their own id.

- archived credential dirs are transcript roots
- every RESUME=1 launch calls POST /api/resume-prepare before the
  credential pre-flight: it moves the resume off an account that can no
  longer sign in, then stages the transcript into the dir it will run under
- a .credentials.json holding no access/refresh token (only mcpOAuth)
  now reads as dead instead of healthy

Pinned by scripts/resume-transcript-stage-test.cjs (in test:governance).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vikasprogrammer
vikasprogrammer merged commit 7b6314f into main Nov 10, 2026
1 check passed
@vikasprogrammer
vikasprogrammer deleted the feat/resume-orphan-transcript branch November 10, 2026 07:08
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