# fix checkpoint policy enforcement

`5f081d9`·

pfleidi·3w ago·16 files·+468 added/-43 removed

Reject unsupported checkpoint reads and user-driven checkpoint writes consistently.

Resolve policy refs through the configured checkpoint remote and skip checkpoint pushes when local policy state diverges from remote policy.

## Sessions

9fc06b382e3eView transcript

## Changes

16

- cmd/entire/cli
    
  - Mattach.go+4
  - Mattach_test.go+34
  - checkpoint/remote
    
    - Mutil.go+51/-21
  - Acheckpoint_policy_write.go+26
  - checkpointpolicy
    
    - Mpolicy.go+31/-2
    - Mremote.go+5
    - Mremote_test.go+36/-1
  - Mexplain.go+5/-2
  - Mexplain_export.go+7
  - Mexplain_export_test.go+86
  - Mexplain_test.go+74/-4
  - Mresume.go+16/-5
  - Mresume_test.go+16/-4
  - Mrewind.go+20/-4
  - strategy
    
    - Mcheckpoint_policy.go+15
    - Mcheckpoint_policy_test.go+42

```
227 unmodified lines

228
229
230
231
232
233
234
235
236
237

227 unmodified lines

return nil
 }

if err := ensureCommittedCheckpointWritePolicy(ctx, repo); err != nil {
 return err;
 }

// Resolve agent and transcript path.
 ag, transcriptPath, err := resolveAgentAndTranscript(logCtx, w, sessionID, agentName, existingState)
 if err != nil {
```

Mcmd/entire/cli/attach.go+4

```
20 unmodified lines

21
22
23
24
25
26
27
41 unmodified lines

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

20 unmodified lines

"github.com/entireio/cli/cmd/entire/cli/agent/types";
 cpkg "github.com/entireio/cli/cmd/entire/cli/checkpoint";
 "github.com/entireio/cli/cmd/entire/cli/checkpoint/id";
 "github.com/entireio/cli/cmd/entire/cli/checkpointpolicy";
 "github.com/entireio/cli/cmd/entire/cli/paths";
 cliReview "github.com/entireio/cli/cmd/entire/cli/review";
 "github.com/entireio/cli/cmd/entire/cli/session";
41 unmodified lines

}
 }

func TestAttachRejectsUnsupportedCheckpointWritePolicy(t *testing.T) {
 setupAttachTestRepo(t)

repoRoot := mustGetwd(t)
 repo, err := git.PlainOpen(repoRoot)
 if err != nil {
 t.Fatal(err)
 }
 if _, err := checkpointpolicy.WriteLocal(context.Background(), repo, plumbing.ZeroHash, checkpointpolicy.Policy{
 CheckpointVersion: "refs-v1",
 CheckpointMinVersion: "branch-v1",
 }); err != nil {
 t.Fatal(err)
 }

sessionID := "test-attach-policy-unsupported"
 setupClaudeTranscript(t, sessionID, `{"type":"user","message":{"role":"user","content":"create a file"},"uuid":"uuid-1"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"Done"}]},"uuid":"uuid-2"}`)

var out bytes.Buffer
 err = runAttach(context.Background(), &out, sessionID, agent.AgentNameClaudeCode, attachOptions{Force: true})
 if err == nil {
 t.Fatal("expected unsupported checkpoint policy error")
 }
 if !strings.Contains(err.Error(), `checkpoint_version "refs-v1"`) {
 t.Fatalf("error = %v, want checkpoint policy version", err)
 }
 if _, refErr := repo.Reference(plumbing.NewBranchReferenceName(paths.MetadataBranchName), true); refErr == nil {
 t.Fatal("metadata branch exists after rejected attach")
 }
 }
 
 func TestAttach_Success(t *testing.T) {
 setupAttachTestRepo(t)
```

Mcmd/entire/cli/attach_test.go+34

