Skip to content

fix(session): reconcile worktree path on resume after repo relocation - #1896

Open
gtrrz-victor wants to merge 2 commits into
mainfrom
fix/resume-worktree-path-reconciliation
Open

fix(session): reconcile worktree path on resume after repo relocation#1896
gtrrz-victor wants to merge 2 commits into
mainfrom
fix/resume-worktree-path-reconciliation

Conversation

@gtrrz-victor

@gtrrz-victor gtrrz-victor commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

https://entire.io/gh/entireio/cli/trails/969

Fixes #1890.

Problem

A session records SessionState.WorktreePath once at start, and the commit-time
matcher (findSessionsForWorktree) uses exact string equality. When the repo
directory is renamed/moved while the session is stopped and the agent resumes it
(Claude Code's own /resume) from the new location, the recorded path no longer
resolves — every commit silently loses its Entire-Checkpoint trailer. #1440's
sibling-worktree fallback doesn't cover a whole-repo move: the old path is gone,
so nothing matches.

Fix

Reconcile on the resumed turn. When a turn starts from a worktree that differs
from the recorded one and the recorded path no longer resolves to this repo's
git common dir, repoint WorktreePath/WorktreeID at the current worktree. The
session store lives in the common dir, so a loaded state is the same repo by
construction. A recorded path that still resolves to this repo (a live sibling
worktree) is left untouched — a session is never stolen from a concurrent sibling.

Test plan

  • RED→GREEN integration test (resume_repo_rename_test.go): start session →
    rename repo folder → resumed turn → commit still gets its trailer. Confirmed
    failing before the fix, passing after.
  • Guard unit tests: relocation reconciles; live sibling untouched; same-path no-op.
  • Full integration suite green; strategy pkg green; lint clean.

Scope

Reconciliation only. Follow-ups from the issue (WARN on zero-match, adopt
without a live --from, doctor flagging stale paths) are deliberately left to
separate PRs.

🤖 Generated with Claude Code


Note

Medium Risk
Changes session-to-worktree matching at turn start, which directly affects whether commits get checkpoint trailers; guards limit updates to stale paths that no longer resolve to the repo.

Overview
Fixes #1890: after the repo folder is renamed while a session is stopped, resumed turns no longer lose Entire-Checkpoint trailers because WorktreePath still pointed at the old path and findSessionsForWorktree only exact-matches.

On each existing-session turn start (InitializeSession), the PR calls reconcileWorktreePathForResumedTurn. When the current cwd differs from the stored path and the stored path no longer resolves to this repo’s git common dir, it updates WorktreePath and WorktreeID to the current worktree. If the recorded path is still a valid sibling worktree of the same repo, it is left unchanged.

Coverage: unit tests for relocation, sibling guard, and no-op; integration test that renames the repo, resumes, commits, and asserts the checkpoint trailer is present.

Reviewed by Cursor Bugbot for commit 5d71aad. Configure here.

A session records SessionState.WorktreePath once at start, and the
commit-time matcher (findSessionsForWorktree) uses exact string equality.
When the repo directory is renamed/moved while the session is stopped and
the agent resumes it (Claude Code's own /resume) from the new location,
the recorded path no longer resolves and every commit silently loses its
Entire-Checkpoint trailer (#1890). #1440's sibling-worktree fallback does
not cover a whole-repo move: the old path is gone, so nothing matches.

Reconcile on the resumed turn: when a turn starts from a worktree that
differs from the recorded one AND the recorded path no longer resolves to
this repo's git common dir, repoint WorktreePath/WorktreeID at the current
worktree. The session store lives in the common dir, so a loaded state is
the same repo by construction. A recorded path that still resolves to this
repo (a live sibling worktree) is left untouched, so a session is never
stolen from a concurrent sibling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 01KZ6BP5N2Y8NHC85KT283C7SW
Copilot AI lite review requested due to automatic review settings August 4, 2026 12:27
@gtrrz-victor
gtrrz-victor requested a review from a team as a code owner August 4, 2026 12:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Ready to approve

The reconciliation logic is narrowly scoped with a clear safety guard (common-dir validation) and is backed by both unit and integration coverage for the reported regression.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Fixes a session-to-worktree mismatch that occurs when a repository is relocated (renamed/moved) while a session is stopped, then resumed from the new path. The change reconciles SessionState.WorktreePath (and WorktreeID) at turn start so commit-time session matching continues to find the session and append the Entire-Checkpoint trailer.

Changes:

  • Reconcile a session’s recorded worktree path on turn start when the stored path no longer resolves to the current repo’s git common dir (repo-relocation case).
  • Add unit coverage for relocation reconciliation, sibling-worktree non-stealing guard, and same-path no-op.
  • Add an integration test reproducing repo rename + resume + commit trailer linkage.
File summaries
File Description
cmd/entire/cli/strategy/manual_commit_session.go Adds worktree-path reconciliation logic gated by git-common-dir resolution to handle repo relocation without stealing sibling sessions.
cmd/entire/cli/strategy/manual_commit_hooks.go Invokes reconciliation during InitializeSession turn-start mutations for existing sessions.
cmd/entire/cli/strategy/manual_commit_reconcile_worktree_test.go Adds unit tests covering relocation repointing, sibling guard, and no-op behavior.
cmd/entire/cli/integration_test/resume_repo_rename_test.go Adds an integration RED→GREEN repro for #1890 verifying commits after rename/resume still get Entire-Checkpoint trailers.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Reconcile repointed WorktreePath *and* WorktreeID at the current worktree
on a resumed turn. The shadow branch is keyed on WorktreeID
(entire/<base>-hash(worktreeID)), so when a linked-worktree session was
resumed from the main worktree after a repo move, WorktreeID flipped
"<name>" -> "" and every prior checkpoint became unreachable to migrate,
GetRewindPoints, ListCheckpoints, and condensation — silently losing the
session's rewind history.

Repoint WorktreePath only; retain the original WorktreeID so the existing
shadow branch stays reachable. Reconcile fires only once the recorded path
is gone, so keeping the ID cannot collide with a live sibling worktree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 01KZ8SY50KYND90FY5ARZWPFTR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants