Skip to content

fix: follow a Claude Code transcript that moved to another project folder - #27

Merged
lr00rl merged 2 commits into
mainfrom
fix/20261023_claude-moved-transcripts
Oct 23, 2026
Merged

lr00rl merged 2 commits into
mainfrom
fix/20261023_claude-moved-transcripts

Conversation

@lr00rl

@lr00rl lr00rl commented Oct 23, 2026

Copy link
Copy Markdown
Owner

Summary

When a session enters or leaves a worktree (EnterWorktree / ExitWorktree / claude --worktree), Claude Code moves its transcript between the two folders' project directories under the same file name. The index treated the old path as a deleted transcript and the new path as a second file of the same session.

Seen on session b6dcd6a5: it went into the integrations-polish worktree and back. The index had two main rows, a frozen 8-turn copy (now missing) and the live 33-turn file. log picked the missing copy ("the transcript is gone from disk"), show counted 40 typed prompts instead of 32, and the agent tree called the copy's $1.26 the main conversation.

Now a file whose account, session, kind and agent match a vanished row, and that starts with the same bytes the row read, is that transcript:

  • at a path the index does not know, the row moves to it and keeps what it read (as Codex moves already do);
  • at a path that already has a row, the vanished row is a stale copy: DropCopy removes it and marks the kept file to be read again from the start, in one transaction.

The transfer ledger follows the file either way. The first commit is a refactor that names the per-file tables once.

Test plan

  • TestMovedTranscriptIsFollowed and TestStaleCopyOfMovedTranscriptIsDropped, both failing before the fix
  • go test ./..., go test -race ./internal/index ./internal/store
  • Copy of the live index: one session changed (1 file re-read, nothing else moved or dropped); log b6dcd6a5 lists 33 turns with costs, 32 typed prompts, total unchanged at $53.61

Forget and a reset each listed the eight tables keyed by file_id. The
next change drops one file's rows as well, so the list lives in one place.
…lder

When a session enters or leaves a worktree, Claude Code moves its
transcript between the two folders' project directories under the same
name. The index took the old path for a deleted transcript and the new one
for a second file of the same session. Session b6dcd6a5 on the author's
machine went into a worktree and back, and ccli ended up with two main rows:
the worktree copy, frozen at 8 turns and now missing, and the live file with
33. log picked the missing one ("the transcript is gone from disk", 8 turns
mostly without cost), and show counted 40 typed prompts instead of 32 and
called the stale copy's $1.26 the main conversation.

A file whose account, session, kind and agent match a vanished row, and
that starts with the bytes the row read, is now taken to be that
transcript. At a new path the row moves to it, as Codex moves already do,
and keeps what it read. At a path that already has a row, the vanished row
is a stale copy: it is dropped and the kept file is read again from the
start, in one transaction, so its replies come back to it. The transfer
ledger follows the file in both cases.

Rejected: picking the present file when a session has two main rows. It
would show the right turns but keep the doubled prompt count and leave the
copy's replies on a row nobody sees.
Tested: go test ./... and -race on index and store; on a copy of the live
index one session changed: log lists 33 turns with costs, 32 typed
prompts, total still $53.61.
@lr00rl
lr00rl merged commit db13190 into main Oct 23, 2026
2 checks passed
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