```
185 unmodified lines

186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
189
190
191
192
26 unmodified lines

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
48 unmodified lines

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

185 unmodified lines

}
 return "", true, fmt.Errorf("no push URL found: %w", err)
 }
 if strings.TrimSpace(os.Getenv(CheckpointTokenEnvVar)) != "" && isDerivableProtocol(pushInfo.Protocol) {
 // Coerce a derivable (ssh/https) remote to HTTPS so the token applies,
 // keeping the host so enterprise installations stay on their own host.
 // A non-derivable protocol (e.g. entire://) carries a host that isn't a
 // usable HTTPS host, so it's left untouched and falls through to the
 // providerCheckpointURL fallback below.
 // 
 // Keep the port only when the source was already HTTPS. SSH ports
 // (e.g., :2222) don't map to HTTPS ports on the same host.
 port := ""
 if pushInfo.Protocol == ProtocolHTTPS {
 port = pushInfo.Port
 }
 pushInfo = &Info{
 Protocol: ProtocolHTTPS,
 Host: pushInfo.Host,
 Port: port,
 Owner: pushInfo.Owner,
 Repo: pushInfo.Repo,
 }
 }
 pushInfo = checkpointTokenTransport(pushInfo)

checkpointOwner := config.Owner()
 if pushInfo.Owner != "" && checkpointOwner != "" && !strings.EqualFold(pushInfo.Owner, checkpointOwner) {
26 unmodified lines

return pushURL, true, nil
}

// ConfiguredURL returns the configured checkpoint_remote URL without the
// push-owner fallback used by PushURL. The boolean reports whether a
// checkpoint_remote is configured.
func ConfiguredURL(ctx context.Context, remoteName, dir string) (string, bool, error) {
 s, err := settings.Load(ctx)
 if err != nil {
 return "", false, fmt.Errorf("load settings: %w", err)
 }
 config := s.GetCheckpointRemote()
 if config == nil {
 return "", false, nil
 }

remoteURL, remoteErr := GetRemoteURLInDir(ctx, dir, remoteName)
 if remoteErr == nil {
 info, parseErr := ParseURL(remoteURL)
 if parseErr == nil {
 if checkpointURL, deriveErr := deriveCheckpointURLFromInfo(checkpointTokenTransport(info), config); deriveErr == nil {
 return checkpointURL, true, nil
 }
 }
 }

if providerURL, ok := resolveProviderCheckpointURL(config, remoteName, dir); ok {
 return providerURL, true, nil
 }
 if remoteErr != nil {
 return "", true, fmt.Errorf("get %s remote URL: %w", remoteName, remoteErr)
 }
 return "", true, fmt.Errorf("resolve checkpoint remote URL from %s", remoteName)
}

// Configured reports whether a structured checkpoint_remote is configured.
func Configured(ctx context.Context) bool {
 s, err := settings.Load(ctx)
48 unmodified lines

return protocol == ProtocolSSH || protocol == ProtocolHTTPS
}

func checkpointTokenTransport(info *Info) *Info {
 if strings.TrimSpace(os.Getenv(CheckpointTokenEnvVar)) == "" || !isDerivableProtocol(info.Protocol) {
 return info
 }

port := ""
 if info.Protocol == ProtocolHTTPS {
 port = info.Port
 }
 return &Info{
 Protocol: ProtocolHTTPS,
 Host: info.Host,
 Port: port,
 Owner: info.Owner,
 Repo: info.Repo,
 }
}

func deriveCheckpointURLFromInfo(info *Info, config *settings.CheckpointRemoteConfig) (string, error) {
 switch info.Protocol {
 case ProtocolSSH:
```

Mcmd/entire/cli/checkpoint/remote/util.go+51/-21

```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

package cli

import (
 "context"
 "fmt"

"github.com/entireio/cli/cmd/entire/cli/checkpointpolicy"
 "github.com/entireio/cli/cmd/entire/cli/versioncheck"
 "github.com/entireio/cli/cmd/entire/cli/versioninfo"
 "github.com/go-git/go-git/v6"
)

func ensureCommittedCheckpointWritePolicy(ctx context.Context, repo *git.Repository) error {
 state, err := checkpointpolicy.ReadLocal(ctx, repo)
 if err != nil {
 return fmt.Errorf("read checkpoint policy: %w", err)
 }
 if !checkpointpolicy.UnsupportedWrite(state.Policy) {
 return nil
 }
 return fmt.Errorf(
 "checkpoint policy requires checkpoint_version %q, which this Entire CLI cannot write; upgrade Entire and rerun the command: %s",
 state.Policy.CheckpointVersion,
 versioncheck.UpdateCommandForCurrentBinary(versioninfo.Version),
 )
}
```

Acmd/entire/cli/checkpoint_policy_write.go+26

```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

package checkpointpolicy

import (
 "errors"
 "fmt"

"github.com/entireio/cli/cmd/entire/cli/checkpoint"
)

func IsUnsupportedVersion(err error) bool {
 var unsupported *unsupportedVersionError
 return errors.As(err, &unsupported)
}

func EnsureCanReadVersion(checkpointID, version string) error {
 policy := Normalize(Policy{CheckpointMinVersion: version})
 format, err := ParseFormat(policy.CheckpointMinVersion)
 if err != nil {
 return fmt.Errorf("checkpoint %s uses unsupported checkpoint_version %q: %w", checkpointID, policy.CheckpointMinVersion, err)
 return &unsupportedVersionError{
 CheckpointID: checkpointID,
 Version: policy.CheckpointMinVersion,
 Err: err,
 }
 }
 if !CanRead(format) {
 return fmt.Errorf("checkpoint %s uses unsupported checkpoint_version %q: not read-supported by this Entire CLI", checkpointID, policy.CheckpointMinVersion)
 return &unsupportedVersionError{
 CheckpointID: checkpointID,
 Version: policy.CheckpointMinVersion,
 Err: errors.New("not read-supported by this Entire CLI"),
 }
 }
 return nil
}

type unsupportedVersionError struct {
 CheckpointID string
 Version      string
 Err          error
}

func (e unsupportedVersionError) Error() string {
 return fmt.Sprintf("checkpoint %s uses unsupported checkpoint_version %q: %v", e.CheckpointID, e.Version, e.Err)
}

func (e unsupportedVersionError) Unwrap() error {
 return e.Err
}
```

