checkpoint: rename committed types to persistent vocabulary · Entire

Home

Log in

checkpoint: rename committed types to persistent vocabulary

a030158→main·

Soph·3w ago·45 files·+309 added/-309 removed

Type-level rename (no method or behavior changes yet): CommittedStore -> PersistentStore CommittedReader -> PersistentReader CommittedListReader -> PersistentListReader WriteCommittedOptions -> WriteOptions UpdateCommittedOptions -> UpdateOptions CommittedMetadata -> Metadata CommittedInfo -> CheckpointInfo

'Committed' collides with git's commit vocabulary (these records are literally stored as git commits); 'persistent' names the actual durability property. Method names and the Stores facade field are renamed in following commits.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

de0c61e39335View transcript

?\ so in ../entiredb "filtered_fetches" is enabled, now today one of my coworkers had this issue:Claude Code·5 steps

Changes

45

61 unmodified lines

62
63
64
65
65
66
67
68
248 unmodified lines

317
318
319
320
320
321
322
323

61 unmodified lines

// openAttachStore opens the committed store for the resolved topology. refs is
// passed explicitly so attach preserves PrimaryAsRead() pinning.
func openAttachStore(ctx context.Context, repo *git.Repository, refs cpkg.CommittedRefs) (cpkg.CommittedStore, error) { //nolint:ireturn // committed store capability preserves attach's read-ref override
func openAttachStore(ctx context.Context, repo *git.Repository, refs cpkg.CommittedRefs) (cpkg.PersistentStore, error) { //nolint:ireturn // committed store capability preserves attach's read-ref override
    stores, err := cpkg.Open(ctx, repo, cpkg.OpenOptions{Refs: &refs})
    if err != nil {
        return nil, fmt.Errorf("open checkpoint store: %w", err)
248 unmodified lines

return fmt.Errorf("failed to redact transcript: %w", redactErr)
    }

writeOpts := cpkg.WriteCommittedOptions{
    writeOpts := cpkg.WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        sessionID,
        Strategy:         strategy.StrategyNameManualCommit,

Mcmd/entire/cli/attach.go+2/-2

424 unmodified lines

425
426
427
428
428
429
430
431
827 unmodified lines

1259
1260
1261
1262
1262
1263
1264
1265

424 unmodified lines

// Seed the local branch with a checkpoint representing Alice's session.
    alicesCheckpoint := id.MustCheckpointID("abcdef012345")
    store := cpkg.NewGitStore(repo, cpkg.DefaultV1Refs())
    if writeErr := store.WriteCommitted(context.Background(), cpkg.WriteCommittedOptions{
    if writeErr := store.WriteCommitted(context.Background(), cpkg.WriteOptions{
        CheckpointID: alicesCheckpoint,
        SessionID:    "alice-original",
        Strategy:     "manual-commit",
827 unmodified lines

sessionID := "test-attach-review-metadata-only"
    checkpointID := id.MustCheckpointID("aabbccddeeff")
    store := cpkg.NewGitStore(repo, cpkg.DefaultV1Refs())
    if err := store.WriteCommitted(context.Background(), cpkg.WriteCommittedOptions{
    if err := store.WriteCommitted(context.Background(), cpkg.WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    sessionID,
        Strategy:     strategy.StrategyNameManualCommit,

Mcmd/entire/cli/attach_test.go+2/-2

90 unmodified lines

91
92
93
94
94
95
96
97
63 unmodified lines

161
162
163
164
164
165
166
167
25 unmodified lines

193
194
195
196
196
197
198
199
21 unmodified lines

221
222
223
224
224
225
226
227
16 unmodified lines

244
245
246
247
247
248
249
250
28 unmodified lines

279
280
281
282
282
283
284
285
23 unmodified lines

309
310
311
312
312
313
314
315
7 unmodified lines

323
324
325
326
326
327
328
329
33 unmodified lines

363
364
365
366
366
367
368
369
30 unmodified lines

400
401
402
403
403
404
405
406
36 unmodified lines

443
444
445
446
446
447
448
449
450
451
452
453
453
454
455
456
73 unmodified lines

530
531
532
533
533
534
535
536

90 unmodified lines

func TestAttributionBlameShowsHumanAndAICheckpointLines(t *testing.T) {
    repoRoot := newAttributionRepo(t)
    writeAttributionCheckpoint(t, repoRoot, "a1b2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "a1b2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-ai-12345678",
        Prompts:          []string{"Add an agent-owned helper."},
        FilesTouched:     []string{"auth.py"},
63 unmodified lines

func TestAttributionBlameLongShowsDetailedColumns(t *testing.T) {
    repoRoot := newAttributionRepo(t)
    writeAttributionCheckpoint(t, repoRoot, "a2b2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "a2b2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-ai-12345678",
        Prompts:          []string{"Add an agent-owned helper."},
        FilesTouched:     []string{"auth.py"},
25 unmodified lines

func TestAttributionBlameMarksMixedCheckpoint(t *testing.T) {
    repoRoot := newAttributionRepo(t)
    writeAttributionCheckpoint(t, repoRoot, "b1b2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "b1b2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-mixed-12345678",
        Prompts:          []string{"Change agent code, then keep a user tweak."},
        FilesTouched:     []string{"auth.py"},
21 unmodified lines

func TestAttributionWhyLineShowsPromptAndCheckpoint(t *testing.T) {
    repoRoot := newAttributionRepo(t)
    writeAttributionCheckpoint(t, repoRoot, "c1b2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "c1b2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-why-12345678",
        Prompts:          []string{"Create a line that can be explained."},
        FilesTouched:     []string{"auth.py"},
16 unmodified lines

func TestAttributionBlameJSONIsStable(t *testing.T) {
    repoRoot := newAttributionRepo(t)
    writeAttributionCheckpoint(t, repoRoot, "d1b2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "d1b2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-json-12345678",
        Prompts:          []string{"Add JSON attributed line."},
        FilesTouched:     []string{"auth.py"},
28 unmodified lines

func TestAttributionBlameJSONLineFilterPrunesCheckpoints(t *testing.T) {
    repoRoot := newAttributionRepo(t)
    writeAttributionCheckpoint(t, repoRoot, "e1b2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "e1b2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-filter-12345678",
        Prompts:          []string{"Add the second line only."},
        FilesTouched:     []string{"auth.py"},
23 unmodified lines

func TestAttributionBlameMixedUsesFileMatchingCheckpoint(t *testing.T) {
    repoRoot := newAttributionRepo(t)
    writeAttributionCheckpoint(t, repoRoot, "f1b2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "f1b2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-auth-12345678",
        Prompts:          []string{"Add auth line."},
        FilesTouched:     []string{"auth.py"},
7 unmodified lines

MetricVersion:     2,
        },
    })
    writeAttributionCheckpoint(t, repoRoot, "f2b2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "f2b2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-other-12345678",
        Prompts:          []string{"Mixed update in another file."},
        FilesTouched:     []string{"other.py"},
33 unmodified lines

Sessions:     []checkpoint.SessionFilePaths{{Metadata: "metadata.json"}},
        },
        content: &checkpoint.SessionContent{
            Metadata: checkpoint.CommittedMetadata{
            Metadata: checkpoint.Metadata{
                SessionID:    "session-ai",
                FilesTouched: []string{"auth.py"},
                Agent:        agent.AgentTypeClaudeCode,
30 unmodified lines

func TestAttributionBlameScopesMixedToSessionNotCheckpoint(t *testing.T) {
    repoRoot := newAttributionRepo(t)
    writeAttributionCheckpoint(t, repoRoot, "a9b2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "a9b2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-scoped-12345678",
        Prompts:          []string{"Agent-only edit to auth.py."},
        FilesTouched:     []string{"auth.py"},
36 unmodified lines

// One checkpoint, two sessions, neither recording a touch to auth.py (e.g.
    // the file was renamed after the checkpoint). Attribution must fall back to
    // a session and flag that the agent/prompt shown is approximate.
    writeAttributionCheckpoint(t, repoRoot, "aab2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "aab2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-one-12345678",
        Prompts:          []string{"Edit the first file."},
        FilesTouched:     []string{"old_name.py"},
        Agent:            agent.AgentTypeClaudeCode,
        CheckpointsCount: 1,
    })
    writeAttributionCheckpoint(t, repoRoot, "aab2c3d4e5f6", checkpoint.WriteCommittedOptions{
    writeAttributionCheckpoint(t, repoRoot, "aab2c3d4e5f6", checkpoint.WriteOptions{
        SessionID:        "session-two-12345678",
        Prompts:          []string{"Edit a second file."},
        FilesTouched:     []string{"other.py"},
73 unmodified lines

return repoRoot
}

func writeAttributionCheckpoint(t *testing.T, repoRoot, checkpointID string, opts checkpoint.WriteCommittedOptions) {
func writeAttributionCheckpoint(t *testing.T, repoRoot, checkpointID string, opts checkpoint.WriteOptions) {
    t.Helper()
    repo, err := git.PlainOpen(repoRoot)
    require.NoError(t, err)

Mcmd/entire/cli/attribution_test.go+13/-13

323 unmodified lines

324
325
326
327
327
328
329
330

323 unmodified lines

b.Fatalf("generate ID: %v", err)
            }
            redactedTranscript := redact.AlreadyRedacted(transcript)
            err = repo.Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
            err = repo.Store.WriteCommitted(ctx, checkpoint.WriteOptions{
                CheckpointID:     cpID,
                SessionID:        fmt.Sprintf("bench-session-%d", i),
                Strategy:         "manual-commit",

Mcmd/entire/cli/benchutil/bench_test.go+1/-1

53 unmodified lines

54
55
56
57
57
58
59
60

53 unmodified lines

checkpointID := id.MustCheckpointID("def456abc123")

// Write checkpoint WITHOUT token usage (simulates old checkpoints)
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    "test-session-old",
        Strategy:     "manual-commit",

Mcmd/entire/cli/checkpoint/backwards_compat_test.go+1/-1

133 unmodified lines

134
135
136
137
137
138
139
140

133 unmodified lines

repo, store, cpID := setupRepoForUpdate(t)

// Write a second session to the same checkpoint
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-002",
        Strategy:     "manual-commit",

Mcmd/entire/cli/checkpoint/blob_resolver_test.go+1/-1

157 unmodified lines

158
159
160
161
162
161
162
163
164
165
79 unmodified lines

245
246
247
248
249
248
249
250
251
252
61 unmodified lines

314
315
316
317
317
318
319
320
321
321
322
323
324
5 unmodified lines

330
331
332
333
333
334
335
336
39 unmodified lines

376
377
378
379
380
379
380
381
382
383
30 unmodified lines

414
415
416
417
417
418
419
420
7 unmodified lines

428
429
430
431
432
431
432
433
434
435
77 unmodified lines

513
514
515
516
516
517
518
519
20 unmodified lines

540
541
542
543
543
544
545
546

157 unmodified lines

Timestamp time.Time
}

// WriteCommittedOptions contains options for writing a committed checkpoint.
type WriteCommittedOptions struct {
// WriteOptions contains options for writing a committed checkpoint.
type WriteOptions struct {
    // CheckpointID is the stable 12-hex-char identifier
    CheckpointID id.CheckpointID

79 unmodified lines

TranscriptIdentifierAtStart string // Last identifier when checkpoint started (UUID for Claude, message ID for Gemini)
    CheckpointTranscriptStart   int    // Transcript line offset at start of this checkpoint's data

// CheckpointTranscriptStart is written to both CommittedMetadata.CheckpointTranscriptStart
    // and the deprecated CommittedMetadata.TranscriptLinesAtStart for backward compatibility.
    // CheckpointTranscriptStart is written to both Metadata.CheckpointTranscriptStart
    // and the deprecated Metadata.TranscriptLinesAtStart for backward compatibility.

// TokenUsage contains the token usage for this checkpoint
    TokenUsage *types.TokenUsage
61 unmodified lines

HasInvestigation bool
}

// UpdateCommittedOptions contains options for updating an existing committed checkpoint.
// UpdateOptions contains options for updating an existing committed checkpoint.
// Uses replace semantics: the transcript and prompts are fully replaced,
// not appended. At stop time we have the complete session transcript and want every
// checkpoint to contain it identically.
type UpdateCommittedOptions struct {
type UpdateOptions struct {
    // CheckpointID identifies the checkpoint to update
    CheckpointID id.CheckpointID

5 unmodified lines

Transcript redact.RedactedBytes

// Prompts contains the raw user prompts (replaces existing).
    // See WriteCommittedOptions.Prompts.
    // See WriteOptions.Prompts.
    Prompts []string

// Agent identifies the agent type (needed for transcript chunking)
39 unmodified lines

return p != nil && !p.ContentHashBlob.IsZero() && len(p.ChunkHashes) > 0
}

// CommittedInfo contains summary information about a committed checkpoint.
type CommittedInfo struct {
// CheckpointInfo contains summary information about a committed checkpoint.
type CheckpointInfo struct {
    // CheckpointID is the stable 12-hex-char identifier
    CheckpointID id.CheckpointID

30 unmodified lines

// as opposed to just the metadata/summary.
type SessionContent struct {
    // Metadata contains the session-specific metadata
    Metadata CommittedMetadata
    Metadata Metadata

// Transcript is the session transcript content
    Transcript []byte
7 unmodified lines

Prompts string
}

// CommittedMetadata contains the metadata stored in metadata.json for each checkpoint.
type CommittedMetadata struct {
// Metadata contains the metadata stored in metadata.json for each checkpoint.
type Metadata struct {
    CLIVersion       string          `json:"cli_version,omitempty"`
    CheckpointID     id.CheckpointID `json:"checkpoint_id"`
    SessionID        string          `json:"session_id"`
77 unmodified lines

// GetTranscriptStart returns the transcript line offset at which this checkpoint's data begins.
// Returns 0 for new checkpoints (start from beginning). For data written by older CLI versions,
// falls back to the deprecated TranscriptLinesAtStart field.
func (m CommittedMetadata) GetTranscriptStart() int {
func (m Metadata) GetTranscriptStart() int {
    if m.CheckpointTranscriptStart > 0 {
        return m.CheckpointTranscriptStart
    }
20 unmodified lines

//	<checkpoint-id[:2]>/<checkpoint-id[2:]>/
//	├── metadata.json         # This CheckpointSummary
//	├── 1/                    # First session
//	│   ├── metadata.json     # Session-specific CommittedMetadata
//	│   ├── metadata.json     # Session-specific Metadata
//	│   ├── full.jsonl
//	│   ├── prompt.txt
//	│   └── content_hash.txt

Mcmd/entire/cli/checkpoint/checkpoint.go+14/-14

141 unmodified lines

142
143
144
145
145
146
147
148
60 unmodified lines

209
210
211
212
212
213
214
215
11 unmodified lines

227
228
229
230
230
231
232
233
50 unmodified lines

284
285
286
287
287
288
289
290
2 unmodified lines

293
294
295
296
296
297
298
299
258 unmodified lines

558
559
560
561
561
562
563
564
80 unmodified lines

645
646
647
648
648
649
650
651
39 unmodified lines

691
692
693
694
694
695
696
697
33 unmodified lines

731
732
733
734
734
735
736
737
18 unmodified lines

756
757
758
759
759
760
761
762
114 unmodified lines

877
878
879
880
880
881
882
883
62 unmodified lines

946
947
948
949
949
950
951
952
78 unmodified lines

1031
1032
1033
1034
1034
1035
1036
1037
9 unmodified lines

1047
1048
1049
1050
1050
1051
1052
1053
58 unmodified lines

1112
1113
1114
1115
1115
1116
1117
1118
13 unmodified lines

1132
1133
1134
1135
1135
1136
1137
1138
65 unmodified lines

1204
1205
1206
1207
1207
1208
1209
1210
62 unmodified lines

1273
1274
1275
1276
1276
1277
1278
1279
44 unmodified lines

1324
1325
1326
1327
1327
1328
1329
1330
18 unmodified lines

1349
1350
1351
1352
1352
1353
1354
1355
43 unmodified lines

1399
1400
1401
1402
1402
1403
1404
1405
32 unmodified lines

1438
1439
1440
1441
1441
1442
1443
1444
45 unmodified lines

1490
1491
1492
1493
1493
1494
1495
1496
16 unmodified lines

1513
1514
1515
1516
1516
1517
1518
1519
32 unmodified lines

1552
1553
1554
1555
1555
1556
1557
1558
30 unmodified lines

1589
1590
1591
1592
1592
1593
1594
1595
5 unmodified lines

1601
1602
1603
1604
1604
1605
1606
1607
32 unmodified lines

1640
1641
1642
1643
1643
1644
1645
1646
1434 unmodified lines

3081
3082
3083
3084
3084
3085
3086
3087
13 unmodified lines

3101
3102
3103
3104
3104
3105
3106
3107
13 unmodified lines

3121
3122
3123
3124
3124
3125
3126
3127
88 unmodified lines

3216
3217
3218
3219
3219
3220
3221
3222
8 unmodified lines

3231
3232
3233
3234
3234
3235
3236
3237
54 unmodified lines

3292
3293
3294
3295
3295
3296
3297
3298
7 unmodified lines

3306
3307
3308
3309
3309
3310
3311
3312
7 unmodified lines

3320
3321
3322
3323
3323
3324
3325
3326
49 unmodified lines

3376
3377
3378
3379
3379
3380
3381
3382
8 unmodified lines

3391
3392
3393
3394
3394
3395
3396
3397
8 unmodified lines

3406
3407
3408
3409
3409
3410
3411
3412
47 unmodified lines

3460
3461
3462
3463
3463
3464
3465
3466
24 unmodified lines

3491
3492
3493
3494
3494
3495
3496
3497
88 unmodified lines

3586
3587
3588
3589
3589
3590
3591
3592
28 unmodified lines

3621
3622
3623
3624
3624
3625
3626
3627
47 unmodified lines

3675
3676
3677
3678
3678
3679
3680
3681
9 unmodified lines

3691
3692
3693
3694
3694
3695
3696
3697
3698
3699
3700
3700
3701
3702
3703
29 unmodified lines

3733
3734
3735
3736
3736
3737
3738
3739
32 unmodified lines

3772
3773
3774
3775
3775
3776
3777
3778
3779
3780
3781
3781
3782
3783
3784
166 unmodified lines

3951
3952
3953
3954
3954
3955
3956
3957
36 unmodified lines

3994
3995
3996
3997
3997
3998
3999
4000
45 unmodified lines

4046
4047
4048
4049
4049
4050
4051
4052
524 unmodified lines

4577
4578
4579
4580
4580
4581
4582
4583
4584
4585
4586
4587
4587
4588
4589
4590
25 unmodified lines

4616
4617
4618
4619
4619
4620
4621
4622
4623
4624
4624
4625
4626
4627
17 unmodified lines

4645
4646
4647
4648
4648
4649
4650
4650
4651
4652
4653
4654
4655
4656
4657
4657
4658
4659
4660
39 unmodified lines

4700
4701
4702
4703
4703
4704
4705
4706
89 unmodified lines

4796
4797
4798
4799
4799
4800
4801
4801
4802
4803
4804
23 unmodified lines

4828
4829
4830
4831
4831
4832
4833
4834
32 unmodified lines

4867
4868
4869
4870
4870
4871
4872
4873
5 unmodified lines

4879
4880
4881
4882
4882
4883
4884
4885
16 unmodified lines

4902
4903
4904
4905
4905
4906
4907
4908
13 unmodified lines

4922
4923
4924
4925
4926
4925
4926
4927
4928
4929
1 unmodified line

4931
4932
4933
4934
4934
4935
4936
4937

141 unmodified lines

sessionID := "test-session-123"
    agentType := agent.AgentTypeClaudeCode

err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    sessionID,
        Strategy:     "manual-commit",
60 unmodified lines

if err != nil {
            t.Fatalf("failed to read session metadata.json: %v", err)
        }
        var sessionMetadata CommittedMetadata
        var sessionMetadata Metadata
        if err := json.Unmarshal([]byte(sessionContent), &sessionMetadata); err != nil {
            t.Fatalf("failed to parse session metadata.json: %v", err)
        }
11 unmodified lines

// readLatestSessionMetadata reads the session-specific metadata from the latest session subdirectory.
// This is where session-specific fields like Summary are stored.
func readLatestSessionMetadata(t *testing.T, repo *git.Repository, checkpointID id.CheckpointID) CommittedMetadata {
func readLatestSessionMetadata(t *testing.T, repo *git.Repository, checkpointID id.CheckpointID) Metadata {
    t.Helper()

ref, err := repo.Reference(plumbing.NewBranchReferenceName(paths.MetadataBranchName), true)
50 unmodified lines

t.Fatalf("failed to read session metadata.json: %v", err)
    }

var metadata CommittedMetadata
    var metadata Metadata
    if err := json.Unmarshal([]byte(content), &metadata); err != nil {
        t.Fatalf("failed to parse session metadata.json: %v", err)
    }
2 unmodified lines

}

// Note: Tests for Agents array and SessionCount fields have been removed
// as those fields were removed from CommittedMetadata in the simplification.
// as those fields were removed from Metadata in the simplification.

// TestWriteTemporary_Deduplication verifies that WriteTemporary skips creating
// a new commit when the tree hash matches the previous checkpoint.
258 unmodified lines

}

cpID := id.MustCheckpointID("abcdef123456")
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: cpID,
        SessionID:    "test-session-id",
        Strategy:     "manual-commit",
80 unmodified lines

t.Fatalf("failed to read metadata.json: %v", err)
    }

var metadata CommittedMetadata
    var metadata Metadata
    if err := json.Unmarshal([]byte(content), &metadata); err != nil {
        t.Fatalf("failed to parse metadata.json: %v", err)
    }
39 unmodified lines

// Write a committed checkpoint with branch information
        checkpointID := id.MustCheckpointID("a1b2c3d4e5f6")
        store := NewGitStore(repo, DefaultV1Refs())
        err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
        err = store.WriteCommitted(context.Background(), WriteOptions{
            CheckpointID: checkpointID,
            SessionID:    "test-session-123",
            Strategy:     "manual-commit",
33 unmodified lines

// Write a committed checkpoint (branch should be empty in detached HEAD)
        checkpointID := id.MustCheckpointID("b2c3d4e5f6a7")
        store := NewGitStore(repo, DefaultV1Refs())
        err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
        err = store.WriteCommitted(context.Background(), WriteOptions{
            CheckpointID: checkpointID,
            SessionID:    "test-session-456",
            Strategy:     "manual-commit",
18 unmodified lines

checkpointID := id.MustCheckpointID("f1e2d3c4b5a6")

// First, create a checkpoint without a summary
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    "test-session-summary",
        Strategy:     "manual-commit",
114 unmodified lines

// Create entire/checkpoints/v1 branch on the remote with a checkpoint
    remoteStore := NewGitStore(remoteRepo, DefaultV1Refs())
    cpID := id.MustCheckpointID("abcdef123456")
    err = remoteStore.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = remoteStore.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: cpID,
        SessionID:    "test-session-id",
        Strategy:     "manual-commit",
62 unmodified lines

authorName := "Alice Developer"
    authorEmail := "alice@example.com"

err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    "test-session-author",
        Strategy:     "manual-commit",
78 unmodified lines

checkpointID := id.MustCheckpointID("a1a2a3a4a5a6")

// Write first session
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-one",
        Strategy:         "manual-commit",
9 unmodified lines

}

// Write second session to the same checkpoint ID
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-two",
        Strategy:         "manual-commit",
58 unmodified lines

checkpointID := id.MustCheckpointID("b1b2b3b4b5b6")

// Write first session with specific stats
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-one",
        Strategy:         "manual-commit",
13 unmodified lines

}

// Write second session with overlapping and new files
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-two",
        Strategy:         "manual-commit",
65 unmodified lines

// Write two sessions
    for i, sessionID := range []string{"session-alpha", "session-beta"} {
        err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
        err := store.WriteCommitted(context.Background(), WriteOptions{
            CheckpointID:     checkpointID,
            SessionID:        sessionID,
            Strategy:         "manual-commit",
62 unmodified lines

}

for _, s := range sessions {
        err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
        err := store.WriteCommitted(context.Background(), WriteOptions{
            CheckpointID:     checkpointID,
            SessionID:        s.id,
            Strategy:         "manual-commit",
44 unmodified lines

store := NewGitStore(repo, DefaultV1Refs())
    checkpointID := id.MustCheckpointID(cpIDStr)

err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        sessionID,
        Strategy:         "manual-commit",
18 unmodified lines

{"timestamp":"2026-03-25T11:31:11.756Z","type":"compacted","payload":{"message":"","replacement_history":[{"type":"message","role":"user","content":[{"type":"input_text","text":"hello"}]},{"type":"reasoning","summary":[{"text":"nested"}],"encrypted_content":"REDACTED"},{"type":"compaction","encrypted_content":"REDACTED"},{"type":"compaction_summary","encrypted_content":"REDACTED"}]}}
`

err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "codex-session",
        Strategy:         "manual-commit",
43 unmodified lines

// Write three sessions
    for i := range 3 {
        err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
        err := store.WriteCommitted(context.Background(), WriteOptions{
            CheckpointID:     checkpointID,
            SessionID:        fmt.Sprintf("session-%d", i),
            Strategy:         "manual-commit",
32 unmodified lines

// Write two sessions with distinct IDs
    sessionIDs := []string{"unique-id-alpha", "unique-id-beta"}
    for i, sid := range sessionIDs {
        err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
        err := store.WriteCommitted(context.Background(), WriteOptions{
            CheckpointID:     checkpointID,
            SessionID:        sid,
            Strategy:         "manual-commit",
45 unmodified lines

// Write two sessions to the same checkpoint
    for i, sid := range []string{"list-session-1", "list-session-2"} {
        err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
        err := store.WriteCommitted(context.Background(), WriteOptions{
            CheckpointID:     checkpointID,
            SessionID:        sid,
            Strategy:         "manual-commit",
16 unmodified lines

}

// Find our checkpoint
    var found *CommittedInfo
    var found *CheckpointInfo
    for i := range checkpoints {
        if checkpoints[i].CheckpointID == checkpointID {
            found = &checkpoints[i]
32 unmodified lines

checkpointID := id.MustCheckpointID("313233343536")

// Write session without prompts
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "no-prompts-session",
        Strategy:         "manual-commit",
30 unmodified lines

}

// TestWriteCommitted_SessionWithSummary verifies that a non-nil Summary
// in WriteCommittedOptions is persisted in the session-level metadata.json.
// in WriteOptions is persisted in the session-level metadata.json.
// Regression test for ENT-243 where Summary was omitted from the struct literal.
func TestWriteCommitted_SessionWithSummary(t *testing.T) {
    repo, _ := setupBranchTestRepo(t)
5 unmodified lines

Outcome: "Bug was fixed",
    }

err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "summary-session",
        Strategy:         "manual-commit",
32 unmodified lines

// Write three sessions
    for i := range 3 {
        err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
        err := store.WriteCommitted(context.Background(), WriteOptions{
            CheckpointID:     checkpointID,
            SessionID:        fmt.Sprintf("three-session-%d", i),
            Strategy:         "manual-commit",
1434 unmodified lines

checkpointID := id.MustCheckpointID("deda01234567")

// Write session "X" with initial data
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-X",
        Strategy:         "manual-commit",
13 unmodified lines

}

// Write session "Y"
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-Y",
        Strategy:         "manual-commit",
13 unmodified lines

}

// Write session "X" again with updated data (should replace, not append)
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-X",
        Strategy:         "manual-commit",
88 unmodified lines

checkpointID := id.MustCheckpointID("dedb07654321")

// Write session "X" with initial data
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-X",
        Strategy:         "manual-commit",
8 unmodified lines

}

// Write session "X" again with updated data
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-X",
        Strategy:         "manual-commit",
54 unmodified lines

checkpointID := id.MustCheckpointID("dedc0abcdef1")

// Write session A at index 0
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-A",
        Strategy:         "manual-commit",
7 unmodified lines

}

// Write session B at index 1
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-B",
        Strategy:         "manual-commit",
7 unmodified lines

}

// Write session A again — should reuse index 0, not create index 2
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-A",
        Strategy:         "manual-commit",
49 unmodified lines

checkpointID := id.MustCheckpointID("dedd0abcdef2")

// Write session A with prompts and context
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-A",
        Strategy:         "manual-commit",
8 unmodified lines

}

// Write session B with prompts
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-B",
        Strategy:         "manual-commit",
8 unmodified lines

}

// Overwrite session A WITHOUT prompts
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "session-A",
        Strategy:         "manual-commit",
47 unmodified lines

t.Fatalf("redact.JSONLBytes() error = %v", err)
    }

err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "redact-transcript-session",
        Strategy:         "manual-commit",
24 unmodified lines

store := NewGitStore(repo, DefaultV1Refs())
    checkpointID := id.MustCheckpointID("aabbccddeef2")

err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "redact-prompt-session",
        Strategy:         "manual-commit",
88 unmodified lines

}

// TestWriteCommitted_CLIVersionField verifies that versioninfo.Version is written
// to both the root CheckpointSummary and session-level CommittedMetadata.
// to both the root CheckpointSummary and session-level Metadata.
func TestWriteCommitted_CLIVersionField(t *testing.T) {
    t.Parallel()

28 unmodified lines

checkpointID := id.MustCheckpointID("b1c2d3e4f5a6")
    sessionID := "test-session-version"

err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    sessionID,
        Strategy:     "manual-commit",
47 unmodified lines

t.Errorf("CheckpointSummary.CLIVersion = %q, want %q", summary.CLIVersion, versioninfo.Version)
    }

// Verify session-level metadata.json (CommittedMetadata) has CLIVersion
    // Verify session-level metadata.json (Metadata) has CLIVersion
    sessionTree, err := checkpointTree.Tree("0")
    if err != nil {
        t.Fatalf("failed to get session tree: %v", err)
9 unmodified lines

t.Fatalf("failed to read session metadata.json: %v", err)
    }

var sessionMetadata CommittedMetadata
    var sessionMetadata Metadata
    if err := json.Unmarshal([]byte(sessionContent), &sessionMetadata); err != nil {
        t.Fatalf("failed to parse session metadata.json: %v", err)
    }

if sessionMetadata.CLIVersion != versioninfo.Version {
        t.Errorf("CommittedMetadata.CLIVersion = %q, want %q", sessionMetadata.CLIVersion, versioninfo.Version)
        t.Errorf("Metadata.CLIVersion = %q, want %q", sessionMetadata.CLIVersion, versioninfo.Version)
    }
}

29 unmodified lines

store := NewGitStore(repo, DefaultV1Refs())

checkpointID := id.MustCheckpointID("c1d2e3f4a5b6")
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    "test-session-model",
        Strategy:     "manual-commit",
32 unmodified lines

t.Fatalf("failed to read session metadata.json: %v", err)
    }

if sessionMetadata.Model != "" {
        t.Errorf("CommittedMetadata.Model = %q, want empty string", sessionMetadata.Model)
        t.Errorf("Metadata.Model = %q, want empty string", sessionMetadata.Model)
    }
    if !strings.Contains(sessionContent, `"model": ""`) {
        t.Errorf("session metadata.json should contain an explicit empty model field, got:\n%s", sessionContent)
166 unmodified lines

store := NewGitStore(repo, DefaultV1Refs())
    checkpointID := id.MustCheckpointID("aabbccddeef7")

err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "redact-summary-session",
        Strategy:         "manual-commit",
36 unmodified lines

checkpointID := id.MustCheckpointID("aabbccddeef8")

// First write a checkpoint without a summary
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "update-summary-session",
        Strategy:         "manual-commit",
45 unmodified lines

t.Fatalf("failed to write transcript: %v", err)
    }

err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:           checkpointID,
        SessionID:              "jsonl-fallback-session",
        Strategy:               "manual-commit",
524 unmodified lines

}

// TestCommittedMetadata_ReviewFields pins the JSON wire format for review
// fields on CommittedMetadata. Any refactor that silently drops or renames
// fields on Metadata. Any refactor that silently drops or renames
// these JSON tags would break the entire/checkpoints/v1 branch format. We
// assert on the actual marshalled JSON keys (not just round-trip identity)
// because a coordinated rename of struct field + tag would otherwise pass
// the round-trip but break on-disk readers of older checkpoints.
func TestCommittedMetadata_ReviewFields(t *testing.T) {
    t.Parallel()
    m := CommittedMetadata{
    m := Metadata{
        Kind:         "agent_review",
        ReviewSkills: []string{"/skill1", "/skill2"},
        ReviewPrompt: "Review this branch.",
25 unmodified lines

}

// TestCommittedMetadata_InvestigateFields pins the JSON wire format for the
// investigate fields on CommittedMetadata. Mirrors
// investigate fields on Metadata. Mirrors
// TestCommittedMetadata_ReviewFields: any silent rename or removal of these
// JSON tags would corrupt the entire/checkpoints/v1 branch format.
func TestCommittedMetadata_InvestigateFields(t *testing.T) {
    t.Parallel()
    m := CommittedMetadata{
    m := Metadata{
        Kind:             "agent_investigate",
        InvestigateRunID: "abcdef012345",
        InvestigateTopic: "Why is checkout flaky?",
17 unmodified lines

t.Errorf(`expected "investigate_topic" present, got %v`, raw["investigate_topic"])
    }

// Zero-value CommittedMetadata must omit all the investigate keys
    // Zero-value Metadata must omit all the investigate keys
    // (omitempty tags) so older checkpoints aren't tagged as investigations.
    bZero, err := json.Marshal(CommittedMetadata{})
    bZero, err := json.Marshal(Metadata{})
    if err != nil {
        t.Fatalf("marshal zero: %v", err)
    }
    zs := string(bZero)
    for _, key := range []string{"investigate_run_id", "investigate_topic"} {
        if strings.Contains(zs, `"`+key+`"`) {
            t.Errorf(`expected zero-value CommittedMetadata to omit %q, got %s`, key, zs)
            t.Errorf(`expected zero-value Metadata to omit %q, got %s`, key, zs)
        }
    }
}
39 unmodified lines

func TestRedactBlobBytes_JSONMetadata(t *testing.T) {
    t.Parallel()

meta := CommittedMetadata{
    meta := Metadata{
        Kind:         "agent_review",
        ReviewPrompt: "credential leak: key=AKIAYRWQG5EJLPZLBYNP",
        Summary: &Summary{
89 unmodified lines

return summary
}

// readSessionMetadataAtIndex reads the per-session CommittedMetadata for
// readSessionMetadataAtIndex reads the per-session Metadata for
// session at numbered subfolder `index` (0-based) under the checkpoint.
func readSessionMetadataAtIndex(t *testing.T, repo *git.Repository, checkpointID id.CheckpointID, index int) CommittedMetadata {
func readSessionMetadataAtIndex(t *testing.T, repo *git.Repository, checkpointID id.CheckpointID, index int) Metadata {
    t.Helper()
    ref, err := repo.Reference(plumbing.NewBranchReferenceName(paths.MetadataBranchName), true)
    if err != nil {
23 unmodified lines

if err != nil {
        t.Fatalf("read session metadata.json: %v", err)
    }
    var meta CommittedMetadata
    var meta Metadata
    if err := json.Unmarshal([]byte(content), &meta); err != nil {
        t.Fatalf("parse session metadata.json: %v", err)
    }
32 unmodified lines

}

// TestWriteCommitted_PropagatesHasInvestigation verifies that
// WriteCommittedOptions.HasInvestigation flows into CheckpointSummary, and
// WriteOptions.HasInvestigation flows into CheckpointSummary, and
// that on a second write into the SAME checkpoint, the existing-summary
// OR-merge keeps HasInvestigation true even when the second session is not
// itself an investigation. Mirrors the existing HasReview merge behaviour.
5 unmodified lines

checkpointID := id.MustCheckpointID("aabbccddeeff")

// First session: investigate session, sets HasInvestigation=true.
    if err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    if err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "investigate-session-1",
        Strategy:         "manual-commit",
16 unmodified lines

// Second session: ordinary session, HasInvestigation=false. The OR-merge
    // against the existing summary must keep HasInvestigation=true.
    if err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    if err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "ordinary-session-2",
        Strategy:         "manual-commit",
13 unmodified lines

}

// TestCommittedMetadata_InvestigateFieldsRoundTrip verifies that
// WriteCommittedOptions investigate fields are written into the per-session
// CommittedMetadata and round-trip on read.
// WriteOptions investigate fields are written into the per-session
// Metadata and round-trip on read.
func TestCommittedMetadata_InvestigateFieldsRoundTrip(t *testing.T) {
    t.Parallel()

1 unmodified line

store := NewGitStore(repo, DefaultV1Refs())
    checkpointID := id.MustCheckpointID("11223344aabb")

if err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    if err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID:     checkpointID,
        SessionID:        "investigate-roundtrip",
        Strategy:         "manual-commit",

Mcmd/entire/cli/checkpoint/checkpoint_test.go+69/-69

54 unmodified lines

55
56
57
58
58
59
60
61
124 unmodified lines

186
187
188
189
189
190
191
192
3 unmodified lines

196
197
198
199
199
200
201
202
24 unmodified lines

227
228
229
230
230
231
232
233
57 unmodified lines

291
292
293
294
294
295
296
297
298
299
300
300
301
302
303
87 unmodified lines

391
392
393
394
394
395
396
397
30 unmodified lines

428
429
430
431
432
431
432
433
434
435
45 unmodified lines

481
482
483
484
484
485
486
487
165 unmodified lines

653
654
655
656
656
657
658
659
59 unmodified lines

719
720
721
722
722
723
724
725
159 unmodified lines

885
886
887
888
889
890
888
889
890
891
892
893
894
895
896
896
897
898
899
88 unmodified lines

988
989
990
991
991
992
993
994
20 unmodified lines

1015
1016
1017
1018
1018
1019
1020
1021
185 unmodified lines

1207
1208
1209
1210
1210
1211
1212
1213
1214
1215
1216
1217
1217
1218
1219
1220
1220
1221
1222
1223
14 unmodified lines

1238
1239
1240
1241
1242
1241
1242
1243
1244
1245
34 unmodified lines

1280
1281
1282
1283
1283
1284
1285
1286
1286
1287
1288
1289
1290
1290
1291
1292
1293
1294
1294
1295
1296
1296
1297
1298
1298
1299
1300
1301
135 unmodified lines

1437
1438
1439
1440
1440
1441
1442
1443

54 unmodified lines

// For task checkpoints (IsTask=true), additional files are written under tasks/<tool-use-id>/:
//   - For incremental checkpoints: checkpoints/NNN-<tool-use-id>.json
//   - For final checkpoints: checkpoint.json and agent-<agent-id>.jsonl
func (s *GitStore) WriteCommitted(ctx context.Context, opts WriteCommittedOptions) error {
func (s *GitStore) WriteCommitted(ctx context.Context, opts WriteOptions) error {
    // Validate identifiers to prevent path traversal and malformed data
    if opts.CheckpointID.IsEmpty() {
        return errors.New("invalid checkpoint options: checkpoint ID is required")
124 unmodified lines

}

// writeTaskCheckpointEntries writes task-specific checkpoint entries and returns the task metadata path.
func (s *GitStore) writeTaskCheckpointEntries(ctx context.Context, opts WriteCommittedOptions, basePath string, entries map[string]object.TreeEntry) (string, error) {
func (s *GitStore) writeTaskCheckpointEntries(ctx context.Context, opts WriteOptions, basePath string, entries map[string]object.TreeEntry) (string, error) {
    taskPath := basePath + "tasks/" + opts.ToolUseID + "/"

if opts.IsIncremental {
3 unmodified lines

}

// writeIncrementalTaskCheckpoint writes an incremental checkpoint file during task execution.
func (s *GitStore) writeIncrementalTaskCheckpoint(opts WriteCommittedOptions, taskPath string, entries map[string]object.TreeEntry) (string, error) {
func (s *GitStore) writeIncrementalTaskCheckpoint(opts WriteOptions, taskPath string, entries map[string]object.TreeEntry) (string, error) {
    incData, err := redact.JSONLBytes(opts.IncrementalData)
    if err != nil {
        return "", fmt.Errorf("failed to redact incremental checkpoint: %w", err)
24 unmodified lines

}

// writeFinalTaskCheckpoint writes the final checkpoint.json and subagent transcript.
func (s *GitStore) writeFinalTaskCheckpoint(ctx context.Context, opts WriteCommittedOptions, taskPath string, entries map[string]object.TreeEntry) (string, error) {
func (s *GitStore) writeFinalTaskCheckpoint(ctx context.Context, opts WriteOptions, taskPath string, entries map[string]object.TreeEntry) (string, error) {
    checkpoint := taskCheckpointData{
        SessionID:      opts.SessionID,
        ToolUseID:      opts.ToolUseID,
57 unmodified lines

//	basePath/
//	├── metadata.json         # CheckpointSummary (aggregated stats)
//	├── 1/                    # First session
//	│   ├── metadata.json     # CommittedMetadata (session-specific, includes initial_attribution)
//	│   ├── metadata.json     # Metadata (session-specific, includes initial_attribution)
//	│   ├── full.jsonl
//	│   ├── prompt.txt
//	│   └── content_hash.txt
//	├── 2/                    # Second session
//	└── ...
func (s *GitStore) writeStandardCheckpointEntries(ctx context.Context, opts WriteCommittedOptions, basePath string, entries map[string]object.TreeEntry) error {
func (s *GitStore) writeStandardCheckpointEntries(ctx context.Context, opts WriteOptions, basePath string, entries map[string]object.TreeEntry) error {
    // Read existing summary to get current session count
    var existingSummary *CheckpointSummary
    metadataPath := basePath + paths.MetadataFileName
87 unmodified lines

// writeSessionToSubdirectory writes a single session's files to a numbered subdirectory.
// Returns the absolute file paths from the git tree root for the sessions map.
func (s *GitStore) writeSessionToSubdirectory(ctx context.Context, opts WriteCommittedOptions, sessionPath string, entries map[string]object.TreeEntry) (SessionFilePaths, error) {
func (s *GitStore) writeSessionToSubdirectory(ctx context.Context, opts WriteOptions, sessionPath string, entries map[string]object.TreeEntry) (SessionFilePaths, error) {
    filePaths := SessionFilePaths{}

// Clear any existing entries at this path so stale files from a previous
30 unmodified lines

filePaths.Prompt = "/" + sessionPath + paths.PromptFileName
    }

// Write session-level metadata.json (CommittedMetadata with all fields including initial_attribution)
    sessionMetadata := CommittedMetadata{
    // Write session-level metadata.json (Metadata with all fields including initial_attribution)
    sessionMetadata := Metadata{
        CheckpointID:                opts.CheckpointID,
        SessionID:                   opts.SessionID,
        Strategy:                    opts.Strategy,
45 unmodified lines

// writeCheckpointSummary writes the root-level CheckpointSummary with aggregated statistics.
// sessions is the complete sessions array (already built by the caller).
func (s *GitStore) writeCheckpointSummary(opts WriteCommittedOptions, basePath string, entries map[string]object.TreeEntry, sessions []SessionFilePaths) error {
func (s *GitStore) writeCheckpointSummary(opts WriteOptions, basePath string, entries map[string]object.TreeEntry, sessions []SessionFilePaths) error {
    checkpointsCount, filesTouched, tokenUsage, err := s.reaggregateFromEntries(basePath, len(sessions), entries)
    if err != nil {
        return fmt.Errorf("failed to aggregate session stats: %w", err)
165 unmodified lines

return totalCount, allFiles, totalTokens, nil
}

func checkpointCreatedAt(opts WriteCommittedOptions) time.Time {
func checkpointCreatedAt(opts WriteOptions) time.Time {
    if opts.CreatedAt.IsZero() {
        return time.Now().UTC()
    }
59 unmodified lines

// writeTranscript writes the transcript and content hash to the checkpoint entries.
// Returns (true, nil) if files were written, (false, nil) if transcript was empty.
func (s *GitStore) writeTranscript(ctx context.Context, opts WriteCommittedOptions, basePath string, entries map[string]object.TreeEntry) (bool, error) {
func (s *GitStore) writeTranscript(ctx context.Context, opts WriteOptions, basePath string, entries map[string]object.TreeEntry) (bool, error) {
    logCtx := logging.WithComponent(ctx, "checkpoint")
    transcriptBytes := opts.Transcript.Bytes()

159 unmodified lines

return out
}

// readMetadataFromBlob reads CommittedMetadata from a blob hash.
func (s *GitStore) readMetadataFromBlob(hash plumbing.Hash) (*CommittedMetadata, error) {
    return readJSONFromBlob[CommittedMetadata](s.repo, hash)
// readMetadataFromBlob reads Metadata from a blob hash.
func (s *GitStore) readMetadataFromBlob(hash plumbing.Hash) (*Metadata, error) {
    return readJSONFromBlob[Metadata](s.repo, hash)
}

// buildCommitMessage constructs the commit message with proper trailers.
// The commit subject is always "Checkpoint: <id>" for consistency.
// If CommitSubject is provided (e.g., for task checkpoints), it's included in the body.
func (s *GitStore) buildCommitMessage(opts WriteCommittedOptions, taskMetadataPath string) string {
func (s *GitStore) buildCommitMessage(opts WriteOptions, taskMetadataPath string) string {
    var commitMsg strings.Builder

// Subject line is always the checkpoint ID for consistent formatting
88 unmodified lines

// ReadSessionMetadata reads only the metadata.json for a specific session within a checkpoint.
// This is a lightweight read that avoids fetching transcript/prompt blobs.
// sessionIndex is 0-based.
func (s *GitStore) ReadSessionMetadata(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*CommittedMetadata, error) {
func (s *GitStore) ReadSessionMetadata(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*Metadata, error) {
    if err := ctx.Err(); err != nil {
        return nil, err //nolint:wrapcheck // Propagating context cancellation
    }
20 unmodified lines

return nil, fmt.Errorf("failed to read session metadata: %w", err)
    }

var metadata CommittedMetadata
    var metadata Metadata
    if err := json.Unmarshal([]byte(content), &metadata); err != nil {
        return nil, fmt.Errorf("failed to parse session metadata: %w", err)
    }
185 unmodified lines

// Scans sharded paths: <id[:2]>/<id[2:]>/ directories containing metadata.json.
//

func (s *GitStore) ListCommitted(ctx context.Context) ([]CommittedInfo, error) {
func (s *GitStore) ListCommitted(ctx context.Context) ([]CheckpointInfo, error) {
    if err := ctx.Err(); err != nil {
        return nil, err //nolint:wrapcheck // Propagating context cancellation
    }

tree, err := s.getSessionsBranchTree()
    if err != nil {
        return []CommittedInfo{}, nil //nolint:nilerr // No sessions branch means empty list
        return []CheckpointInfo{}, nil //nolint:nilerr // No sessions branch means empty list
    }

var checkpoints []CommittedInfo
    var checkpoints []CheckpointInfo

// Scan sharded structure: <2-char-prefix>/<remaining-id>/metadata.json
    _ = WalkCheckpointShards(ctx, s.repo, tree, func(checkpointID id.CheckpointID, cpTreeHash plumbing.Hash) error { //nolint:errcheck // callback never returns errors
14 unmodified lines

return checkpoints, nil
}

func readCommittedInfoFromCheckpointTree(checkpointID id.CheckpointID, checkpointTree *object.Tree) CommittedInfo {
    info := CommittedInfo{
func readCommittedInfoFromCheckpointTree(checkpointID id.CheckpointID, checkpointTree *object.Tree) CheckpointInfo {
    info := CheckpointInfo{
        CheckpointID: checkpointID,
    }

34 unmodified lines

return info
}

func readCommittedMetadataFromCheckpointTree(checkpointTree *object.Tree, sessionIndex int) (CommittedMetadata, bool) {
func readCommittedMetadataFromCheckpointTree(checkpointTree *object.Tree, sessionIndex int) (Metadata, bool) {
    sessionTree, treeErr := checkpointTree.Tree(strconv.Itoa(sessionIndex))
    if treeErr != nil {
        return CommittedMetadata{}, false
        return Metadata{}, false
    }
    sessionMetadataFile, fileErr := sessionTree.File(paths.MetadataFileName)
    if fileErr != nil {
        return CommittedMetadata{}, false
        return Metadata{}, false
    }
    sessionContent, contentErr := sessionMetadataFile.Contents()
    if contentErr != nil {
        return CommittedMetadata{}, false
        return Metadata{}, false
    }
    var sessionMetadata CommittedMetadata
    var sessionMetadata Metadata
    if err := json.Unmarshal([]byte(sessionContent), &sessionMetadata); err != nil {
        return CommittedMetadata{}, false
        return Metadata{}, false
    }
    return sessionMetadata, true
}
135 unmodified lines

// with the complete session transcript (from prompt to stop event).
//
// Returns ErrCheckpointNotFound if the checkpoint doesn't exist.
func (s *GitStore) UpdateCommitted(ctx context.Context, opts UpdateCommittedOptions) error {
func (s *GitStore) UpdateCommitted(ctx context.Context, opts UpdateOptions) error {
    if opts.CheckpointID.IsEmpty() {
        return errors.New("invalid update options: checkpoint ID is required")
    }

Mcmd/entire/cli/checkpoint/committed.go+30/-30

45 unmodified lines

46
47
48
49
49
50
51
52

45 unmodified lines

store := NewGitStore(repo, DefaultV1Refs())
    cpID := id.MustCheckpointID("a1b2c3d4e5f6")

err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: cpID,
        SessionID:    "regression-no-opf-trailer",
        Strategy:     "manual-commit",

Mcmd/entire/cli/checkpoint/committed_opf_trailer_test.go+1/-1

39 unmodified lines

40
41
42
43
43
44
45
46
39 unmodified lines

86
87
88
89
89
90
91
92

39 unmodified lines

cpID := id.MustCheckpointID("d4e5f6a1b2c3")

// Write a checkpoint with NO transcript
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-no-transcript",
        Strategy:     "manual-commit",
39 unmodified lines

cpID := id.MustCheckpointID("e5f6a1b2c3d4")

// Write a checkpoint WITH a transcript
    err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-with-transcript",
        Strategy:     "manual-commit",

Mcmd/entire/cli/checkpoint/committed_phantom_paths_test.go+2/-2

84 unmodified lines

85
86
87
88
88
89
90
91

84 unmodified lines

store := NewGitStore(repo, refs)

cpID := id.MustCheckpointID("a1b2c3d4e5f6")
    require.NoError(t, store.WriteCommitted(context.Background(), WriteCommittedOptions{
    require.NoError(t, store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session",
        Strategy:     "manual-commit",

Mcmd/entire/cli/checkpoint/committed_read_store_test.go+1/-1

6 unmodified lines

7
8
9
10
11
10
11
12
13
14
15
16
17
18
19
20
16
17
18
19
20
21
22
23
24
24
25
26
27
28
29
28
29
30
31
32
5 unmodified lines

38
39
40
41
41
42
43
44
10 unmodified lines

55
56
57
58
58
59
60
61
5 unmodified lines

67
68
69
70
70
71
72
73

6 unmodified lines

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

// CommittedReader provides read access to committed checkpoint data.
type CommittedReader interface {
// PersistentReader provides read access to committed checkpoint data.
type PersistentReader interface {
    ReadCommitted(ctx context.Context, checkpointID id.CheckpointID) (*CheckpointSummary, error)
    ReadSessionContent(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*SessionContent, error)
}

// CommittedListReader provides read and list access to committed checkpoint data.
type CommittedListReader interface {
    CommittedReader
    ListCommitted(ctx context.Context) ([]CommittedInfo, error)
    ReadSessionMetadata(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*CommittedMetadata, error)
// PersistentListReader provides read and list access to committed checkpoint data.
type PersistentListReader interface {
    PersistentReader
    ListCommitted(ctx context.Context) ([]CheckpointInfo, error)
    ReadSessionMetadata(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*Metadata, error)
    ReadSessionPrompts(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (string, error)
}

// CommittedStore provides the production committed checkpoint storage surface.
// PersistentStore provides the production committed checkpoint storage surface.
// Writes go through the unified Writer.Write(ctx, WriteRequest); the concrete
// per-operation methods (WriteCommitted/UpdateCommitted/...) remain on GitStore
// as the implementation Write dispatches to.
type CommittedStore interface {
    CommittedListReader
type PersistentStore interface {
    PersistentListReader
    ReadSessionMetadataAndPrompts(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*SessionContent, error)
    Writer
}
5 unmodified lines

// ReadCommittedCheckpoint reads a committed checkpoint summary and normalizes
// a nil store response into ErrCheckpointNotFound.
func ReadCommittedCheckpoint(ctx context.Context, reader CommittedReader, checkpointID id.CheckpointID) (*CheckpointSummary, error) {
func ReadCommittedCheckpoint(ctx context.Context, reader PersistentReader, checkpointID id.CheckpointID) (*CheckpointSummary, error) {
    if err := ctx.Err(); err != nil {
        return nil, err //nolint:wrapcheck // Propagating context cancellation
    }
10 unmodified lines

// ReadLatestSessionContent reads the latest session from an already-resolved
// committed reader and summary.
func ReadLatestSessionContent(ctx context.Context, reader CommittedReader, checkpointID id.CheckpointID, summary *CheckpointSummary) (*SessionContent, error) {
func ReadLatestSessionContent(ctx context.Context, reader PersistentReader, checkpointID id.CheckpointID, summary *CheckpointSummary) (*SessionContent, error) {
    if summary == nil || len(summary.Sessions) == 0 {
        return nil, ErrCheckpointNotFound
    }
5 unmodified lines

return content, nil
}

func ReadRawSessionLogForCheckpoint(ctx context.Context, reader CommittedReader, checkpointID id.CheckpointID) ([]byte, string, error) {
func ReadRawSessionLogForCheckpoint(ctx context.Context, reader PersistentReader, checkpointID id.CheckpointID) ([]byte, string, error) {
    if err := ctx.Err(); err != nil {
        return nil, "", err //nolint:wrapcheck // Propagating context cancellation
    }

Mcmd/entire/cli/checkpoint/committed_reader_resolve.go+13/-13

55 unmodified lines

56
57
58
59
59
60
61
62
1 unmodified line

64
65
66
67
67
68
69
70

55 unmodified lines

ctx := context.Background()
    cpID := id.MustCheckpointID("222222222222")

require.NoError(t, store.WriteCommitted(ctx, WriteCommittedOptions{
    require.NoError(t, store.WriteCommitted(ctx, WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-a",
        Strategy:     "manual-commit",
1 unmodified line

AuthorName:   "Test",
        AuthorEmail:  "test@example.com",
    }))
    require.NoError(t, store.WriteCommitted(ctx, WriteCommittedOptions{
    require.NoError(t, store.WriteCommitted(ctx, WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-b",
        Strategy:     "manual-commit",

Mcmd/entire/cli/checkpoint/committed_reader_resolve_test.go+2/-2

39 unmodified lines

40
41
42
43
43
44
45
46
17 unmodified lines

64
65
66
67
67
68
69
70

39 unmodified lines

}
    basePath := checkpointID.Path() + "/"

oldMetadata := CommittedMetadata{
    oldMetadata := Metadata{
        CheckpointID: checkpointID,
        SessionID:    "session-old",
        Strategy:     "manual-commit",
17 unmodified lines

},
    }

opts := WriteCommittedOptions{
    opts := WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    "session-new",
        Strategy:     "manual-commit",

Mcmd/entire/cli/checkpoint/committed_tripwire_test.go+2/-2

50 unmodified lines

51
52
53
54
54
55
56
57
15 unmodified lines

73
74
75
76
76
77
78
79
17 unmodified lines

97
98
99
100
100
101
102
103
18 unmodified lines

122
123
124
125
125
126
127
128
20 unmodified lines

149
150
151
152
152
153
154
155
14 unmodified lines

170
171
172
173
173
174
175
176
22 unmodified lines

199
200
201
202
202
203
204
205
10 unmodified lines

216
217
218
219
219
220
221
222
21 unmodified lines

244
245
246
247
247
248
249
250
36 unmodified lines

287
288
289
290
290
291
292
293
8 unmodified lines

302
303
304
305
305
306
307
308
22 unmodified lines

331
332
333
334
334
335
336
337
152 unmodified lines

490
491
492
493
493
494
495
496
6 unmodified lines

503
504
505
506
506
507
508
509
100 unmodified lines

610
611
612
613
613
614
615
616
21 unmodified lines

638
639
640
641
641
642
643
644
5 unmodified lines

650
651
652
653
653
654
655
656
30 unmodified lines

687
688
689
690
690
691
692
693
2 unmodified lines

696
697
698
699
699
700
701
702

50 unmodified lines

store := NewGitStore(repo, DefaultV1Refs())
    cpID := id.MustCheckpointID("a1b2c3d4e5f6")

err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Strategy:     "manual-commit",
15 unmodified lines

// Update with full transcript (replace semantics)
    fullTranscript := []byte("full transcript line 1\nfull transcript line 2\nfull transcript line 3\n")
    err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Transcript:   redact.AlreadyRedacted(fullTranscript),
17 unmodified lines

t.Parallel()
    _, store, cpID := setupRepoForUpdate(t)

err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Prompts:      []string{"prompt 1", "prompt 2", "prompt 3"},
18 unmodified lines

_, store, cpID := setupRepoForUpdate(t)

fullTranscript := []byte("complete transcript\n")
    err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Transcript:   redact.AlreadyRedacted(fullTranscript),
20 unmodified lines

t.Parallel()
    _, store, _ := setupRepoForUpdate(t)

err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: id.MustCheckpointID("deadbeef1234"),
        SessionID:    "session-001",
        Transcript:   redact.AlreadyRedacted([]byte("should fail")),
14 unmodified lines

}

// Update only transcript
    err = store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    err = store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Transcript:   redact.AlreadyRedacted([]byte("updated transcript\n")),
22 unmodified lines

// Write a second checkpoint
    cpID2 := id.MustCheckpointID("b2c3d4e5f6a1")
    err := store.WriteCommitted(context.Background(), WriteCommittedOptions{
    err := store.WriteCommitted(context.Background(), WriteOptions{
        CheckpointID: cpID2,
        SessionID:    "session-001",
        Strategy:     "manual-commit",
10 unmodified lines

// Update both checkpoints with the same full transcript
    for _, cpID := range []id.CheckpointID{cpID1, cpID2} {
        err = store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
        err = store.UpdateCommitted(context.Background(), UpdateOptions{
            CheckpointID: cpID,
            SessionID:    "session-001",
            Transcript:   redact.AlreadyRedacted(fullTranscript),
21 unmodified lines

repo, store, cpID := setupRepoForUpdate(t)

// Update transcript
    err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Transcript:   redact.AlreadyRedacted([]byte("new full transcript content\n")),
36 unmodified lines

t.Parallel()
    _, store, _ := setupRepoForUpdate(t)

err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    err := store.UpdateCommitted(context.Background(), UpdateOptions{
        SessionID:  "session-001",
        Transcript: redact.AlreadyRedacted([]byte("should fail")),
    })
8 unmodified lines

// Update with wrong session ID — should fall back to latest (index 0)
    fullTranscript := []byte("updated via fallback\n")
    err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "nonexistent-session",
        Transcript:   redact.AlreadyRedacted(fullTranscript),
22 unmodified lines

t.Fatalf("ReadCommitted() before error = %v", err)
    }

err = store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    err = store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Transcript:   redact.AlreadyRedacted([]byte("updated\n")),
152 unmodified lines

// Write initial checkpoint
            store := NewGitStore(repo, DefaultV1Refs())
            cpID := id.MustCheckpointID("a1b2c3d4e5f6")
            err = store.WriteCommitted(context.Background(), WriteCommittedOptions{
            err = store.WriteCommitted(context.Background(), WriteOptions{
                CheckpointID: cpID,
                SessionID:    "session-001",
                Strategy:     "manual-commit",
6 unmodified lines

}

// Call UpdateCommitted — this is the operation under test
            err = store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
            err = store.UpdateCommitted(context.Background(), UpdateOptions{
                CheckpointID: cpID,
                SessionID:    "session-001",
                Transcript:   redact.AlreadyRedacted([]byte("full transcript\n")),
100 unmodified lines

t.Fatal("precompute returned zero content-hash blob")
    }

if err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    if err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID:     cpID,
        SessionID:        "session-001",
        Transcript:       transcript,
21 unmodified lines

transcript := redact.AlreadyRedacted([]byte("stable transcript content\n"))

if err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    if err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Transcript:   transcript,
5 unmodified lines

// should never touch the chunking function.
    calls := installChunkCounter(t)

if err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    if err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Transcript:   transcript,
30 unmodified lines

first := redact.AlreadyRedacted([]byte("first version\n"))
    second := redact.AlreadyRedacted([]byte("second version with more content\n"))

if err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    if err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Transcript:   first,
2 unmodified lines

}
    hashBefore := readTranscriptBlobHash(t, repo, cpID)

if err := store.UpdateCommitted(context.Background(), UpdateCommittedOptions{
    if err := store.UpdateCommitted(context.Background(), UpdateOptions{
        CheckpointID: cpID,
        SessionID:    "session-001",
        Transcript:   second,

Mcmd/entire/cli/checkpoint/committed_update_test.go+19/-19

23 unmodified lines

24
25
26
27
27
28
29
30
31
32
32
33
34
35
25 unmodified lines

61
62
63
64
64
65
66
66
67
68
69

23 unmodified lines

// WriteSession creates or replaces a session document within a checkpoint,
// materializing the checkpoint on its first session. This is condensation's
// write. (Maps to the former WriteCommitted.)
type WriteSession WriteCommittedOptions
type WriteSession WriteOptions

// BackfillTranscript replaces a session's transcript, prompts, and skill
// events at stop time without clobbering sibling fields. (Maps to the former
// UpdateCommitted.)
type BackfillTranscript UpdateCommittedOptions
type BackfillTranscript UpdateOptions

// BackfillSummary rewrites only the summary of the checkpoint's latest
// session. (Maps to the former UpdateSummary.)
25 unmodified lines

func (s *GitStore) Write(ctx context.Context, req WriteRequest) error {
    switch r := req.(type) {
    case WriteSession:
        return s.WriteCommitted(ctx, WriteCommittedOptions(r))
        return s.WriteCommitted(ctx, WriteOptions(r))
    case BackfillTranscript:
        return s.UpdateCommitted(ctx, UpdateCommittedOptions(r))
        return s.UpdateCommitted(ctx, UpdateOptions(r))
    case BackfillSummary:
        return s.UpdateSummary(ctx, r.CheckpointID, r.Summary)
    case BackfillAttribution:

Mcmd/entire/cli/checkpoint/committed_write.go+4/-4

23 unmodified lines

24
25
26
27
27
28
29
30

23 unmodified lines

// temporary capability and resolved committed-ref topology.
type Stores struct {
    // Primary is the committed store that serves committed reads and writes.
    Primary CommittedStore
    Primary PersistentStore

temporary TemporaryStore
    refs      CommittedRefs

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

7 unmodified lines

8
9
10
11
12
13
14
11
12
13
14
15
16
17

7 unmodified lines

)

var (
    _ CommittedStore = (*GitStore)(nil)
    _ AuthorReader   = (*GitStore)(nil)
    _ Writer         = (*GitStore)(nil)
    _ TemporaryStore = (*ephemeralStore)(nil)
    _ PersistentStore = (*GitStore)(nil)
    _ AuthorReader    = (*GitStore)(nil)
    _ Writer          = (*GitStore)(nil)
    _ TemporaryStore  = (*ephemeralStore)(nil)
)

// GitStore is the committed (persistent) checkpoint store. Writes target

Mcmd/entire/cli/checkpoint/store.go+4/-4

324 unmodified lines

325
326
327
328
328
329
330
331
60 unmodified lines

392
393
394
395
395
396
397
398
435 unmodified lines

834
835
836
837
837
838
839
840

324 unmodified lines

if err != nil {
        t.Fatal(err)
    }
    err = store.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID:     parsedID,
        SessionID:        "session-1",
        Strategy:         "manual-commit",
60 unmodified lines

if err != nil {
        t.Fatal(err)
    }
    err = store.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID:     parsedID,
        SessionID:        "session-1",
        Strategy:         "manual-commit",
435 unmodified lines

t.Fatal(err)
    }

err = store.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    err = store.WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID:     cpID,
        SessionID:        "session-1",
        Strategy:         "manual-commit",

Mcmd/entire/cli/dispatch/mode_local_test.go+3/-3

88 unmodified lines

89
90
91
92
93
92
93
94
95
96
1474 unmodified lines

1571
1572
1573
1574
1574
1575
1576
1576
1577
1578
1579
177 unmodified lines

1757
1758
1759
1760
1760
1761
1762
1763
284 unmodified lines

2048
2049
2050
2051
2051
2052
2053
2054
104 unmodified lines

2159
2160
2161
2162
2162
2163
2164
2165

88 unmodified lines

type explainCheckpointLookup struct {
    repo      *git.Repository
    store     checkpoint.CommittedStore
    committed []checkpoint.CommittedInfo
    store     checkpoint.PersistentStore
    committed []checkpoint.CheckpointInfo
}

func (l *explainCheckpointLookup) Close() error {
1474 unmodified lines

// into ambiguousMatch entries enriched with timestamps and session IDs from
// the loaded committed-checkpoint listing. Caps at 5 entries to keep the
// failure block readable when a short prefix collides on many checkpoints.
func buildAmbiguousCheckpointMatches(ids []id.CheckpointID, committed []checkpoint.CommittedInfo) []ambiguousMatch {
func buildAmbiguousCheckpointMatches(ids []id.CheckpointID, committed []checkpoint.CheckpointInfo) []ambiguousMatch {
    const maxMatches = 5
    infoByID := make(map[id.CheckpointID]checkpoint.CommittedInfo, len(committed))
    infoByID := make(map[id.CheckpointID]checkpoint.CheckpointInfo, len(committed))
    for _, info := range committed {
        infoByID[info.CheckpointID] = info
    }
177 unmodified lines

// otherwise the same compact shape is returned as plain text.
func formatCheckpointHeader(
    summary *checkpoint.CheckpointSummary,
    meta checkpoint.CommittedMetadata,
    meta checkpoint.Metadata,
    cpID id.CheckpointID,
    commits []associatedCommit,
    author checkpoint.Author,
284 unmodified lines

}

// Build map of checkpoint ID -> committed info
    committedByID := make(map[id.CheckpointID]checkpoint.CommittedInfo)
    committedByID := make(map[id.CheckpointID]checkpoint.CheckpointInfo)
    for _, info := range committedInfos {
        if !info.CheckpointID.IsEmpty() {
            committedByID[info.CheckpointID] = info
104 unmodified lines

return points, nil
}

func readLatestCommittedSessionPrompt(ctx context.Context, store checkpoint.CommittedListReader, cpID id.CheckpointID, sessionCount int) string {
func readLatestCommittedSessionPrompt(ctx context.Context, store checkpoint.PersistentListReader, cpID id.CheckpointID, sessionCount int) string {
    if sessionCount <= 0 {
        return ""
    }

Mcmd/entire/cli/explain.go+7/-7

282 unmodified lines

283
284
285
286
286
287
288
289
95 unmodified lines

385
386
387
388
388
389
390
391
30 unmodified lines

422
423
424
425
425
426
427
427
428
429
430
1 unmodified line

432
433
434
435
435
436
437
438
4 unmodified lines

443
444
445
446
446
447
448
449

282 unmodified lines

// checkpointExportJSON is the metadata-only envelope returned by
// `entire checkpoint explain --json`. It exposes only existing CheckpointSummary
// and CommittedMetadata fields — no schema invention, no transcript bytes.
// and Metadata fields — no schema invention, no transcript bytes.
//
// `partial` is true when any session metadata read failed; the offending
// entries surface their cause via Sessions[].error. Consumers that don't
95 unmodified lines

// plus the list of session indexes that failed to read; a non-empty failed
// list means envelope.Partial is true. Extracted from runExplainCheckpointJSON so
// the envelope-building behavior can be tested independently of git storage.
func buildCheckpointJSONEnvelope(ctx context.Context, reader checkpoint.CommittedReader, summary *checkpoint.CheckpointSummary, cpID id.CheckpointID) (checkpointExportJSON, []int) {
func buildCheckpointJSONEnvelope(ctx context.Context, reader checkpoint.PersistentReader, summary *checkpoint.CheckpointSummary, cpID id.CheckpointID) (checkpointExportJSON, []int) {
    envelope := checkpointExportJSON{
        CheckpointID:     cpID.String(),
        Strategy:         summary.Strategy,
30 unmodified lines

// readSessionMetadataForExport reads only metadata.json for a session — no
// transcript or prompt bytes. GitStore exposes a metadata-only reader, so this
// never depends on transcript availability.
func readSessionMetadataForExport(ctx context.Context, reader checkpoint.CommittedReader, cpID id.CheckpointID, idx int) (*checkpoint.CommittedMetadata, error) {
func readSessionMetadataForExport(ctx context.Context, reader checkpoint.PersistentReader, cpID id.CheckpointID, idx int) (*checkpoint.Metadata, error) {
    if r, ok := reader.(interface {
        ReadSessionMetadata(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*checkpoint.CommittedMetadata, error)
        ReadSessionMetadata(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*checkpoint.Metadata, error)
    }); ok {
        meta, err := r.ReadSessionMetadata(ctx, cpID, idx)
        if err != nil {
1 unmodified line

}
        return meta, nil
    }
    // CommittedReader doesn't promise a metadata-only method; fall back
    // PersistentReader doesn't promise a metadata-only method; fall back
    // to the heavier ReadSessionContent path. Reachable only if a third
    // store implementation is added without exposing metadata reads.
    content, err := reader.ReadSessionContent(ctx, cpID, idx)
4 unmodified lines

return &meta, nil
}

func sessionMetadataToJSON(idx int, meta *checkpoint.CommittedMetadata) checkpointSessionJSON {
func sessionMetadataToJSON(idx int, meta *checkpoint.Metadata) checkpointSessionJSON {
    out := checkpointSessionJSON{
        Index:            idx,
        SessionID:        meta.SessionID,

Mcmd/entire/cli/explain_export.go+6/-6

59 unmodified lines

60
61
62
63
63
64
65
66
15 unmodified lines

82
83
84
85
85
86
87
88
38 unmodified lines

127
128
129
130
130
131
132
133
32 unmodified lines

166
167
168
169
169
170
171
172
22 unmodified lines

195
196
197
198
198
199
200
201
15 unmodified lines

217
218
219
220
220
221
222
223
13 unmodified lines

237
238
239
240
240
241
242
243
18 unmodified lines

262
263
264
265
265
266
267
268
21 unmodified lines

290
291
292
293
293
294
295
296
297
298
298
299
300
301
35 unmodified lines

337
338
339
340
340
341
342
343
80 unmodified lines

424
425
426
427
427
428
429
430
58 unmodified lines

489
490
491
492
492
493
494
495
36 unmodified lines

532
533
534
535
535
536
537
538
160 unmodified lines

699
700
701
702
702
703
704
705
706
707
707
708
709
710
23 unmodified lines

734
735
736
737
737
738
739
740

59 unmodified lines

return repo
}

func writeCheckpointForExport(t *testing.T, repo *git.Repository, cpID id.CheckpointID, opts checkpoint.WriteCommittedOptions) {
func writeCheckpointForExport(t *testing.T, repo *git.Repository, cpID id.CheckpointID, opts checkpoint.WriteOptions) {
    t.Helper()
    if opts.CheckpointID.IsEmpty() {
        opts.CheckpointID = cpID
15 unmodified lines

repo := setupExportRepo(t)

cpID := id.MustCheckpointID("aaaa11112222")
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteOptions{
        SessionID:  "session-json",
        Transcript: redact.AlreadyRedacted([]byte(`{"type":"user","message":{"content":[{"type":"text","text":"hi"}]}}` + "\n")),
    })
38 unmodified lines

runGit(t, tmpDir, "clone", "--branch", "main", bareDir, localDir)

targetID := id.MustCheckpointID("aaaa99998888")
    writeCheckpointForExport(t, producerRepo, targetID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, producerRepo, targetID, checkpoint.WriteOptions{
        SessionID:  "remote-v1-session",
        Transcript: redact.AlreadyRedacted([]byte(`{"type":"user","message":{"content":[{"type":"text","text":"remote"}]}}` + "\n")),
    })
32 unmodified lines

cpID := id.MustCheckpointID("777711112222")
    v1 := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    require.NoError(t, v1.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    require.NoError(t, v1.WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-v1-only",
        Strategy:     "manual-commit",
22 unmodified lines

repo := setupExportRepo(t)

cpID := id.MustCheckpointID("bbbb11112222")
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteOptions{
        SessionID:  "session-no-leak",
        Transcript: redact.AlreadyRedacted([]byte(`{"type":"user","message":{"content":[{"type":"text","text":"SECRET-RAW"}]}}` + "\n")),
    })
15 unmodified lines

cpID := id.MustCheckpointID("cccc11112222")
    raw := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"stored line"}]}}` + "\n")
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteOptions{
        SessionID:  "session-stored",
        Transcript: redact.AlreadyRedacted(raw),
    })
13 unmodified lines

cpID := id.MustCheckpointID("dddd11112222")
    raw := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"hello raw"}]}}` + "\n")
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteOptions{
        SessionID:  "session-raw",
        Transcript: redact.AlreadyRedacted(raw),
    })
18 unmodified lines

cpID := id.MustCheckpointID("ffff11112222")
    raw0 := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"hello session 0"}]}}` + "\n")
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteOptions{
        SessionID:  "session-zero",
        Transcript: redact.AlreadyRedacted(raw0),
    })
21 unmodified lines

rawSession0 := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"SESSION-ZERO-MARKER"}]}}` + "\n")
    rawSession1 := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"SESSION-ONE-DIFFERENT-MARKER"}]}}` + "\n")

writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteOptions{
        SessionID:  "session-zero",
        Transcript: redact.AlreadyRedacted(rawSession0),
    })
    // Second fixture write with the same checkpoint ID appends session 1.
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteOptions{
        SessionID:  "session-one",
        Transcript: redact.AlreadyRedacted(rawSession1),
    })
35 unmodified lines

repo := setupExportRepo(t)

cpID := id.MustCheckpointID("eeee11112222")
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteOptions{
        SessionID:  "session-only",
        Transcript: redact.AlreadyRedacted([]byte(`{"type":"user","message":{"content":[{"type":"text","text":"hi"}]}}` + "\n")),
    })
80 unmodified lines

repo := setupExportRepo(t)

cpID := id.MustCheckpointID("aaaabbbb1234")
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteCommittedOptions{
    writeCheckpointForExport(t, repo, cpID, checkpoint.WriteOptions{
        SessionID:  "session-via-commit",
        Transcript: redact.AlreadyRedacted([]byte(`{"type":"user","message":{"content":[{"type":"text","text":"hi"}]}}` + "\n")),
    })
58 unmodified lines

require.Empty(t, stdout.String(), "must not emit JSON when no mode is set")
}

// stubCommittedReader is a minimal CommittedReader that returns canned
// stubCommittedReader is a minimal PersistentReader that returns canned
// metadata or errors per session index. Used to exercise the partial-failure
// path in buildCheckpointJSONEnvelope without corrupting a real git tree.
type stubCommittedReader struct {
36 unmodified lines

reader := &stubCommittedReader{
        summary: summary,
        contents: map[int]*checkpoint.SessionContent{
            0: {Metadata: checkpoint.CommittedMetadata{
            0: {Metadata: checkpoint.Metadata{
                SessionID: "good-session",
                Agent:     "Claude Code",
            }},
160 unmodified lines

}

// TestSessionMetadataToJSON_CopiesInvestigateFields pins that
// sessionMetadataToJSON copies the investigate fields from CommittedMetadata
// sessionMetadataToJSON copies the investigate fields from Metadata
// into the per-session JSON struct.
func TestSessionMetadataToJSON_CopiesInvestigateFields(t *testing.T) {
    t.Parallel()

meta := &checkpoint.CommittedMetadata{
    meta := &checkpoint.Metadata{
        SessionID:        "investigate-session",
        Kind:             "agent_investigate",
        InvestigateRunID: "0123456789ab",
23 unmodified lines

reader := &stubCommittedReader{
        summary: summary,
        contents: map[int]*checkpoint.SessionContent{
            0: {Metadata: checkpoint.CommittedMetadata{
            0: {Metadata: checkpoint.Metadata{
                SessionID:        "investigate-session",
                Kind:             "agent_investigate",
                InvestigateRunID: "0123456789ab",

Mcmd/entire/cli/explain_export_test.go+17/-17

413 unmodified lines

414
415
416
417
417
418
419
420
254 unmodified lines

675
676
677
678
678
679
680
681
86 unmodified lines

768
769
770
771
771
772
773
774
1218 unmodified lines

1993
1994
1995
1996
1996
1997
1998
1999
57 unmodified lines

2057
2058
2059
2060
2060
2061
2062
2063
61 unmodified lines

2125
2126
2127
2128
2128
2129
2130
2131
74 unmodified lines

2206
2207
2208
2209
2209
2210
2211
2212
70 unmodified lines

2283
2284
2285
2286
2286
2287
2288
2289
51 unmodified lines

2341
2342
2343
2344
2344
2345
2346
2347
42 unmodified lines

2390
2391
2392
2393
2393
2394
2395
2396
163 unmodified lines

2560
2561
2562
2563
2563
2564
2565
2566
35 unmodified lines

2602
2603
2604
2605
2605
2606
2607
2608
122 unmodified lines

2731
2732
2733
2734
2734
2735
2736
2737
37 unmodified lines

2775
2776
2777
2778
2778
2779
2780
2781
25 unmodified lines

2807
2808
2809
2810
2810
2811
2812
2813
62 unmodified lines

2876
2877
2878
2879
2879
2880
2881
2882
49 unmodified lines

2932
2933
2934
2935
2935
2936
2937
2938
26 unmodified lines

2965
2966
2967
2968
2968
2969
2970
2971
38 unmodified lines

3010
3011
3012
3013
3013
3014
3015
3016
64 unmodified lines

3081
3082
3083
3084
3084
3085
3086
3087
207 unmodified lines

3295
3296
3297
3298
3298
3299
3300
3301
26 unmodified lines

3328
3329
3330
3331
3331
3332
3333
3334
10 unmodified lines

3345
3346
3347
3348
3348
3349
3350
3351
10 unmodified lines

3362
3363
3364
3365
3365
3366
3367
3368
20 unmodified lines

3389
3390
3391
3392
3392
3393
3394
3395
10 unmodified lines

3406
3407
3408
3409
3409
3410
3411
3412
10 unmodified lines

3423
3424
3425
3426
3426
3427
3428
3429
14 unmodified lines

3444
3445
3446
3447
3447
3448
3449
3450
1205 unmodified lines

4656
4657
4658
4659
4659
4660
4661
4662
25 unmodified lines

4688
4689
4690
4691
4691
4692
4693
4694
26 unmodified lines

4721
4722
4723
4724
4724
4725
4726
4727
265 unmodified lines

4993
4994
4995
4996
4996
4997
4998
4999
24 unmodified lines

5024
5025
5026
5027
5027
5028
5029
5030
253 unmodified lines

5284
5285
5286
5287
5287
5288
5289
5290
469 unmodified lines

5760
5761
5762
5763
5763
5764
5765
5766
214 unmodified lines

5981
5982
5983
5984
5984
5985
5986
5987
61 unmodified lines

6049
6050
6051
6052
6052
6053
6054
6055
66 unmodified lines

6122
6123
6124
6125
6125
6126
6127
6128

413 unmodified lines

ctx := context.Background()

cpID := id.MustCheckpointID("deadbeefcafe")
    require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-auto",
        Strategy:     "manual-commit",
254 unmodified lines

id.MustCheckpointID("e7aaaaaaaaaa"),
        id.MustCheckpointID("e7bbbbbbbbbb"),
    } {
        require.NoError(t, store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
        require.NoError(t, store.WriteCommitted(ctx, checkpoint.WriteOptions{
            CheckpointID: cpID,
            SessionID:    "session-" + cpID.String(),
            Strategy:     "manual-commit",
86 unmodified lines

commitPrefix := head.Hash().String()[:7]
    collisionID := id.MustCheckpointID(commitPrefix + "aaaaa")

require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: collisionID,
        SessionID:    "session-collision",
        Strategy:     "manual-commit",
1218 unmodified lines

`{"type":"user","message":{"content":[{"type":"text","text":"old prompt before checkpoint"}]}}` + "\n" +
            `{"type":"user","message":{"content":[{"type":"text","text":"scoped prompt for checkpoint"}]}}` + "\n",
    )
    require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID:              cpID,
        SessionID:                 "session-v1",
        Strategy:                  "manual-commit",
57 unmodified lines

cpID := id.MustCheckpointID("ab12ab12ab12")
    ctx := context.Background()
    require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-v1-only-generate",
        Strategy:     "manual-commit",
61 unmodified lines

}

cpID := id.MustCheckpointID("cd12cd12cd12")
    require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-v1-mode-generate",
        Strategy:     "manual-commit",
74 unmodified lines

transcript := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"generate test"}]}}` + "\n" +
        `{"type":"assistant","message":{"content":"done"}}` + "\n")

require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-v1",
        Strategy:     "manual-commit",
70 unmodified lines

transcript := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"generate v1 test"}]}}` + "\n" +
        `{"type":"assistant","message":{"content":"done"}}` + "\n")

require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-v1",
        Strategy:     "manual-commit",
51 unmodified lines

`{"type":"assistant","message":{"content":"raw reply"}}` + "\n",
    )

require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-v1-transcript",
        Strategy:     "manual-commit",
42 unmodified lines

rawTranscript := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"v1 raw fallback prompt"}]}}` + "\n" +
        `{"type":"assistant","message":{"content":"v1 raw reply"}}` + "\n")

require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-v1-fallback",
        Strategy:     "manual-commit",
163 unmodified lines

v1Store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())

nativeTranscript := []byte("EXTERNAL_NATIVE_TRANSCRIPT\nuser=external native prompt\nassistant=external native reply\n")
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-external-display",
        Strategy:     "manual-commit",
35 unmodified lines

v1Store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())

nativeTranscript := []byte("EXTERNAL_NATIVE_BEFORE\nEXTERNAL_NATIVE_SCOPE\nuser=scoped external prompt\nassistant=scoped external reply\n")
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID:              cpID,
        SessionID:                 "session-external-verbose",
        Strategy:                  "manual-commit",
122 unmodified lines

v1Store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())

nativeTranscript := []byte("EXTERNAL_NATIVE_TRANSCRIPT\nuser=unparseable native prompt\nassistant=unparseable native reply\n")
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-external-fallback",
        Strategy:     "manual-commit",
37 unmodified lines

transcript := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"hello"}]}}` + "\n")

v1ID := id.MustCheckpointID("ccc777888999")
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    require.NoError(t, v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: v1ID,
        SessionID:    "session-v1",
        Strategy:     "manual-commit",
25 unmodified lines

},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:     "abc123def456",
            SessionID:        "2026-01-21-test-session",
            CreatedAt:        time.Date(2026, 1, 21, 10, 30, 0, 0, time.UTC),
62 unmodified lines

},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:              "abc123def456",
            SessionID:                 "2026-01-21-test-session",
            CreatedAt:                 time.Date(2026, 1, 21, 10, 30, 0, 0, time.UTC),
49 unmodified lines

FilesTouched:     []string{"main.go"},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:     "abc123def456",
            SessionID:        "2026-01-21-test-session",
            CreatedAt:        time.Date(2026, 1, 21, 10, 30, 0, 0, time.UTC),
26 unmodified lines

},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:     "abc123def456",
            SessionID:        "2026-01-21-test-session",
            CreatedAt:        time.Date(2026, 1, 21, 10, 30, 0, 0, time.UTC),
38 unmodified lines

FilesTouched: []string{"file1.go", "file2.go"},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID: cpID,
            SessionID:    "2026-01-22-test-session",
            CreatedAt:    time.Date(2026, 1, 22, 10, 30, 0, 0, time.UTC),
64 unmodified lines

cpID := id.MustCheckpointID("abc123456789")
    summary := &checkpoint.CheckpointSummary{CheckpointID: cpID}
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID: cpID,
            SessionID:    "2026-01-22-test-session",
            CreatedAt:    time.Date(2026, 1, 22, 10, 30, 0, 0, time.UTC),
207 unmodified lines

summary := &checkpoint.CheckpointSummary{
        TokenUsage: &agent.TokenUsage{InputTokens: 18432},
    }
    meta := checkpoint.CommittedMetadata{
    meta := checkpoint.Metadata{
        SessionID: "2026-04-29-7f3c1a",
        CreatedAt: time.Date(2026, 4, 29, 14, 22, 8, 0, time.UTC),
    }
26 unmodified lines

t.Parallel()

cpID := id.MustCheckpointID("a3b2c4d5e6f7")
    meta := checkpoint.CommittedMetadata{
    meta := checkpoint.Metadata{
        SessionID: "s",
        CreatedAt: time.Date(2026, 4, 29, 14, 22, 8, 0, time.UTC),
    }
10 unmodified lines

t.Parallel()

t.Parallel()

cpID := id.MustCheckpointID("a3b2c4d5e6f7")
    meta := checkpoint.CommittedMetadata{
    meta := checkpoint.Metadata{
        SessionID: "s",
        CreatedAt: time.Date(2026, 4, 29, 14, 22, 8, 0, time.UTC),
    }
20 unmodified lines

t.Parallel()

t.Parallel()

t.Parallel()

cpID := id.MustCheckpointID("a3b2c4d5e6f7")
    meta := checkpoint.CommittedMetadata{
    meta := checkpoint.Metadata{
        SessionID:  "s",
        CreatedAt:  time.Date(2026, 4, 29, 14, 22, 8, 0, time.UTC),
        TokenUsage: nil,
14 unmodified lines

t.Parallel()

cpID := id.MustCheckpointID("a3b2c4d5e6f7")
    meta := checkpoint.CommittedMetadata{
    meta := checkpoint.Metadata{
        SessionID:  "s",
        CreatedAt:  time.Date(2026, 4, 29, 14, 22, 8, 0, time.UTC),
        TokenUsage: &agent.TokenUsage{InputTokens: 1234},
1205 unmodified lines

FilesTouched: []string{"main.go"},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:              "abc123def456",
            SessionID:                 "2026-01-30-test-session",
            CreatedAt:                 time.Date(2026, 1, 30, 10, 30, 0, 0, time.UTC),
25 unmodified lines

FilesTouched: []string{"main.go"},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:              "abc123def456",
            SessionID:                 "2026-01-30-test-session",
            CreatedAt:                 time.Date(2026, 1, 30, 10, 30, 0, 0, time.UTC),
26 unmodified lines

FilesTouched: []string{"main.go"},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:              "abc123def456",
            SessionID:                 "2026-01-30-test-session",
            CreatedAt:                 time.Date(2026, 1, 30, 10, 30, 0, 0, time.UTC),
265 unmodified lines

FilesTouched: []string{"main.go"},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:              "abc123def456",
            SessionID:                 "2026-01-30-test-session",
            CreatedAt:                 time.Date(2026, 1, 30, 10, 30, 0, 0, time.UTC),
24 unmodified lines

FilesTouched: []string{"main.go"},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:              "abc123def456",
            SessionID:                 "2026-01-30-test-session",
            CreatedAt:                 time.Date(2026, 1, 30, 10, 30, 0, 0, time.UTC),
253 unmodified lines

FilesTouched: []string{"main.go"},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:              "abc123def456",
            SessionID:                 "2026-02-04-test-session",
            CreatedAt:                 time.Date(2026, 2, 4, 10, 30, 0, 0, time.UTC),
469 unmodified lines

FilesTouched: []string{"main.go"},
    }
    content := &checkpoint.SessionContent{
        Metadata: checkpoint.CommittedMetadata{
        Metadata: checkpoint.Metadata{
            CheckpointID:              "abc123def456",
            SessionID:                 "2026-02-04-test-session",
            CreatedAt:                 time.Date(2026, 2, 4, 10, 30, 0, 0, time.UTC),
214 unmodified lines

// Write committed checkpoint metadata so getBranchCheckpoints can find it
    store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    if err := store.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    if err := store.WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "test-session",
        Strategy:     "manual-commit",
61 unmodified lines

expectedPrompt := "Refactor the authentication module to use JWT tokens"
    store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    if err := store.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    if err := store.WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "2026-02-27-test-session",
        Strategy:     "manual-commit",
66 unmodified lines

cpID := id.MustCheckpointID("bbcc33445566")
    store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    for _, sessionID := range []string{"older-session-aaaa", "latest-session-bbbb"} {
        require.NoError(t, store.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
        require.NoError(t, store.WriteCommitted(context.Background(), checkpoint.WriteOptions{
            CheckpointID: cpID,
            SessionID:    sessionID,
            Strategy:     "manual-commit",

Mcmd/entire/cli/explain_test.go+38/-38

45 unmodified lines

46
47
48
49
49
50
51
52

45 unmodified lines

t.Helper()
    cpID := id.MustCheckpointID("aabbccdd1122")
    store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    require.NoError(t, store.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    require.NoError(t, store.WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID:     cpID,
        SessionID:        "head-flags-session",
        Strategy:         "manual-commit",

Mcmd/entire/cli/head_checkpoint_flags_test.go+1/-1

163 unmodified lines

164
165
166
167
167
168
169
170
136 unmodified lines

307
308
309
310
310
311
312
313
540 unmodified lines

854
855
856
857
857
858
859
860

163 unmodified lines

t.Fatalf("Failed to read metadata content: %v", err)
    }

var metadata checkpoint.CommittedMetadata
    var metadata checkpoint.Metadata
    if err := json.Unmarshal([]byte(metadataContent), &metadata); err != nil {
        t.Fatalf("Failed to parse metadata.json: %v", err)
    }
136 unmodified lines

t.Fatalf("Failed to read metadata content: %v", err)
    }

var metadata checkpoint.CommittedMetadata
    var metadata checkpoint.Metadata
    if err := json.Unmarshal([]byte(metadataContent), &metadata); err != nil {
        t.Fatalf("Failed to parse metadata.json: %v", err)
    }
540 unmodified lines

t.Fatalf("Failed to read metadata content: %v", err)
    }

var metadata checkpoint.CommittedMetadata
    var metadata checkpoint.Metadata
    if err := json.Unmarshal([]byte(metadataContent), &metadata); err != nil {
        t.Fatalf("Failed to parse metadata.json: %v", err)
    }

Mcmd/entire/cli/integration_test/attribution_test.go+3/-3

691 unmodified lines

692
693
694
695
695
696
697
698

691 unmodified lines

if !found {
        t.Fatal("session metadata.json should be readable")
    }
    var sessionMetadata checkpoint.CommittedMetadata
    var sessionMetadata checkpoint.Metadata
    if err := json.Unmarshal([]byte(sessionMetadataContent), &sessionMetadata); err != nil {
        t.Fatalf("failed to parse session metadata.json: %v", err)
    }

Mcmd/entire/cli/integration_test/manual_commit_workflow_test.go+1/-1

289 unmodified lines

290
291
292
293
293
294
295
296
1 unmodified line

298
299
300
301
301
302
303
304

289 unmodified lines

return summary
}

func readSessionMetadata(t *testing.T, env *TestEnv, checkpointID string) checkpoint.CommittedMetadata {
func readSessionMetadata(t *testing.T, env *TestEnv, checkpointID string) checkpoint.Metadata {
    t.Helper()

content, found := env.ReadFileFromBranch(paths.MetadataBranchName, SessionMetadataPath(checkpointID))
1 unmodified line

t.Fatalf("session metadata not found for %s", checkpointID)
    }

var metadata checkpoint.CommittedMetadata
    var metadata checkpoint.Metadata
    if err := json.Unmarshal([]byte(content), &metadata); err != nil {
        t.Fatalf("failed to parse session metadata: %v\n%s", err, content)
    }

Mcmd/entire/cli/integration_test/review_test.go+2/-2

947 unmodified lines

948
949
950
951
951
952
953
954
586 unmodified lines

1541
1542
1543
1544
1544
1545
1546
1547
3 unmodified lines

1551
1552
1553
1554
1554
1555
1556
1557
57 unmodified lines

1615
1616
1617
1618
1618
1619
1620
1621
3 unmodified lines

1625
1626
1627
1628
1628
1629
1630
1630
1631
1632
1633
1634
1635
1635
1636
1637
1638
1639
1640
1640
1641
1642
1643
1644
1645
1645
1646
1647
1648
1649
1650
1650
1651
1652
1653
4 unmodified lines

1658
1659
1660
1661
1661
1662
1663
1664
1665
1666
1667
1668
1668
1669
1670
1671

947 unmodified lines

if !found {
        return false
    }
    var meta checkpoint.CommittedMetadata
    var meta checkpoint.Metadata
    if err := json.Unmarshal([]byte(content), &meta); err != nil {
        return false
    }
586 unmodified lines

// ValidateCheckpoint performs comprehensive validation of a checkpoint on the metadata branch.
// It validates:
// - Root metadata.json (CheckpointSummary) structure and expected fields
// - Session metadata.json (CommittedMetadata) structure and expected fields
// - Session metadata.json (Metadata) structure and expected fields
// - Transcript file (full.jsonl) is valid JSONL and contains expected content
// - Content hash file (content_hash.txt) matches SHA256 of transcript
// - Prompt file (prompt.txt) contains expected prompts
3 unmodified lines

// Validate root metadata.json (CheckpointSummary)
    env.validateCheckpointSummary(v)

// Validate session metadata.json (CommittedMetadata)
    // Validate session metadata.json (Metadata)
    env.validateSessionMetadata(v)

// Validate transcript is valid JSONL
57 unmodified lines

}
}

// validateSessionMetadata validates the session-level metadata.json (CommittedMetadata).
// validateSessionMetadata validates the session-level metadata.json (Metadata).
func (env *TestEnv) validateSessionMetadata(v CheckpointValidation) {
    env.T.Helper()

3 unmodified lines

env.T.Fatalf("Session metadata not found at %s", metadataPath)
    }

var metadata checkpoint.CommittedMetadata
    var metadata checkpoint.Metadata
    if err := json.Unmarshal([]byte(content), &metadata); err != nil {
        env.T.Fatalf("Failed to parse CommittedMetadata: %v\nContent: %s", err, content)
        env.T.Fatalf("Failed to parse Metadata: %v\nContent: %s", err, content)
    }

// Validate checkpoint_id
    if metadata.CheckpointID.String() != v.CheckpointID {
        env.T.Errorf("CommittedMetadata.CheckpointID = %q, want %q", metadata.CheckpointID, v.CheckpointID)
        env.T.Errorf("Metadata.CheckpointID = %q, want %q", metadata.CheckpointID, v.CheckpointID)
    }

// Validate session_id
    if v.SessionID != "" && metadata.SessionID != v.SessionID {
        env.T.Errorf("CommittedMetadata.SessionID = %q, want %q", metadata.SessionID, v.SessionID)
        env.T.Errorf("Metadata.SessionID = %q, want %q", metadata.SessionID, v.SessionID)
    }

// Validate strategy
    if v.Strategy != "" && metadata.Strategy != v.Strategy {
        env.T.Errorf("CommittedMetadata.Strategy = %q, want %q", metadata.Strategy, v.Strategy)
        env.T.Errorf("Metadata.Strategy = %q, want %q", metadata.Strategy, v.Strategy)
    }

// Validate created_at is not zero
    if metadata.CreatedAt.IsZero() {
        env.T.Error("CommittedMetadata.CreatedAt should not be zero")
        env.T.Error("Metadata.CreatedAt should not be zero")
    }

// Validate files_touched
4 unmodified lines

}
        for _, expected := range v.FilesTouched {
            if !touchedSet[expected] {
                env.T.Errorf("CommittedMetadata.FilesTouched missing %q, got %v", expected, metadata.FilesTouched)
                env.T.Errorf("Metadata.FilesTouched missing %q, got %v", expected, metadata.FilesTouched)
            }
        }
    }

// Validate checkpoints_count
    if v.CheckpointsCount > 0 && metadata.CheckpointsCount != v.CheckpointsCount {
        env.T.Errorf("CommittedMetadata.CheckpointsCount = %d, want %d", metadata.CheckpointsCount, v.CheckpointsCount)
        env.T.Errorf("Metadata.CheckpointsCount = %d, want %d", metadata.CheckpointsCount, v.CheckpointsCount)
    }
}

Mcmd/entire/cli/integration_test/testenv.go+12/-12

103 unmodified lines

104
105
106
107
107
108
109
110

103 unmodified lines

content, found := env.ReadFileFromBranch(paths.MetadataBranchName, metadataPath)
    require.True(t, found, "Session metadata should exist for checkpoint %s", checkpointID2)

var metadata checkpoint.CommittedMetadata
    var metadata checkpoint.Metadata
    require.NoError(t, json.Unmarshal([]byte(content), &metadata))

t.Logf("Checkpoint 2: checkpoint_transcript_start=%d (commit 1 offset was %d)",

Mcmd/entire/cli/integration_test/transcript_offset_test.go+1/-1

349 unmodified lines

350
351
352
353
354
353
354
355
356
357

349 unmodified lines

}

type checkpointInfoReader interface {
    checkpoint.CommittedReader
    ReadSessionMetadata(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*checkpoint.CommittedMetadata, error)
    checkpoint.PersistentReader
    ReadSessionMetadata(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*checkpoint.Metadata, error)
}

func readCheckpointInfoFromStore(ctx context.Context, store checkpointInfoReader, checkpointID id.CheckpointID) (*strategy.CheckpointInfo, error) {

Mcmd/entire/cli/resume.go+2/-2

530 unmodified lines

531
532
533
534
534
535
536
537
64 unmodified lines

602
603
604
605
605
606
607
608
16 unmodified lines

625
626
627
628
628
629
630
631
4 unmodified lines

636
637
638
639
639
640
641
642
29 unmodified lines

672
673
674
675
675
676
677
678
179 unmodified lines

858
859
860
861
861
862
863
864
60 unmodified lines

925
926
927
928
928
929
930
931
215 unmodified lines

1147
1148
1149
1150
1150
1151
1152
1153

530 unmodified lines

) {
    t.Helper()

if err := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    if err := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    sessionID,
        CreatedAt:    createdAt,
64 unmodified lines

oldID: {Sessions: []checkpoint.SessionFilePaths{{Metadata: "old"}}},
            newID: {Sessions: []checkpoint.SessionFilePaths{{Metadata: "new"}}},
        },
        metadata: map[id.CheckpointID][]checkpoint.CommittedMetadata{
        metadata: map[id.CheckpointID][]checkpoint.Metadata{
            oldID: {{
                SessionID: "old-session",
                CreatedAt: time.Date(2025, 1, 1, 10, 0, 0, 0, time.UTC),
16 unmodified lines

type resumeCheckpointInfoReaderStub struct {
    summaries map[id.CheckpointID]*checkpoint.CheckpointSummary
    metadata  map[id.CheckpointID][]checkpoint.CommittedMetadata
    metadata  map[id.CheckpointID][]checkpoint.Metadata
}

func (r *resumeCheckpointInfoReaderStub) ReadCommitted(_ context.Context, checkpointID id.CheckpointID) (*checkpoint.CheckpointSummary, error) {
4 unmodified lines

return nil, checkpoint.ErrCheckpointNotFound
}

func (r *resumeCheckpointInfoReaderStub) ReadSessionMetadata(_ context.Context, checkpointID id.CheckpointID, sessionIndex int) (*checkpoint.CommittedMetadata, error) {
func (r *resumeCheckpointInfoReaderStub) ReadSessionMetadata(_ context.Context, checkpointID id.CheckpointID, sessionIndex int) (*checkpoint.Metadata, error) {
    sessions := r.metadata[checkpointID]
    if sessionIndex < 0 || sessionIndex >= len(sessions) {
        return nil, checkpoint.ErrCheckpointNotFound
29 unmodified lines

},
    }
    for _, session := range sessions {
        if err := store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
        if err := store.WriteCommitted(ctx, checkpoint.WriteOptions{
            CheckpointID: cpID,
            SessionID:    session.sessionID,
            CreatedAt:    session.createdAt,
179 unmodified lines

raw := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"payload"}]}}` + "\n")

v1Store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    if err := v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    if err := v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "benign-session",
        Strategy:     "manual-commit",
60 unmodified lines

raw := []byte(`{"type":"user","message":{"content":[{"type":"text","text":"resume v1 fallback"}]}}` + "\n")

v1Store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    if err := v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    if err := v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    sessionID,
        Strategy:     "manual-commit",
215 unmodified lines

// Agent must be set so RestoreLogsOnly can resolve a session-write target.
    v1Store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    if err := v1Store.WriteCommitted(ctx, checkpoint.WriteCommittedOptions{
    if err := v1Store.WriteCommitted(ctx, checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "2025-01-01-test-session-uuid",
        Strategy:     "manual-commit",

Mcmd/entire/cli/resume_test.go+8/-8

28 unmodified lines

29
30
31
32
32
33
34
35
237 unmodified lines

273
274
275
276
276
277
278
279
27 unmodified lines

307
308
309
310
310
311
312
313
313
314
315
316
9 unmodified lines

326
327
328
329
329
330
331
332

28 unmodified lines

)

type reviewContextSessionMetadataReader interface {
    ReadSessionMetadata(ctx context.Context, checkpointID checkpointid.CheckpointID, sessionIndex int) (*checkpoint.CommittedMetadata, error)
    ReadSessionMetadata(ctx context.Context, checkpointID checkpointid.CheckpointID, sessionIndex int) (*checkpoint.Metadata, error)
}

type reviewContextSessionMetadataPromptsReader interface {
237 unmodified lines

func reviewCheckpointDetail(
    ctx context.Context,
    reader checkpoint.CommittedReader,
    reader checkpoint.PersistentReader,
    cpID checkpointid.CheckpointID,
    summary *checkpoint.CheckpointSummary,
) string {
27 unmodified lines

func readReviewContextSessionMetadata(
    ctx context.Context,
    reader checkpoint.CommittedReader,
    reader checkpoint.PersistentReader,
    cpID checkpointid.CheckpointID,
    sessionIndex int,
) (*checkpoint.CommittedMetadata, error) {
) (*checkpoint.Metadata, error) {
    if r, ok := reader.(reviewContextSessionMetadataReader); ok {
        return r.ReadSessionMetadata(ctx, cpID, sessionIndex) //nolint:wrapcheck // Best-effort prompt context.
    }
9 unmodified lines

func readReviewContextSessionPrompts(
    ctx context.Context,
    reader checkpoint.CommittedReader,
    reader checkpoint.PersistentReader,
    cpID checkpointid.CheckpointID,
    sessionIndex int,
) (string, error) {

Mcmd/entire/cli/review_context.go+5/-5

120 unmodified lines

121
122
123
124
124
125
126
127
268 unmodified lines

396
397
398
399
399
400
401
402
49 unmodified lines

452
453
454
455
455
456
457
458
23 unmodified lines

482
483
484
485
485
486
487
488

120 unmodified lines

cpID := checkpointid.MustCheckpointID("d1b2c3d4e5f6")
    reader := &countingReviewContextReader{
        metadata: checkpoint.CommittedMetadata{
        metadata: checkpoint.Metadata{
            CheckpointID: cpID,
            SessionID:    "session-1",
        },
268 unmodified lines

t.Fatalf("open repo: %v", err)
    }
    cpID := checkpointid.MustCheckpointID(checkpointID)
    err = checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    err = checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID:     cpID,
        SessionID:        checkpointID,
        Strategy:         "manual-commit",
49 unmodified lines

}

type countingReviewContextReader struct {
    metadata      checkpoint.CommittedMetadata
    metadata      checkpoint.Metadata
    prompts       string
    metadataErr   error
    promptErr     error
23 unmodified lines

context.Context,
    checkpointid.CheckpointID,
    int,
) (*checkpoint.CommittedMetadata, error) {
) (*checkpoint.Metadata, error) {
    r.metadataCalls++
    return &r.metadata, r.metadataErr
}

Mcmd/entire/cli/review_context_test.go+4/-4

1888 unmodified lines

1889
1890
1891
1892
1892
1893
1894
1895

1888 unmodified lines

}
    cpID := id.MustCheckpointID(cpHex)
    store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    if err := store.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    if err := store.WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID:     cpID,
        SessionID:        "status-test-session",
        Strategy:         "manual-commit",

Mcmd/entire/cli/status_test.go+1/-1

498 unmodified lines

499
500
501
502
502
503
504
505

498 unmodified lines

// and lists both IDs in SessionIDs.
    store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    for _, sid := range []string{archivedSessionID, latestSessionID} {
        require.NoError(t, store.WriteCommitted(t.Context(), checkpoint.WriteCommittedOptions{
        require.NoError(t, store.WriteCommitted(t.Context(), checkpoint.WriteOptions{
            CheckpointID: cpID,
            SessionID:    sid,
            Strategy:     "manual-commit",

Mcmd/entire/cli/strategy/clean_test.go+1/-1

315 unmodified lines

316
317
318
319
319
320
321
322
272 unmodified lines

595
596
597
598
598
599
600
601
241 unmodified lines

843
844
845
846
846
847
848
849
58 unmodified lines

908
909
910
911
911
912
913
914

315 unmodified lines

return checkpointInfosFromCommitted(committed), nil
}

func checkpointInfosFromCommitted(committed []checkpoint.CommittedInfo) []CheckpointInfo {
func checkpointInfosFromCommitted(committed []checkpoint.CheckpointInfo) []CheckpointInfo {
    result := make([]CheckpointInfo, 0, len(committed))
    for _, c := range committed {
        result = append(result, CheckpointInfo{
272 unmodified lines

// sessionMetadataLite contains only the fields needed from session-level metadata.json.
// Using a minimal struct avoids allocating large nested objects (Summary, Attribution,
// TokenUsage, etc.) that CommittedMetadata carries but callers never need here.
// TokenUsage, etc.) that Metadata carries but callers never need here.
type sessionMetadataLite struct {
    SessionID string          `json:"session_id"`
    Agent     types.AgentType `json:"agent,omitempty"`
241 unmodified lines

metadataPath := checkpointPath + "/" + paths.MetadataFileName
    if file, err := tree.File(metadataPath); err == nil {
        if content, err := file.Contents(); err == nil {
            var metadata checkpoint.CommittedMetadata
            var metadata checkpoint.Metadata
            if err := json.Unmarshal([]byte(content), &metadata); err == nil && metadata.Agent != "" {
                return metadata.Agent
            }
58 unmodified lines

//
// Falls back through earlier sessions when the latest has no prompt.
// Avoids reading full transcripts — only reads prompt.txt files.
// sessionCount is the number of sessions in the checkpoint (from CommittedInfo.SessionCount).
// sessionCount is the number of sessions in the checkpoint (from CheckpointInfo.SessionCount).
func ReadLatestSessionPromptFromCommittedTree(tree *object.Tree, cpID id.CheckpointID, sessionCount int) string {
    cpPath := cpID.Path()
    cpTree, err := tree.Tree(cpPath)

Mcmd/entire/cli/strategy/common.go+4/-4

51 unmodified lines

52
53
54
55
55
56
57
58

51 unmodified lines

// topology. Writes target refs.Primary; reads target refs.Read. The strategy's
// blob fetcher is wired in so reads can fetch blobs on demand after a treeless
// fetch.
func (s *ManualCommitStrategy) getCheckpointStore(ctx context.Context, repo *git.Repository) (checkpoint.CommittedStore, error) { //nolint:ireturn // committed store capability is the abstraction boundary
func (s *ManualCommitStrategy) getCheckpointStore(ctx context.Context, repo *git.Repository) (checkpoint.PersistentStore, error) { //nolint:ireturn // committed store capability is the abstraction boundary
    stores, err := s.getCheckpointStores(ctx, repo)
    if err != nil {
        return nil, err

Mcmd/entire/cli/strategy/manual_commit.go+1/-1

134 unmodified lines

135
136
137
138
138
139
140
141
113 unmodified lines

255
256
257
258
258
259
260
261

134 unmodified lines

// CondenseSession condenses a session's shadow branch to permanent storage.
// checkpointID is the 12-hex-char value from the Entire-Checkpoint trailer.
// Metadata is stored at sharded path: <checkpoint_id[:2]>/<checkpoint_id[2:]>/
// Uses checkpoint.CommittedStore.WriteCommitted for committed storage.
// Uses checkpoint.PersistentStore.WriteCommitted for committed storage.
//
// For mid-session commits (no Stop/SaveStep called yet), the shadow branch may not exist.
// In this case, data is extracted from the live transcript instead.
113 unmodified lines

// pre-push rewrite path, never here.
    skillEvents := mergeSkillEvents(state.SkillEvents, withSkillEventTurnID(sessionData.SkillEvents, state.TurnID))

writeOpts := cpkg.WriteCommittedOptions{
    writeOpts := cpkg.WriteOptions{
        CheckpointID:                checkpointID,
        SessionID:                   state.SessionID,
        Strategy:                    StrategyNameManualCommit,

Mcmd/entire/cli/strategy/manual_commit_condensation.go+2/-2

457 unmodified lines

458
459
460
461
461
462
463
464
82 unmodified lines

547
548
549
550
550
551
552
553

457 unmodified lines

// when state.Kind is KindAgentInvestigate, condensation propagates the kind
// through to CheckpointSummary.HasInvestigation on the metadata branch and
// writes the per-session investigate fields into the per-session
// CommittedMetadata. Mirrors the (untested) review-tagging path so future
// Metadata. Mirrors the (untested) review-tagging path so future
// regressions in either flow are caught here.
//
// Tests in this file use t.Chdir for CWD-based git resolution, so this
82 unmodified lines

}
    sessionBytes, err := sessionMeta.Contents()
    require.NoError(t, err)
    var meta checkpoint.CommittedMetadata
    var meta checkpoint.Metadata
    require.NoError(t, json.Unmarshal([]byte(sessionBytes), &meta))

require.Equal(t, string(session.KindAgentInvestigate), meta.Kind, "per-session Kind")

Mcmd/entire/cli/strategy/manual_commit_condensation_test.go+2/-2

2819 unmodified lines

2820
2821
2822
2823
2823
2824
2825
2826

2819 unmodified lines

continue
        }

updateOpts := checkpoint.UpdateCommittedOptions{
        updateOpts := checkpoint.UpdateOptions{
            CheckpointID:     cpID,
            SessionID:        state.SessionID,
            Transcript:       redactedTranscript,

Mcmd/entire/cli/strategy/manual_commit_hooks.go+1/-1

133 unmodified lines

134
135
136
137
137
138
139
140

133 unmodified lines

t.Helper()
    store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    cpID := id.MustCheckpointID(cpIDString)
    require.NoError(t, store.WriteCommitted(context.Background(), checkpoint.WriteCommittedOptions{
    require.NoError(t, store.WriteCommitted(context.Background(), checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    sessionID,
        Strategy:     "manual-commit",

Mcmd/entire/cli/strategy/manual_commit_opf_rewrite_test.go+1/-1

859 unmodified lines

860
861
862
863
863
864
865
866

859 unmodified lines

// about each session, including whether local logs have newer timestamps.
// repoRoot is used to compute per-session agent directories.
// Sessions without agent metadata are skipped (cannot determine target directory).
func (s *ManualCommitStrategy) classifySessionsForRestore(ctx context.Context, repoRoot string, store cpkg.CommittedReader, checkpointID id.CheckpointID, summary *cpkg.CheckpointSummary) []SessionRestoreInfo {
func (s *ManualCommitStrategy) classifySessionsForRestore(ctx context.Context, repoRoot string, store cpkg.PersistentReader, checkpointID id.CheckpointID, summary *cpkg.CheckpointSummary) []SessionRestoreInfo {
    var sessions []SessionRestoreInfo

totalSessions := len(summary.Sessions)

Mcmd/entire/cli/strategy/manual_commit_rewind.go+1/-1

473 unmodified lines

474
475
476
477
477
478
479
480
3 unmodified lines

484
485
486
487
487
488
489
490

473 unmodified lines

// Earlier session carries the only usable prompt.
    store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
    require.NoError(t, store.WriteCommitted(t.Context(), checkpoint.WriteCommittedOptions{
    require.NoError(t, store.WriteCommitted(t.Context(), checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-earlier",
        Strategy:     "manual-commit",
3 unmodified lines

AuthorEmail:  "test@test.com",
    }))
    // Latest session has no prompt at all.
    require.NoError(t, store.WriteCommitted(t.Context(), checkpoint.WriteCommittedOptions{
    require.NoError(t, store.WriteCommitted(t.Context(), checkpoint.WriteOptions{
        CheckpointID: cpID,
        SessionID:    "session-latest",
        Strategy:     "manual-commit",

Mcmd/entire/cli/strategy/manual_commit_test.go+2/-2

615 unmodified lines

616
617
618
619
619
620
621
622

615 unmodified lines

) {
    t.Helper()

err := cpkg.NewGitStore(repo, cpkg.DefaultV1Refs()).WriteCommitted(context.Background(), cpkg.WriteCommittedOptions{
    err := cpkg.NewGitStore(repo, cpkg.DefaultV1Refs()).WriteCommitted(context.Background(), cpkg.WriteOptions{
        CheckpointID: checkpointID,
        SessionID:    sessionID,
        CreatedAt:    createdAt,

Mcmd/entire/cli/strategy/rewind_test.go+1/-1