# Serialize same-store session adoption

`20429fc`→[main](/content/gh/entireio/cli/commits/main/index.html)·

peyton-alt·3w ago·4 files·+171 added/-15 removed

## Sessions

433a8df1c11aView transcript

## Changes

4

- cmd/entire/cli

- checkpoint

- Mopen.go+3/-1

- Msession_adopt.go+69/-12

- Msession_adopt_test.go+93

- strategy

- Mmanual_commit.go+6/-2

```
54 unmodified lines

}

// Temporary returns the git-backed temporary shadow-branch store.
func (s *Stores) Temporary() TemporaryStore {
	//nolint:ireturn // temporary store capability is the abstraction boundary
return s.temporary
}
```

Mcmd/entire/cli/checkpoint/open.go+3/-1

```
17 unmodified lines

}
```

Mcmd/entire/cli/session_adopt.go+69/-12

```
767 unmodified lines

}
```

func TestSessionAdopt_SameStoreReloadsSourceStateUnderLock(t *testing.T) {
sourceRepo := setupAdoptRepo(t)
targetWorktree := filepath.Join(t.TempDir(), "target-worktree")
runAdoptGit(t, sourceRepo, "worktree", "add", targetWorktree, "-b", "target-worktree")
resolvedTargetWorktree, err := filepath.EvalSymlinks(targetWorktree)
if err != nil {
t.Fatal(err)
}
targetWorktree = resolvedTargetWorktree

t.Cleanup(func() {
runAdoptGit(t, sourceRepo, "worktree", "remove", targetWorktree, "--force")
})

sourceWorktreeID, err := paths.GetWorktreeID(sourceRepo)
if err != nil {
t.Fatal(err)
}
targetWorktreeID, err := paths.GetWorktreeID(targetWorktree)
if err != nil {
t.Fatal(err)
}

sessionID := "test-adopt-same-store-reload"
lastInteraction := time.Now().Add(-1 * time.Minute)
sourceStore := session.NewStateStoreWithDir(filepath.Join(sourceRepo, ".git", session.SessionStateDirName))
if err := sourceStore.Save(context.Background(), &session.State{
SessionID: sessionID,
AgentType: agent.AgentTypeClaudeCode,
StartedAt: time.Now().Add(-5 * time.Minute),
LastInteractionTime: &lastInteraction,
Phase: session.PhaseActive,
BaseCommit: testutil.GetHeadHash(t, sourceRepo),
WorktreePath: sourceRepo,
WorktreeID: sourceWorktreeID,
LastPrompt: "stale prompt",
SessionTurnCount: 1,
}); err != nil {
t.Fatal(err)
}
staleSelected, err := sourceStore.Load(context.Background(), sessionID)
if err != nil {
t.Fatal(err)
}
if err := sourceStore.Save(context.Background(), &session.State{
SessionID: sessionID,
AgentType: agent.AgentTypeClaudeCode,
StartedAt: time.Now().Add(-5 * time.Minute),
LastInteractionTime: &lastInteraction,
Phase: session.PhaseActive,
BaseCommit: testutil.GetHeadHash(t, sourceRepo),
WorktreePath: sourceRepo,
WorktreeID: sourceWorktreeID,
LastPrompt: "fresh hook prompt",
SessionTurnCount: 9,
}); err != nil {
t.Fatal(err)
}

testutil.WriteFile(t, targetWorktree, "feature.txt", "agent change\n")
testutil.GitAdd(t, targetWorktree, "feature.txt")
t.Chdir(targetWorktree)

adopted, _, err := adoptFromSameSessionStore(context.Background(), sourceRepo, staleSelected, adoptOptions{
Force: true,
})
if err != nil {
t.Fatalf("adoptFromSameSessionStore failed: %v", err)
}
if adopted.LastPrompt != "fresh hook prompt" {
t.Fatalf("adopted LastPrompt = %q, want fresh hook prompt", adopted.LastPrompt)
}
if adopted.SessionTurnCount != 9 {
t.Fatalf("adopted SessionTurnCount = %d, want fresh source value", adopted.SessionTurnCount)
}

loaded, err := sourceStore.Load(context.Background(), sessionID)
if err != nil {
t.Fatal(err)
}
if loaded.WorktreePath != targetWorktree {
t.Fatalf("WorktreePath = %q, want %q", loaded.WorktreePath, targetWorktree)
}
if loaded.WorktreeID != targetWorktreeID {
t.Fatalf("WorktreeID = %q, want %q", loaded.WorktreeID, targetWorktreeID)
}
if loaded.LastPrompt != "fresh hook prompt" {
t.Fatalf("loaded LastPrompt = %q, want fresh hook prompt", loaded.LastPrompt)
}
if loaded.SessionTurnCount != 9 {
t.Fatalf("loaded SessionTurnCount = %d, want fresh source value", loaded.SessionTurnCount)
}
}

func TestSessionAdopt_MovesSameStoreSessionIntoCurrentWorktree(t *testing.T) {
sourceRepo := setupAdoptRepo(t)
targetWorktree := filepath.Join(t.TempDir(), "target-worktree")

```

Mcmd/entire/cli/session_adopt_test.go+93

```
51 unmodified lines

}

Mcmd/entire/cli/strategy/manual_commit.go+6/-2

```
51 unmodified lines