Mcmd/entire/cli/checkpointpolicy/policy.go+31/-2

```
37 unmodified lines

38
39
40
41
42
43
44
45
46
47
48

37 unmodified lines

if err != nil {
 return Target{}, fmt.Errorf("resolve worktree root: %w", err)
 }
 if target, dedicated, err := remote.ConfiguredURL(ctx, baseRemote, dir); err != nil {
 return Target{}, fmt.Errorf("resolve checkpoint remote URL: %w", err)
 } else if dedicated {
 return Target{Remote: target, Label: "checkpoint remote", Dir: dir}, nil
 }
 target, dedicated, err := remote.PushURL(ctx, baseRemote)
 if err != nil {
 return Target{}, fmt.Errorf("resolve checkpoint push URL: %w", err)
 }
```

Mcmd/entire/cli/checkpointpolicy/remote.go+5

```
1 unmodified line

2
3
4
5
6
7
8
9
10
11
12
13
14
96 unmodified lines

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
15 unmodified lines

160
161
162
133
163
164
165
166
167
168
169
170
171

1 unmodified line

import (
 "context"
 "os"
 "os/exec"
 "path/filepath"
 "testing"

"github.com/entireio/cli/cmd/entire/cli/checkpointpolicy"
 "github.com/entireio/cli/cmd/entire/cli/paths"
 "github.com/entireio/cli/cmd/entire/cli/testutil"
 "github.com/go-git/go-git/v6"
 "github.com/go-git/go-git/v6/plumbing"
)

require.ErrorContains(t, err, "push checkpoint policy")

func TestResolveTargetUsesConfiguredCheckpointRemoteWithOriginOwnerMismatch(t *testing.T) {
 localDir, _ := initPolicyRepoWithDir(t)
 runPolicyGit(t, localDir, "remote", "add", "origin", "git@github.com:fork/cli.git")
 require.NoError(t, os.MkdirAll(filepath.Join(localDir, ".entire"), 0o750))
 require.NoError(t, os.WriteFile(filepath.Join(localDir, ".entire", "settings.json"), []byte(`{
  "enabled": true,
  "strategy_options": {
    "checkpoint_remote": {
      "provider": "github",
      "repo": "org/checkpoints"
    }
  }
}`), 0o600))

t.Chdir(localDir)
 paths.ClearWorktreeRootCache()

target, err := checkpointpolicy.ResolveTarget(t.Context(), "origin")
 require.NoError(t, err)
 require.Equal(t, "git@github.com:org/checkpoints.git", target.Remote)
 require.Equal(t, "checkpoint remote", target.Label)
 wantDir, err := filepath.EvalSymlinks(localDir)
 require.NoError(t, err)
 gotDir, err := filepath.EvalSymlinks(target.Dir)
 require.NoError(t, err)
 require.Equal(t, wantDir, gotDir)
}

func initPolicyRemoteFixture(t *testing.T) (string, *git.Repository, string) {
 t.Helper()
 localDir, repo := initPolicyRepoWithDir(t)
15 unmodified lines

func pushPolicyRefWithGit(t *testing.T, dir, remote string) {
 t.Helper()
 refspec := checkpointpolicy.RefName.String() + ":" + checkpointpolicy.RefName.String()
 cmd := exec.CommandContext(context.Background(), "git", "push", remote, refspec)
 runPolicyGit(t, dir, "push", remote, refspec)
}

func runPolicyGit(t *testing.T, dir string, args ...string) {
 t.Helper()
 cmd := exec.CommandContext(context.Background(), "git", args...)
 cmd.Dir = dir
 cmd.Env = testutil.GitIsolatedEnv()
 output, err := cmd.CombinedOutput()
```

Mcmd/entire/cli/checkpointpolicy/remote_test.go+36/-1

```
686 unmodified lines

687
688
689
690
690
691
692
693
205 unmodified lines

899
900
901
902
902
903
904
905
16 unmodified lines

922
923
924
925
926
927
928
929
930

686 unmodified lines

if openErr != nil {
 return fmt.Errorf("open checkpoint store: %w", openErr)
 }
 if err := generateCheckpointSummary(ctx, w, errW, writeStores.Primary, fullCheckpointID, summary, content, force, summaryTimeoutSeconds); err != nil {
 if err := generateCheckpointSummary(ctx, w, errW, lookup.repo, writeStores.Primary, fullCheckpointID, summary, content, force, summaryTimeoutSeconds); err != nil {
 return err
 }
 // Reload to get the updated summary.
205 unmodified lines

// summaryTimeoutSeconds is the per-invocation --summary-timeout-seconds flag
// value (0 = unset). Effective precedence for the deadline: flag > settings >
// package default. See resolveSummaryTimeout for the resolution.
func generateCheckpointSummary(ctx context.Context, w, errW io.Writer, store checkpoint.Writer, checkpointID id.CheckpointID, cpSummary *checkpoint.CheckpointSummary, content *checkpoint.SessionContent, force bool, summaryTimeoutSeconds int) error {
func generateCheckpointSummary(ctx context.Context, w, errW io.Writer, repo *git.Repository, store checkpoint.Writer, checkpointID id.CheckpointID, cpSummary *checkpoint.CheckpointSummary, content *checkpoint.SessionContent, force bool, summaryTimeoutSeconds int) error {
 // Check if summary already exists
 if content.Metadata.Summary != nil && !force {
 return renderExplainFailure(errW, "Summary already exists", []explainRow{
16 unmodified lines

{Label: "id", Value: checkpointID.String()},
}, fmt.Errorf("checkpoint %s has no transcript content for this checkpoint (scoped)", checkpointID))
 }
 if err := ensureCommittedCheckpointWritePolicy(ctx, repo); err != nil {
 return err
 }
 provider, err := resolveCheckpointSummaryProvider(ctx, w)
 if err != nil {
 return fmt.Errorf("failed to resolve summary provider: %w", err)
 }
```

Mcmd/entire/cli/explain.go+5/-2

```
10 unmodified lines

11
12
13
14
15
16
17
248 unmodified lines

266
267
268
269
270
271
272
273
274
88 unmodified lines

363
364
365
366
367
368
369
370
371

10 unmodified lines

"github.com/entireio/cli/cmd/entire/cli/checkpoint";
 "github.com/entireio/cli/cmd/entire/cli/checkpoint/id";
 "github.com/entireio/cli/cmd/entire/cli/checkpointpolicy";
 "github.com/entireio/cli/cmd/entire/cli/strategy";
 "github.com/entireio/cli/cmd/entire/cli/trailers";
)
248 unmodified lines

if err != nil {
 return fmt.Errorf("failed to read checkpoint: %w", err)
 }
 if err := checkpointpolicy.EnsureCanReadVersion(cpID.String(), summary.CheckpointVersion); err != nil {
 return fmt.Errorf("check checkpoint version: %w", err)
 }

idx, err := resolveSessionIndex(summary, opts.sessionIndex)
 if err != nil {
88 unmodified lines

envelope, failedSessions := buildCheckpointJSONEnvelope(ctx, store, summary, cpID)
}

Mcmd/entire/cli/explain_export.go+7/-2

```
16 unmodified lines

17
18
19
20
21
22
23
55 unmodified lines

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
21 unmodified lines

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
121 unmodified lines

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

16 unmodified lines

"github.com/entireio/cli/cmd/entire/cli/testutil";
 "github.com/entireio/cli/redact";
 "github.com/go-git/go-git/v6";
 "github.com/go-git/go-git/v6/plumbing";
 "github.com/go-git/go-git/v6/plumbing/object";
 "github.com/stretchr/testify/require";
)
55 unmodified lines

require.NoError(t, store.WriteCommitted(context.Background(), opts))
}

func rewriteExportCheckpointVersion(t *testing.T, repo *git.Repository, cpID id.CheckpointID, version string) {
 t.Helper()
 ctx := context.Background()
 refName := plumbing.NewBranchReferenceName(paths.MetadataBranchName)
 ref, err := repo.Reference(refName, true)
 require.NoError(t, err)
 commit, err := repo.CommitObject(ref.Hash())
 require.NoError(t, err)
 tree, err := commit.Tree()
 require.NoError(t, err)

metadataPath := cpID.Path() + "/" + paths.MetadataFileName
 metadataFile, err := tree.File(metadataPath)
 require.NoError(t, err)
 content, err := metadataFile.Contents()
 require.NoError(t, err)
 var summary checkpoint.CheckpointSummary
 require.NoError(t, json.Unmarshal([]byte(content), &summary))
 summary.CheckpointVersion = version
 metadataJSON, err := json.Marshal(summary)
 require.NoError(t, err)
 metadataHash, err := checkpoint.CreateBlobFromContent(repo, metadataJSON)
 require.NoError(t, err)

entries := make(map[string]object.TreeEntry)
 require.NoError(t, tree.Files().ForEach(func(file *object.File) error {
 entries[file.Name] = object.TreeEntry{Name: file.Name, Mode: file.Mode, Hash: file.Hash}
 return nil
 }))
 entries[metadataPath] = object.TreeEntry{Name: metadataPath, Mode: metadataFile.Mode, Hash: metadataHash}

treeHash, err := checkpoint.BuildTreeFromEntries(ctx, repo, entries)
 require.NoError(t, err)
 commitHash, err := checkpoint.CreateCommit(ctx, repo, treeHash, ref.Hash(), "rewrite checkpoint summary\n", exportTestAuthorName, exportTestAuthorEmail)
 require.NoError(t, err)
 require.NoError(t, repo.Storer.SetReference(plumbing.NewHashReference(refName, commitHash)))
}

func TestRunExplainExport_JSONSingleCheckpoint(t *testing.T) {
 repo := setupExportRepo(t)

require.Equal(t, 0, envelope.Sessions[0].Index)
}

func TestRunExplainExportJSONRejectsUnsupportedCheckpointVersion(t *testing.T) {
 repo := setupExportRepo(t)

cpID := id.MustCheckpointID("aaaabbbbcccc")
 writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
 SessionID: "session-json-unsupported",
 Transcript: redact.AlreadyRedacted([]byte(`{"type":"user","message":{"content":[{"type":"text","text":"hi"}]}}` + "\n")),
 })
 rewriteExportCheckpointVersion(t, repo, cpID, "refs-v1")

var stdout, stderr bytes.Buffer
 err := runExplainExport(context.Background(), &stdout, &stderr, explainExportOptions{
 target: "aaaabbbb",
 json: true,
 sessionIndex: -1,
 })
 require.ErrorContains(t, err, `checkpoint aaaabbbbcccc uses unsupported checkpoint_version "refs-v1"`)
 require.Empty(t, stdout.String())
}

func TestRunExplainExport_JSONFetchesRemoteV1Metadata(t *testing.T) {
 tmpDir := t.TempDir()
 bareDir := filepath.Join(tmpDir, "origin.git")
121 unmodified lines

require.Equal(t, raw, stdout.Bytes())
}

func TestRunExplainExportTranscriptRejectsUnsupportedCheckpointVersion(t *testing.T) {
 tests := []struct {
 name string
 opts explainExportOptions
 }{
 {name: "transcript", opts: explainExportOptions{target: "abcd1111", transcript: true, sessionIndex: -1}},
 {name: "raw transcript", opts: explainExportOptions{target: "abcd1111", rawTranscript: true, sessionIndex: -1}},
 }
 for _, tt := range tests {
 t.Run(tt.name, func(t *testing.T) {
 repo := setupExportRepo(t)
 cpID := id.MustCheckpointID("abcd11112222")
 raw := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"stored line"}]}}` + "\n")
 writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
 SessionID: "session-unsupported-transcript",
 Transcript: redact.AlreadyRedacted(raw),
 })
 rewriteExportCheckpointVersion(t, repo, cpID, "refs-v1")

var stdout, stderr bytes.Buffer
 err := runExplainExport(context.Background(), &stdout, &stderr, tt.opts)
 require.ErrorContains(t, err, `checkpoint abcd11112222 uses unsupported checkpoint_version "refs-v1"`)
 require.Empty(t, stdout.String())
 })
 }
}

func TestRunExplainExport_RawTranscriptStreamsRawBytes(t *testing.T) {
 repo := setupExportRepo(t)
```

Mcmd/entire/cli/explain_export_test.go+86

```
20 unmodified lines

21
22
23
24
25
26
27
968 unmodified lines

996
997
998
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
27 unmodified lines

1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1131
1132
1133
1134
1135
1136

20 unmodified lines

"github.com/entireio/cli/cmd/entire/cli/agent/types";
 "github.com/entireio/cli/cmd/entire/cli/checkpoint";
 "github.com/entireio/cli/cmd/entire/cli/checkpoint/id";
 "github.com/entireio/cli/cmd/entire/cli/checkpointpolicy";
 "github.com/entireio/cli/cmd/entire/cli/paths";
 "github.com/entireio/cli/cmd/entire/cli/settings";
 "github.com/entireio/cli/cmd/entire/cli/strategy";
968 unmodified lines

}

// Not parallel: uses t.Chdir() and package-level var stubs.
func TestGenerateCheckpointSummary_AdvancesV1Metadata(t *testing.T) {
type generateSummaryFixture struct {
 ctx context.Context
 repo *git.Repository
 store checkpoint.CommittedStore
 cpID id.CheckpointID
 cpSummary *checkpoint.CheckpointSummary
 content *checkpoint.SessionContent
 v1Hash plumbing.Hash
}

func setupGenerateSummaryFixture(t *testing.T) generateSummaryFixture {
 t.Helper()
 ctx := context.Background()
 tmpDir := t.TempDir()
 testutil.InitRepo(t, tmpDir)
27 unmodified lines

v1Before, err := repo.Reference(plumbing.NewBranchReferenceName(paths.MetadataBranchName), true)
 require.NoError(t, err)

return generateSummaryFixture{
 ctx: ctx,
 repo: repo,
 store: store,
 cpID: cpID,
 cpSummary: cpSummary,
 content: content,
 v1Hash: v1Before.Hash(),
 }
}

func stubSummaryProviderForTest(t *testing.T) {
 t.Helper()

origLoad := loadSummarySettings
 origGet := getSummaryAgent
 origCLI := isSummaryCLIAvailable
19 unmodified lines

generateTranscriptSummary = func(context.Context, redact.RedactedBytes, []string, types.AgentType, summarize.Generator) (*checkpoint.Summary, error) {
 return &checkpoint.Summary{Intent: "i", Outcome: "o"}, nil
 }
}

func TestGenerateCheckpointSummary_AdvancesV1Metadata(t *testing.T) {
 fixture := setupGenerateSummaryFixture(t)
 stubSummaryProviderForTest(t)

var stdout, stderr bytes.Buffer
 require.NoError(t, generateCheckpointSummary(ctx, &stdout, &stderr, stores.Primary, cpID, cpSummary, content, false, 0))
 require.NoError(t, generateCheckpointSummary(
 fixture.ctx,
 &stdout,
 &stderr,
 fixture.repo,
 fixture.store,
 fixture.cpID,
 fixture.cpSummary,
 fixture.content,
 false,
 0,
 ))

v1After, err := repo.Reference(plumbing.NewBranchReferenceName(paths.MetadataBranchName), true)
 require.NoError(t, err)
 require.NotEqual(t, v1Before.Hash(), v1After.Hash(), "v1 metadata branch must advance after UpdateSummary")
 require.NotEqual(t, fixture.v1Hash, v1After.Hash(), "v1 metadata branch must advance after UpdateSummary")
}

func TestGenerateCheckpointSummaryRejectsUnsupportedCheckpointWritePolicy(t *testing.T) {
 fixture := setupGenerateSummaryFixture(t)
 _, err := checkpointpolicy.WriteLocal(fixture.ctx, fixture.repo, plumbing.ZeroHash, checkpointpolicy.Policy{
 CheckpointVersion: "refs-v1",
 CheckpointMinVersion: "branch-v1",
 })
 require.NoError(t, err)

var stdout, stderr bytes.Buffer
 err = generateCheckpointSummary(
 fixture.ctx,
 &stdout,
 &stderr,
 fixture.repo,
 fixture.store,
 fixture.cpID,
 fixture.cpSummary,
 fixture.content,
 false,
 0,
 )
 require.ErrorContains(t, err, `checkpoint_version "refs-v1"`)

v1After, refErr := fixture.repo.Reference(plumbing.NewBranchReferenceName(paths.MetadataBranchName), true)
 require.NoError(t, refErr)
 require.Equal(t, fixture.v1Hash, v1After.Hash(), "v1 metadata branch must not advance after rejected summary write")
}

func TestGenerateCheckpointAISummary_ClampsLongParentDeadlineToDefaultTimeout(t *testing.T) {
```

Mcmd/entire/cli/explain_test.go+74/-4

```
214 unmodified lines

215
216
217
218
219
220
221
222
223
63 unmodified lines

287
288
289
287
290
291
292
293
294
295
296
297
292
298
299
300
11 unmodified lines

312
313
314
315
316
317
318
319
320
17 unmodified lines

338
339
340
333
341
342
343
344
345
346
347
348
349
350
351
4 unmodified lines

356
357
358
348
359
360
350
361
362
363
364

214 unmodified lines

metadata, err := readCheckpointInfoFromStore(ctx, store, checkpointID)
 if err != nil {
 if checkpointpolicy.IsUnsupportedVersion(err) {
 return err
 }
 logging.Debug(ctx, "resume by checkpoint: metadata read failed, checking remote",
 slog.String("checkpoint_id", checkpointID.String()),
 slog.String("error", err.Error()),
)
63 unmodified lines

// Multiple checkpoints (squash merge): resolve latest by CreatedAt timestamp.
 if len(result.checkpointIDs) > 1 {
 latestMetadata, err := resolveLatestCheckpoint(ctx, store, result.checkpointIDs)
 latestMetadata, found, err := resolveLatestCheckpoint(ctx, store, result.checkpointIDs)
 if err != nil {
 return err
 }
 if !found {
 // No metadata available — nothing to resume from
 logging.Warn(logCtx, "resolveLatestCheckpoint failed",
 slog.Int("checkpoint_count", len(result.checkpointIDs)),
 slog.String("error", err.Error()),
 )
 fmt.Fprintf(w, "Found %d checkpoints for commit %s but metadata is not available\n",
 len(result.checkpointIDs), result.commitHash[:7])
11 unmodified lines

if storeErr == nil {
 metadata = storeInfo
 } else {
 if checkpointpolicy.IsUnsupportedVersion(storeErr) {
 return storeErr
 }
 logging.Debug(ctx, "checkpoint store metadata read failed",
 slog.String("checkpoint_id", checkpointID.String()),
 slog.String("error", storeErr.Error()),
)
17 unmodified lines

// resolveLatestCheckpoint reads metadata for each checkpoint ID and returns
// the checkpoint with the latest CreatedAt.
func resolveLatestCheckpoint(ctx context.Context, store checkpointInfoReader, checkpointIDs []id.CheckpointID) (*strategy.CheckpointInfo, error) {
func resolveLatestCheckpoint(ctx context.Context, store checkpointInfoReader, checkpointIDs []id.CheckpointID) (*strategy.CheckpointInfo, bool, error) {
 infoMap := make(map[id.CheckpointID]strategy.CheckpointInfo, len(checkpointIDs))
 for _, cpID := range checkpointIDs {
 metadata, readErr := readCheckpointInfoFromStore(ctx, store, cpID)
 if readErr != nil {
 if checkpointpolicy.IsUnsupportedVersion(readErr) {
 return nil, false, readErr
 }
 logging.Debug(ctx, "resolveLatestCheckpoint: checkpoint metadata read failed",
 slog.String("checkpoint_id", cpID.String()),
 slog.String("error", readErr.Error()),
)
4 unmodified lines

}
 latest, found := strategy.ResolveLatestCheckpointFromMap(checkpointIDs, infoMap)
 if !found {
 return nil, errors.New("no checkpoint metadata found")
 return nil, false, nil
 }
 return &latest, nil
 return &latest, true, nil
}

type checkpointInfoReader interface {
```

Mcmd/entire/cli/resume.go+16/-5

```
570 unmodified lines

571
572
573
574
574
575
576
577
578
579
580
581
582
583
2 unmodified lines

586
587
588
586
589
590
591
592
593
594
595
596
597
598
21 unmodified lines

620
621
622
617
623
624
625
626
627
628
629
630
631
632
92 unmodified lines

725
726
727
719
728
729
730
731
732
733
734
735
736
737

570 unmodified lines

// simulating git CLI squash merge trailer order.
 reverseOrderIDs := []id.CheckpointID{cpID3, cpID2, cpID1}
 reader := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
 latest, err := resolveLatestCheckpoint(context.Background(), reader, reverseOrderIDs)
 latest, found, err := resolveLatestCheckpoint(context.Background(), reader, reverseOrderIDs)
 if err != nil {
 t.Fatalf("resolveLatestCheckpoint() error = %v", err)
 }
 if !found {
 t.Fatal("resolveLatestCheckpoint() found = false")
 }

// Should return the newest checkpoint regardless of input order
 if latest.CheckpointID.String() != cpID3.String() {
 2 unmodified lines

// Also verify with chronological order
 chronologicalIDs := []id.CheckpointID{cpID1, cpID2, cpID3}
 latest2, err := resolveLatestCheckpoint(context.Background(), reader, chronologicalIDs)
 latest2, found, err := resolveLatestCheckpoint(context.Background(), reader, chronologicalIDs)
 if err != nil {
 t.Fatalf("resolveLatestCheckpoint() error = %v", err)
 }
 if !found {
 t.Fatal("resolveLatestCheckpoint() found = false")
 }
 if latest2.CheckpointID.String() != cpID3.String() {
 t.Errorf("resolveLatestCheckpoint() = %s, want newest %s", latest2.CheckpointID, cpID3)
 }
21 unmodified lines

latest, err := resolveLatestCheckpoint(context.Background(), store, []id.CheckpointID{targetID})
 latest, found, err := resolveLatestCheckpoint(context.Background(), store, []id.CheckpointID{targetID})
 if err != nil {
 t.Fatalf("resolveLatestCheckpoint() error = %v", err)
 }
 if !found {
 t.Fatal("resolveLatestCheckpoint() found = false")
 }
 if latest.CheckpointID != targetID {
 t.Errorf("resolveLatestCheckpoint() = %s, want %s", latest.CheckpointID, targetID)
 }
```

Mcmd/entire/cli/resume_test.go+16/-4

```
17 unmodified lines

18
19
20
21
22
23
24
306 unmodified lines

331
332
333
333
334
335
336
337
338
339
340
341
342
194 unmodified lines

537
538
539
536
540
541
542
543
544
545
546
547
548
180 unmodified lines

729
730
731
725
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
9 unmodified lines

760
761
762
747
763
764
765
766

17 unmodified lines

"github.com/entireio/cli/cmd/entire/cli/agent/types";
 "github.com/entireio/cli/cmd/entire/cli/checkpoint";
 "github.com/entireio/cli/cmd/entire/cli/checkpoint/id";
 "github.com/entireio/cli/cmd/entire/cli/checkpointpolicy";
 "github.com/entireio/cli/cmd/entire/cli/gitrepo";
 "github.com/entireio/cli/cmd/entire/cli/jsonutil";
 "github.com/entireio/cli/cmd/entire/cli/logging";
306 unmodified lines

var restored bool
 if !selectedPoint.CheckpointID.IsEmpty() {
 // Try checkpoint storage first for committed checkpoints
 if returnedSessionID, err := restoreSessionTranscriptFromStrategy(ctx, selectedPoint.CheckpointID, sessionID, agent); err == nil {
 returnedSessionID, err := restoreSessionTranscriptFromStrategy(ctx, selectedPoint.CheckpointID, sessionID, agent)
 if err == nil {
 sessionID = returnedSessionID
 restored = true
 } else if checkpointpolicy.IsUnsupportedVersion(err) {
 return err
 }
 }

194 unmodified lines

180 unmodified lines

if err != nil {
 return "", fmt.Errorf("open checkpoint store: %w", err)
 }
 content, returnedSessionID, err := checkpoint.ReadRawSessionLogForCheckpoint(ctx, stores.Primary, cpID)
 summary, err := checkpoint.ReadCommittedCheckpoint(ctx, stores.Primary, cpID)
 if err != nil {
 return "", fmt.Errorf("failed to read checkpoint: %w", err)
 }
 if err := checkpointpolicy.EnsureCanReadVersion(cpID.String(), summary.CheckpointVersion); err != nil {
 return "", fmt.Errorf("check checkpoint version: %w", err)
 }

content, err := checkpoint.ReadLatestSessionContent(ctx, stores.Primary, cpID, summary)
 if err != nil {
 return "", fmt.Errorf("failed to get session log: %w", err)
 }

// Use session ID returned from checkpoint if available
 // Otherwise fall back to the passed-in sessionID
 returnedSessionID := content.Metadata.SessionID
 if returnedSessionID != "" {
 sessionID = returnedSessionID
 }

}

Mcmd/entire/cli/rewind.go+20/-4

```
49 unmodified lines

50
51
52
53
54
55
56
57
58
59
11 unmodified lines

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

49 unmodified lines

warnOrLogCheckpointPolicySyncFailure(ctx, err)
 return true
 }
 if state.Source == checkpointpolicy.SourceLocalDiverged {
 warnOrLogCheckpointPolicyDiverged(ctx, state)
 return false
 }
 if !checkpointpolicy.UnsupportedWrite(state.Policy) {
 return true
 }
11 unmodified lines

)
}

func warnOrLogCheckpointPolicyDiverged(ctx context.Context, state checkpointpolicy.State) {
 if interactive.CanPromptInteractively() {
 fmt.Fprintf(stderrWriter, "[entire] Could not reconcile checkpoint policy: %s\n", state.Warning)
 return
 }
 logging.Warn(ctx, "checkpoint policy diverged; skipping checkpoint push",
 slog.String("local_hash", state.Hash.String()),
 slog.String("remote_hash", state.RemoteHash.String()),
)
}

func warnOrLogUnsupportedCheckpointWrite(ctx context.Context, policy checkpointpolicy.Policy) {
 warning := checkpointpolicy.UpgradeWarning(versioncheck.UpdateCommandForCurrentBinary(versioninfo.Version))
 if interactive.CanPromptInteractively() {
```

Mcmd/entire/cli/strategy/checkpoint_policy.go+15

```
50 unmodified lines

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

50 unmodified lines

require.Empty(t, strings.TrimSpace(out))
}

func TestPrePushSkipsCheckpointPushWhenPolicyDiverged(t *testing.T) {
 workDir := setupRepoWithCheckpointBranch(t)
 bareDir := filepath.Join(t.TempDir(), "remote.git")
 _, err := git.PlainInit(bareDir, true)
 require.NoError(t, err)
 runCheckpointPolicyGit(t, workDir, "remote", "add", "origin", bareDir)

repo, err := git.PlainOpen(workDir)
 require.NoError(t, err)
 t.Cleanup(func() {
 _ = repo.Close()
 })
 baseHash, err := checkpointpolicy.WriteLocal(t.Context(), repo, plumbing.ZeroHash, checkpointpolicy.DefaultPolicy())
 require.NoError(t, err)
 runCheckpointPolicyGit(t, workDir, "push", bareDir, checkpointpolicy.RefName.String()+":"+checkpointpolicy.RefName.String())

localHash, err := checkpointpolicy.WriteLocal(t.Context(), repo, baseHash, checkpointpolicy.DefaultPolicy())
 require.NoError(t, err)
 _, err = checkpointpolicy.WriteLocal(t.Context(), repo, baseHash, checkpointpolicy.Policy{
 CheckpointVersion: "refs-v1",
 CheckpointMinVersion: "branch-v1",
 })
 require.NoError(t, err)
 runCheckpointPolicyGit(t, workDir, "push", bareDir, checkpointpolicy.RefName.String()+":"+checkpointpolicy.RefName.String())
 require.NoError(t, checkpointpolicy.SetRef(repo, checkpointpolicy.RefName, localHash))

t.Chdir(workDir)
 paths.ClearWorktreeRootCache()
 t.Setenv(interactive.EnvTestTTY, "1")
 oldWriter := stderrWriter
 var stderr bytes.Buffer
 stderrWriter = &stderr
 t.Cleanup(func() { stderrWriter = oldWriter })

err = NewManualCommitStrategy().PrePush(context.Background(), "origin")
 require.NoError(t, err)
 require.Contains(t, stderr.String(), "Could not reconcile checkpoint policy")

out := runCheckpointPolicyGit(t, workDir, "ls-remote", bareDir, "refs/heads/"+paths.MetadataBranchName)
 require.Empty(t, strings.TrimSpace(out))
}

func runCheckpointPolicyGit(t *testing.T, dir string, args ...string) string {
 t.Helper()
 cmd := exec.CommandContext(context.Background(), "git", args...)
```
