checkpoint: name Write requests by scope (Session / Checkpoint*) · Entire
Log in
checkpoint: name Write requests by scope (Session / Checkpoint*)
72eee65·
Soph·3w ago·60 files·+296 added/-294 removed
Rename the Write request union to noun-based, scope-explicit names — the verb is already Write, and the tier (session vs checkpoint) should be visible in the type: WriteSession -> Session (session-level: write/replace a session) BackfillTranscript -> SessionTranscript (session-level) BackfillSummary -> SessionSummary (session-level) BackfillAttribution -> CheckpointAttribution (checkpoint-level: root combined attribution)
The old BackfillAttribution name hid that it targets the checkpoint root's combined attribution across all sessions, not a single session — CheckpointAttribution makes the one checkpoint-level write explicit alongside the three session-level ones.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
1dc8e6fe2d64View transcript
?\ Review Checkpoint Commit f16b7101Codex·GPT-5.5·1 step
Changes
60
cmd/entire/cli
agent
Magent.go+2/-2
Magent_test.go+3/-3
Mcapabilities_test.go+7/-7
claudecode
Mclaude.go+2/-2
codex
Mcodex.go+2/-2
copilotcli
Mcopilotcli.go+2/-2
Mcopilotcli_test.go+15/-15
cursor
Mcursor.go+2/-2
Mcursor_test.go+15/-15
external
Mcapabilities.go+2/-2
Mdiscovery_test.go+2/-2
Mexternal.go+1/-1
factoryaidroid
Mfactoryaidroid.go+2/-2
Mfactoryaidroid_test.go+13/-13
geminicli
Mgemini.go+2/-2
Mgemini_test.go+10/-10
opencode
Mopencode.go+1/-1
pi
Mpi.go+2/-2
Mtranscript_test.go+2/-2
vogon
Mvogon.go+1/-1
Mattach.go+1/-1
Mattach_test.go+2/-2
Mattribution_test.go+1/-1
benchutil
Mbench_test.go+1/-1
Mbenchutil.go+1/-1
checkpoint
Mbackwards_compat_test.go+1/-1
Mblob_resolver_test.go+1/-1
Mcheckpoint.go+1/-1
Mcheckpoint_test.go+45/-45
Mpersistent_compact_transcript_test.go+7/-7
Mpersistent_opf_trailer_test.go+1/-1
Mpersistent_phantom_paths_test.go+2/-2
Mpersistent_read_store_test.go+1/-1
Mpersistent_reader_test.go+2/-2
Mpersistent_update_test.go+22/-22
Mpersistent_write.go+18/-16
Mpersistent_write_test.go+19/-19
dispatch
Mmode_local_test.go+3/-3
Mexplain.go+1/-1
Mexplain_export_test.go+2/-2
Mexplain_summary_provider_test.go+2/-2
Mexplain_test.go+18/-18
Mhead_checkpoint_flags_test.go+1/-1
integration_test
Magent_test.go+24/-24
Mlifecycle_test.go+1/-1
Mresume.go+2/-2
Mresume_test.go+6/-6
review
Mmanifest_test.go+1/-1
Mreview_context_test.go+1/-1
Mrewind.go+2/-2
Mstatus_test.go+1/-1
strategy
Mclean_test.go+1/-1
Mmanual_commit_condensation.go+2/-2
Mmanual_commit_hooks.go+2/-2
Mmanual_commit_opf_rewrite_test.go+1/-1
Mmanual_commit_rewind.go+2/-2
Mmanual_commit_test.go+2/-2
Mrewind_test.go+4/-4
summarize
Mclaude_test.go+1/-1
Mtext_generator_test.go+2/-2
79 unmodified lines
80
81
82
83
84
83
84
85
86
87
79 unmodified lines
// ReadSession reads session data from agent's storage.
ReadSession(input *HookInput) (*AgentSession, error)
// WriteSession writes session data for resumption.
WriteSession(ctx context.Context, session *AgentSession) error
// Session writes session data for resumption.
Session(ctx context.Context, session *AgentSession) error
// FormatResumeCommand returns command to resume a session.
FormatResumeCommand(sessionID string) string
Mcmd/entire/cli/agent/agent.go+2/-2
41 unmodified lines
42
43
44
45
46
47
45
46
47
48
49
50
41 unmodified lines
}
//nolint:nilnil // Mock implementation
func (m *mockAgent) ReadSession(_ *HookInput) (*AgentSession, error) { return nil, nil }
func (m *mockAgent) WriteSession(_ context.Context, _ *AgentSession) error { return nil }
func (m *mockAgent) FormatResumeCommand(_ string) string { return "" }
func (m *mockAgent) ReadSession(_ *HookInput) (*AgentSession, error) { return nil, nil }
func (m *mockAgent) Session(_ context.Context, _ *AgentSession) error { return nil }
func (m *mockAgent) FormatResumeCommand(_ string) string { return "" }
// mockHookSupport implements both Agent and HookSupport interfaces.
type mockHookSupport struct {
Mcmd/entire/cli/agent/agent_test.go+3/-3
22 unmodified lines
23
24
25
26
27
28
29
30
31
32
26
27
28
29
30
31
32
33
34
35
22 unmodified lines
func (m *mockBaseAgent) ChunkTranscript(context.Context, []byte, int) ([][]byte, error) {
return nil, nil
}
func (m *mockBaseAgent) ReassembleTranscript([][]byte) ([]byte, error) { return nil, nil }
func (m *mockBaseAgent) GetSessionID(*HookInput) string { return "" }
func (m *mockBaseAgent) GetSessionDir(string) (string, error) { return "", nil }
func (m *mockBaseAgent) ResolveSessionFile(string, string) string { return "" }
func (m *mockBaseAgent) ReadSession(*HookInput) (*AgentSession, error) { return nil, nil } //nolint:nilnil // test mock
func (m *mockBaseAgent) WriteSession(context.Context, *AgentSession) error { return nil }
func (m *mockBaseAgent) FormatResumeCommand(string) string { return "" }
func (m *mockBaseAgent) ReassembleTranscript([][]byte) ([]byte, error) { return nil, nil }
func (m *mockBaseAgent) GetSessionID(*HookInput) string { return "" }
func (m *mockBaseAgent) GetSessionDir(string) (string, error) { return "", nil }
func (m *mockBaseAgent) ResolveSessionFile(string, string) string { return "" }
func (m *mockBaseAgent) ReadSession(*HookInput) (*AgentSession, error) { return nil, nil } //nolint:nilnil // test mock
func (m *mockBaseAgent) Session(context.Context, *AgentSession) error { return nil }
func (m *mockBaseAgent) FormatResumeCommand(string) string { return "" }
// mockBuiltinHookAgent is a built-in agent that implements HookSupport but NOT CapabilityDeclarer.
type mockBuiltinHookAgent struct {
Mcmd/entire/cli/agent/capabilities_test.go+7/-7
147 unmodified lines
148
149
150
151
151
152
153
154
154
155
156
157
147 unmodified lines
}, nil
}
// WriteSession writes a session to Claude's storage (JSONL transcript file).
// Session writes a session to Claude's storage (JSONL transcript file).
// Uses the NativeData field which contains raw JSONL bytes.
// The session must have been created by Claude Code (AgentName check).
func (c *ClaudeCodeAgent) WriteSession(_ context.Context, session *agent.AgentSession) error {
func (c *ClaudeCodeAgent) Session(_ context.Context, session *agent.AgentSession) error {
if session == nil {
return errors.New("session is nil")
}
Mcmd/entire/cli/agent/claudecode/claude.go+2/-2
156 unmodified lines
157
158
159
160
161
160
161
162
163
164
156 unmodified lines
}, nil
}
// WriteSession writes a session to Codex's storage (JSONL rollout file).
func (c *CodexAgent) WriteSession(_ context.Context, session *agent.AgentSession) error {
// Session writes a session to Codex's storage (JSONL rollout file).
func (c *CodexAgent) Session(_ context.Context, session *agent.AgentSession) error {
if session == nil {
return errors.New("session is nil")
}
Mcmd/entire/cli/agent/codex/codex.go+2/-2
114 unmodified lines
115
116
117
118
119
118
119
120
121
122
114 unmodified lines
}, nil
}
// WriteSession writes a session to Copilot CLI's storage (JSONL transcript file).
func (c *CopilotCLIAgent) WriteSession(_ context.Context, session *agent.AgentSession) error {
// Session writes a session to Copilot CLI's storage (JSONL transcript file).
func (c *CopilotCLIAgent) Session(_ context.Context, session *agent.AgentSession) error {
if session == nil {
return errors.New("session is nil")
}
Mcmd/entire/cli/agent/copilotcli/copilotcli.go+2/-2
228 unmodified lines
229
230
231
232
232
233
234
235
10 unmodified lines
246
247
248
249
250
249
250
251
252
253
25 unmodified lines
279
280
281
282
283
282
283
284
285
286
13 unmodified lines
300
301
302
303
304
303
304
305
306
307
5 unmodified lines
313
314
315
316
317
316
317
318
319
320
8 unmodified lines
329
330
331
332
333
332
333
334
335
336
4 unmodified lines
341
342
343
344
345
344
345
346
347
348
4 unmodified lines
353
354
355
356
357
356
357
358
359
360
228 unmodified lines
}
}
// --- WriteSession ---
// --- Session ---
func TestWriteSession_Success(t *testing.T) {
t.Parallel()
10 unmodified lines
NativeData: []byte(content),
}
if err := ag.WriteSession(context.Background(), session); err != nil {
t.Fatalf("WriteSession() error = %v", err)
if err := ag.Session(context.Background(), session); err != nil {
t.Fatalf("Session() error = %v", err)
}
data, err := os.ReadFile(transcriptPath)
25 unmodified lines
// Write to new path
newPath := filepath.Join(tmpDir, "roundtrip.jsonl")
session.SessionRef = newPath
if err := ag.WriteSession(context.Background(), session); err != nil {
t.Fatalf("WriteSession() error = %v", err)
if err := ag.Session(context.Background(), session); err != nil {
t.Fatalf("Session() error = %v", err)
}
// Read back and compare
13 unmodified lines
func TestWriteSession_Nil(t *testing.T) {
t.Parallel()
ag := &CopilotCLIAgent{}
if err := ag.WriteSession(context.Background(), nil); err == nil {
t.Error("WriteSession(nil) should error")
if err := ag.Session(context.Background(), nil); err == nil {
t.Error("Session(nil) should error")
}
}
5 unmodified lines
SessionRef: "/path/to/file",
NativeData: []byte("data"),
}
if err := ag.WriteSession(context.Background(), session); err == nil {
t.Error("WriteSession() should error for wrong agent")
if err := ag.Session(context.Background(), session); err == nil {
t.Error("Session() should error for wrong agent")
}
}
8 unmodified lines
SessionRef: transcriptPath,
NativeData: []byte("data"),
}
if err := ag.WriteSession(context.Background(), session); err != nil {
t.Errorf("WriteSession() with empty AgentName should succeed, got: %v", err)
if err := ag.Session(context.Background(), session); err != nil {
t.Errorf("Session() with empty AgentName should succeed, got: %v", err)
}
}
4 unmodified lines
AgentName: agent.AgentNameCopilotCLI,
NativeData: []byte("data"),
}
if err := ag.WriteSession(context.Background(), session); err == nil {
t.Error("WriteSession() should error when SessionRef is empty")
if err := ag.Session(context.Background(), session); err == nil {
t.Error("Session() should error when SessionRef is empty")
}
}
4 unmodified lines
AgentName: agent.AgentNameCopilotCLI,
SessionRef: "/path/to/file",
}
if err := ag.WriteSession(context.Background(), session); err == nil {
t.Error("WriteSession() should error when NativeData is empty")
if err := ag.Session(context.Background(), session); err == nil {
t.Error("Session() should error when NativeData is empty")
}
}
Mcmd/entire/cli/agent/copilotcli/copilotcli_test.go+15/-15
201 unmodified lines
202
203
204
205
206
205
206
207
208
209
201 unmodified lines
return nil
}
// WriteSession writes a session to Cursor's storage (JSONL transcript file).
func (c *CursorAgent) WriteSession(_ context.Context, session *agent.AgentSession) error {
// Session writes a session to Cursor's storage (JSONL transcript file).
func (c *CursorAgent) Session(_ context.Context, session *agent.AgentSession) error {
if session == nil {
return errors.New("session is nil")
}
Mcmd/entire/cli/agent/cursor/cursor.go+2/-2
334 unmodified lines
335
336
337
338
338
339
340
341
10 unmodified lines
352
353
354
355
356
355
356
357
358
359
25 unmodified lines
385
386
387
388
389
388
389
390
391
392
13 unmodified lines
406
407
408
409
410
409
410
411
412
413
5 unmodified lines
419
420
421
422
423
422
423
424
425
426
8 unmodified lines
435
436
437
438
439
438
439
440
441
442
4 unmodified lines
447
448
449
450
451
450
451
452
453
454
4 unmodified lines
459
460
461
462
463
462
463
464
465
466
334 unmodified lines
}
}
// --- WriteSession ---
// --- Session ---
func TestWriteSession_Success(t *testing.T) {
t.Parallel()
10 unmodified lines
NativeData: []byte(content),
}
data, err := os.ReadFile(transcriptPath)
25 unmodified lines
// Read back and compare
13 unmodified lines
func TestWriteSession_Nil(t *testing.T) {
t.Parallel()
ag := &CursorAgent{}
if err := ag.WriteSession(context.Background(), nil); err == nil {
t.Error("WriteSession(nil) should error")
if err := ag.Session(context.Background(), nil); err == nil {
t.Error("Session(nil) should error")
}
}
5 unmodified lines
8 unmodified lines
4 unmodified lines
AgentName: agent.AgentNameCursor,
NativeData: []byte("data"),
}
if err := ag.WriteSession(context.Background(), session); err == nil {
t.Error("WriteSession() should error when SessionRef is empty")
if err := ag.Session(context.Background(), session); err == nil {
t.Error("Session() should error when SessionRef is empty")
}
}
4 unmodified lines
AgentName: agent.AgentNameCursor,
SessionRef: "/path/to/file",
}
if err := ag.WriteSession(context.Background(), session); err == nil {
t.Error("WriteSession() should error when NativeData is empty")
if err := ag.Session(context.Background(), session); err == nil {
t.Error("Session() should error when NativeData is empty")
}
}
Mcmd/entire/cli/agent/cursor/cursor_test.go+15/-15
71 unmodified lines
72
73
74
75
76
75
76
77
78
79
71 unmodified lines
func (w *wrappedAgent) ReadSession(input *agent.HookInput) (*agent.AgentSession, error) {
return w.ea.ReadSession(input)
}
func (w *wrappedAgent) WriteSession(ctx context.Context, s *agent.AgentSession) error {
return w.ea.WriteSession(ctx, s)
func (w *wrappedAgent) Session(ctx context.Context, s *agent.AgentSession) error {
return w.ea.Session(ctx, s)
}
func (w *wrappedAgent) FormatResumeCommand(id string) string { return w.ea.FormatResumeCommand(id) }
Mcmd/entire/cli/agent/external/capabilities.go+2/-2
350 unmodified lines
351
352
353
354
355
354
355
356
357
358
350 unmodified lines
func (f *fakeBuiltInAgent) ReadSession(*agent.HookInput) (*agent.AgentSession, error) {
return nil, nil //nolint:nilnil // test fake — no session is a valid state
}
func (f *fakeBuiltInAgent) WriteSession(context.Context, *agent.AgentSession) error { return nil }
func (f *fakeBuiltInAgent) FormatResumeCommand(string) string { return "" }
func (f *fakeBuiltInAgent) Session(context.Context, *agent.AgentSession) error { return nil }
func (f *fakeBuiltInAgent) FormatResumeCommand(string) string { return "" }
func TestDiscoverAndRegister_SkipsInfoFailure(t *testing.T) {
if _, err := exec.LookPath("sh"); err != nil {
Mcmd/entire/cli/agent/external/discovery_test.go+2/-2
199 unmodified lines
200
201
202
203
203
204
205
206
199 unmodified lines
return unmarshalAgentSession(&resp)
}
func (e *Agent) WriteSession(ctx context.Context, session *agent.AgentSession) error {
func (e *Agent) Session(ctx context.Context, session *agent.AgentSession) error {
data, err := marshalAgentSession(session)
if err != nil {
return fmt.Errorf("write-session: marshal: %w", err)
Mcmd/entire/cli/agent/external/external.go+1/-1
150 unmodified lines
151
152
153
154
154
155
156
156
157
158
159
150 unmodified lines
}, nil
}
// WriteSession writes a session to Factory AI Droid's storage (JSONL transcript file).
// Session writes a session to Factory AI Droid's storage (JSONL transcript file).
// Uses the NativeData field which contains raw JSONL bytes.
func (f *FactoryAIDroidAgent) WriteSession(_ context.Context, session *agent.AgentSession) error {
func (f *FactoryAIDroidAgent) Session(_ context.Context, session *agent.AgentSession) error {
if session == nil {
return errors.New("session is nil")
}
Mcmd/entire/cli/agent/factoryaidroid/factoryaidroid.go+2/-2
153 unmodified lines
154
155
156
157
157
158
159
160
64 unmodified lines
225
226
227
228
228
229
230
231
232
233
234
235
235
236
237
238
9 unmodified lines
248
249
250
251
252
251
252
253
254
255
256
257
258
259
259
260
261
262
263
264
265
265
266
267
268
269
270
271
272
272
273
274
275
276
277
277
278
279
280
281
282
283
284
284
285
286
287
288
289
289
290
291
292
23 unmodified lines
316
317
318
319
320
319
320
321
322
323
153 unmodified lines
}
}
// --- ReadSession / WriteSession tests ---
// --- ReadSession / Session tests ---
func TestReadSession(t *testing.T) {
t.Parallel()
64 unmodified lines
nativeData := []byte(`{"type":"message","id":"msg1","message":{"role":"user","content":"hello"}}`)
ag := &FactoryAIDroidAgent{}
err := ag.WriteSession(context.Background(), &agent.AgentSession{
err := ag.Session(context.Background(), &agent.AgentSession{
SessionID: "test-session-456",
AgentName: agent.AgentNameFactoryAIDroid,
SessionRef: transcriptPath,
NativeData: nativeData,
})
if err != nil {
t.Fatalf("WriteSession() error = %v", err)
t.Fatalf("Session() error = %v", err)
}
// Verify file was written correctly
9 unmodified lines
func TestWriteSession_NilSession(t *testing.T) {
t.Parallel()
ag := &FactoryAIDroidAgent{}
if err := ag.WriteSession(context.Background(), nil); err == nil {
t.Error("WriteSession(nil) should error")
if err := ag.Session(context.Background(), nil); err == nil {
t.Error("Session(nil) should error")
}
}
func TestWriteSession_WrongAgent(t *testing.T) {
t.Parallel()
ag := &FactoryAIDroidAgent{}
err := ag.WriteSession(context.Background(), &agent.AgentSession{
err := ag.Session(context.Background(), &agent.AgentSession{
AgentName: "claude-code",
SessionRef: "/tmp/test.jsonl",
NativeData: []byte("data"),
})
if err == nil {
t.Error("WriteSession() should error for wrong agent name")
t.Error("Session() should error for wrong agent name")
}
}
func TestWriteSession_EmptyRef(t *testing.T) {
t.Parallel()
ag := &FactoryAIDroidAgent{}
err := ag.WriteSession(context.Background(), &agent.AgentSession{
err := ag.Session(context.Background(), &agent.AgentSession{
AgentName: agent.AgentNameFactoryAIDroid,
NativeData: []byte("data"),
})
if err == nil {
t.Error("WriteSession() should error on empty SessionRef")
t.Error("Session() should error on empty SessionRef")
}
}
func TestWriteSession_EmptyNativeData(t *testing.T) {
t.Parallel()
ag := &FactoryAIDroidAgent{}
err := ag.WriteSession(context.Background(), &agent.AgentSession{
err := ag.Session(context.Background(), &agent.AgentSession{
AgentName: agent.AgentNameFactoryAIDroid,
SessionRef: "/tmp/test.jsonl",
})
if err == nil {
t.Error("WriteSession() should error on empty NativeData")
t.Error("Session() should error on empty NativeData")
}
}
23 unmodified lines
// Write to new location
session.SessionRef = restoredPath
if err := ag.WriteSession(context.Background(), session); err != nil {
t.Fatalf("WriteSession() error = %v", err)
if err := ag.Session(context.Background(), session); err != nil {
t.Fatalf("Session() error = %v", err)
}
// Verify content matches
Mcmd/entire/cli/agent/factoryaidroid/factoryaidroid_test.go+13/-13
166 unmodified lines
167
168
169
170
170
171
172
172
173
174
175
166 unmodified lines
}, nil
}
// WriteSession writes a session to Gemini's storage (JSON transcript file).
// Session writes a session to Gemini's storage (JSON transcript file).
// Uses the NativeData field which contains raw JSON bytes.
func (g *GeminiCLIAgent) WriteSession(_ context.Context, session *agent.AgentSession) error {
func (g *GeminiCLIAgent) Session(_ context.Context, session *agent.AgentSession) error {
if session == nil {
return errors.New("session is nil")
}
Mcmd/entire/cli/agent/geminicli/gemini.go+2/-2
264 unmodified lines
265
266
267
268
268
269
270
270
271
272
273
12 unmodified lines
286
287
288
289
289
290
291
291
292
293
294
7 unmodified lines
302
303
304
305
305
306
307
307
308
309
310
6 unmodified lines
317
318
319
320
320
321
322
322
323
324
325
6 unmodified lines
332
333
334
335
335
336
337
337
338
339
340
264 unmodified lines
NativeData: []byte(`{"messages": []}`),
}
err := ag.WriteSession(context.Background(), session)
err := ag.Session(context.Background(), session)
if err != nil {
t.Fatalf("WriteSession() error = %v", err)
t.Fatalf("Session() error = %v", err)
}
// Verify file was written
12 unmodified lines
ag := &GeminiCLIAgent{}
err := ag.WriteSession(context.Background(), nil)
err := ag.Session(context.Background(), nil)
if err == nil {
t.Error("WriteSession(nil) should error")
t.Error("Session(nil) should error")
}
}
7 unmodified lines
NativeData: []byte("{}"),
}
err := ag.WriteSession(context.Background(), session)
err := ag.Session(context.Background(), session)
if err == nil {
t.Error("WriteSession() should error for wrong agent")
t.Error("Session() should error for wrong agent")
}
}
6 unmodified lines
NativeData: []byte("{}"),
}
err := ag.WriteSession(context.Background(), session)
err := ag.Session(context.Background(), session)
if err == nil {
t.Error("WriteSession() should error when SessionRef is empty")
t.Error("Session() should error when SessionRef is empty")
}
}
6 unmodified lines
SessionRef: "/path/to/file",
}
err := ag.WriteSession(context.Background(), session)
err := ag.Session(context.Background(), session)
if err == nil {
t.Error("WriteSession() should error when NativeData is empty")
t.Error("Session() should error when NativeData is empty")
}
}
Mcmd/entire/cli/agent/geminicli/gemini_test.go+10/-10
212 unmodified lines
213
214
215
216
216
217
218
219
212 unmodified lines
}, nil
}
func (a *OpenCodeAgent) WriteSession(ctx context.Context, session *agent.AgentSession) error {
func (a *OpenCodeAgent) Session(ctx context.Context, session *agent.AgentSession) error {
if session == nil {
return errors.New("nil session")
}
Mcmd/entire/cli/agent/opencode/opencode.go+1/-1
248 unmodified lines
249
250
251
252
252
253
254
255
255
256
257
258
248 unmodified lines
}, nil
}
// WriteSession writes a captured Pi transcript back to disk so Pi can resume
// Session writes a captured Pi transcript back to disk so Pi can resume
// from it. Pi loads sessions from arbitrary paths via `pi --session <path>`,
// so a plain write is sufficient.
func (a *PiAgent) WriteSession(_ context.Context, session *agent.AgentSession) error {
func (a *PiAgent) Session(_ context.Context, session *agent.AgentSession) error {
if session == nil {
return errors.New("nil session")
}
Mcmd/entire/cli/agent/pi/pi.go+2/-2
312 unmodified lines
313
314
315
316
316
317
318
319
21 unmodified lines
341
342
343
344
344
345
346
347
312 unmodified lines
}
}
// --- ReadSession / WriteSession ---
// --- ReadSession / Session ---
func TestReadSession(t *testing.T) {
t.Parallel()
21 unmodified lines
dir := t.TempDir()
path := filepath.Join(dir, "subdir", "session.json")
body := []byte(`{"type":"session","version":3}` + "\n")
err := (&PiAgent{}).WriteSession(context.Background(), &agent.AgentSession{
err := (&PiAgent{}).Session(context.Background(), &agent.AgentSession{
SessionID: "abc",
SessionRef: path,
NativeData: body,
Mcmd/entire/cli/agent/pi/transcript_test.go+2/-2
111 unmodified lines
112
113
114
115
115
116
117
118
111 unmodified lines
}, nil
}
func (v *Agent) WriteSession(_ context.Context, session *agent.AgentSession) error {
func (v *Agent) Session(_ context.Context, session *agent.AgentSession) error {
if session == nil {
return errors.New("session is nil")
}
Mcmd/entire/cli/agent/vogon/vogon.go+1/-1
336 unmodified lines
337
338
339
340
340
341
342
343
336 unmodified lines
writeOpts.HasReview = true
}
if err := store.Write(ctx, cpkg.WriteSession(writeOpts)); err != nil {
if err := store.Write(ctx, cpkg.Session(writeOpts)); err != nil {
return fmt.Errorf("failed to write checkpoint: %w", err)
}
Mcmd/entire/cli/attach.go+1/-1
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.Write(context.Background(), cpkg.WriteSession{
if writeErr := store.Write(context.Background(), cpkg.Session{
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.Write(context.Background(), cpkg.WriteSession{
if err := store.Write(context.Background(), cpkg.Session{
CheckpointID: checkpointID,
SessionID: sessionID,
Strategy: strategy.StrategyNameManualCommit,
Mcmd/entire/cli/attach_test.go+2/-2
544 unmodified lines
545
546
547
548
548
549
550
551
544 unmodified lines
if opts.SessionID == "" {
opts.SessionID = checkpointID
}
require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(context.Background(), checkpoint.WriteSession(opts)))
require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(context.Background(), checkpoint.Session(opts)))
// WriteCommitted uses git plumbing only, but keep the worktree file system
// anchored for git CLI blame in these tests.
Mcmd/entire/cli/attribution_test.go+1/-1
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.Write(ctx, checkpoint.WriteSession{
err = repo.Store.Write(ctx, checkpoint.Session{
CheckpointID: cpID,
SessionID: fmt.Sprintf("bench-session-%d", i),
Strategy: "manual-commit",
Mcmd/entire/cli/benchutil/bench_test.go+1/-1
401 unmodified lines
402
403
404
405
405
406
407
408
401 unmodified lines
files = append(files, fmt.Sprintf("src/file_%03d.go", (i*5+j)%100))
}
err = br.Store.Write(context.Background(), checkpoint.WriteSession{
err = br.Store.Write(context.Background(), checkpoint.Session{
CheckpointID: cpID,
SessionID: sessionID,
Strategy: br.Strategy,
Mcmd/entire/cli/benchutil/benchutil.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.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-002",
Strategy: "manual-commit",
Mcmd/entire/cli/checkpoint/blob_resolver_test.go+1/-1
271 unmodified lines
272
273
274
275
275
276
277
278
271 unmodified lines
// CombinedAttribution is holistic attribution across all sessions.
// Used during migration to preserve v1 root summary attribution.
// During normal condensation this is nil (computed post-commit via a BackfillAttribution write).
// During normal condensation this is nil (computed post-commit via a CheckpointAttribution write).
CombinedAttribution *Attribution
// Summary is an optional AI-generated summary for this checkpoint.
Mcmd/entire/cli/checkpoint/checkpoint.go+1/-1
141 unmodified lines
142
143
144
145
145
146
147
148
409 unmodified lines
558
559
560
561
561
562
563
564
126 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
25 unmodified lines
788
789
790
791
791
792
793
794
41 unmodified lines
836
837
838
839
839
840
841
842
34 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
55 unmodified lines
1552
1553
1554
1555
1555
1556
1557
1558
42 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
123 unmodified lines
3621
3622
3623
3624
3624
3625
3626
3627
105 unmodified lines
3733
3734
3735
3736
3736
3737
3738
3739
211 unmodified lines
3951
3952
3953
3954
3954
3955
3956
3957
36 unmodified lines
3994
3995
3996
3997
3997
3998
3999
4000
7 unmodified lines
4008
4009
4010
4011
4011
4012
4013
4014
31 unmodified lines
4046
4047
4048
4049
4049
4050
4051
4052
826 unmodified lines
4879
4880
4881
4882
4882
4883
4884
4885
16 unmodified lines
4902
4903
4904
4905
4905
4906
4907
4908
22 unmodified lines
4931
4932
4933
4934
4934
4935
4936
4937
141 unmodified lines
sessionID := "test-session-123"
agentType := agent.AgentTypeClaudeCode
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: sessionID,
Strategy: "manual-commit",
409 unmodified lines
}
cpID := id.MustCheckpointID("abcdef123456")
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "test-session-id",
Strategy: "manual-commit",
126 unmodified lines
// Write a committed checkpoint with branch information
checkpointID := id.MustCheckpointID("a1b2c3d4e5f6")
store := NewGitStore(repo, DefaultV1Refs())
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "test-session-summary",
Strategy: "manual-commit",
25 unmodified lines
OpenItems: []string{"Open item 1"},
}
err = store.Write(context.Background(), BackfillSummary{CheckpointID: checkpointID, Summary: summary})
err = store.Write(context.Background(), SessionSummary{CheckpointID: checkpointID, Summary: summary})
if err != nil {
t.Fatalf("UpdateSummary() error = %v", err)
}
41 unmodified lines
checkpointID := id.MustCheckpointID("000000000000")
summary := &Summary{Intent: "Test", Outcome: "Test"}
err = store.Write(context.Background(), BackfillSummary{CheckpointID: checkpointID, Summary: summary})
err = store.Write(context.Background(), SessionSummary{CheckpointID: checkpointID, Summary: summary})
if err == nil {
t.Error("UpdateSummary() should return error for non-existent checkpoint")
}
34 unmodified lines
// Create entire/checkpoints/v1 branch on the remote with a checkpoint
remoteStore := NewGitStore(remoteRepo, DefaultV1Refs())
cpID := id.MustCheckpointID("abcdef123456")
err = remoteStore.Write(context.Background(), WriteSession{
err = remoteStore.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "test-session-id",
Strategy: "manual-commit",
62 unmodified lines
authorName := "Alice Developer"
authorEmail := "alice@example.com"
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "test-session-author",
Strategy: "manual-commit",
78 unmodified lines
checkpointID := id.MustCheckpointID("a1a2a3a4a5a6")
// Write first session
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-one",
Strategy: "manual-commit",
9 unmodified lines
}
// Write second session to the same checkpoint ID
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-two",
Strategy: "manual-commit",
58 unmodified lines
checkpointID := id.MustCheckpointID("b1b2b3b4b5b6")
// Write first session with specific stats
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-one",
Strategy: "manual-commit",
13 unmodified lines
}
// Write second session with overlapping and new files
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: sessionID,
Strategy: "manual-commit",
62 unmodified lines
}
for _, s := range sessions {
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: s.id,
Strategy: "manual-commit",
44 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
checkpointID := id.MustCheckpointID(cpIDStr)
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "codex-session",
Strategy: "manual-commit",
43 unmodified lines
// Write three sessions
for i := range 3 {
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: sid,
Strategy: "manual-commit",
55 unmodified lines
checkpointID := id.MustCheckpointID("313233343536")
// Write session without prompts
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "no-prompts-session",
Strategy: "manual-commit",
42 unmodified lines
Outcome: "Bug was fixed",
}
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "summary-session",
Strategy: "manual-commit",
32 unmodified lines
// Write three sessions
for i := range 3 {
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-X",
Strategy: "manual-commit",
13 unmodified lines
}
// Write session "Y"
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-Y",
Strategy: "manual-commit",
13 unmodified lines
}
// Write session "X" again with updated data (should replace, not append)
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-X",
Strategy: "manual-commit",
88 unmodified lines
checkpointID := id.MustCheckpointID("dedb07654321")
// Write session "X" with initial data
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-X",
Strategy: "manual-commit",
8 unmodified lines
}
// Write session "X" again with updated data
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-X",
Strategy: "manual-commit",
54 unmodified lines
checkpointID := id.MustCheckpointID("dedc0abcdef1")
// Write session A at index 0
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-A",
Strategy: "manual-commit",
7 unmodified lines
}
// Write session B at index 1
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-A",
Strategy: "manual-commit",
49 unmodified lines
checkpointID := id.MustCheckpointID("dedd0abcdef2")
// Write session A with prompts and context
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-A",
Strategy: "manual-commit",
8 unmodified lines
}
// Write session B with prompts
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-B",
Strategy: "manual-commit",
8 unmodified lines
}
// Overwrite session A WITHOUT prompts
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "session-A",
Strategy: "manual-commit",
47 unmodified lines
t.Fatalf("redact.JSONLBytes() error = %v", err)
}
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "redact-transcript-session",
Strategy: "manual-commit",
24 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
checkpointID := id.MustCheckpointID("aabbccddeef2")
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "redact-prompt-session",
Strategy: "manual-commit",
123 unmodified lines
checkpointID := id.MustCheckpointID("b1c2d3e4f5a6")
sessionID := "test-session-version"
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: sessionID,
Strategy: "manual-commit",
105 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
checkpointID := id.MustCheckpointID("c1d2e3f4a5b6")
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "test-session-model",
Strategy: "manual-commit",
211 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
checkpointID := id.MustCheckpointID("aabbccddeef7")
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "update-summary-session",
Strategy: "manual-commit",
7 unmodified lines
}
// Now update the summary with a secret
err = store.Write(context.Background(), BackfillSummary{CheckpointID: checkpointID, Summary: &Summary{
err = store.Write(context.Background(), SessionSummary{CheckpointID: checkpointID, Summary: &Summary{
Intent: "Rotated key " + highEntropySecret,
Outcome: "Done",
}})
31 unmodified lines
t.Fatalf("failed to write transcript: %v", err)
}
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "jsonl-fallback-session",
Strategy: "manual-commit",
826 unmodified lines
checkpointID := id.MustCheckpointID("aabbccddeeff")
// First session: investigate session, sets HasInvestigation=true.
if err := store.Write(context.Background(), WriteSession{
if err := store.Write(context.Background(), Session{
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.Write(context.Background(), WriteSession{
if err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "ordinary-session-2",
Strategy: "manual-commit",
22 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
checkpointID := id.MustCheckpointID("11223344aabb")
if err := store.Write(context.Background(), WriteSession{
if err := store.Write(context.Background(), Session{
CheckpointID: checkpointID,
SessionID: "investigate-roundtrip",
Strategy: "manual-commit",
Mcmd/entire/cli/checkpoint/checkpoint_test.go+45/-45
47 unmodified lines
48
49
50
51
51
52
53
54
47 unmodified lines
102
103
104
105
105
106
107
108
25 unmodified lines
134
135
136
137
137
138
139
140
50 unmodified lines
191
192
193
194
194
195
196
197
20 unmodified lines
218
219
220
221
221
222
223
224
21 unmodified lines
246
247
248
249
249
250
251
252
9 unmodified lines
262
263
264
265
265
266
267
268
47 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
cpID := id.MustCheckpointID("a1b2c3d4e5f6")
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
47 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
cpID := id.MustCheckpointID("b2c3d4e5f6a1")
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
25 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
cpID := id.MustCheckpointID("c3d4e5f6a1b2")
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
50 unmodified lines
// Initial write sanitizes before compaction. With start=2 the dropped
// compaction line shifts the window so only "gamma" survives.
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
20 unmodified lines
// Finalize with the same raw transcript. replaceTranscript must sanitize
// before compaction; otherwise the raw slice at line 2 would reintroduce
// "beta".
err = store.Write(context.Background(), BackfillTranscript{
err = store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: redact.AlreadyRedacted(raw),
21 unmodified lines
cpID := id.MustCheckpointID("d4e5f6a1b2c3")
initial := claudeStyleTranscript()
err := store.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
9 unmodified lines
extended := append([]byte{}, initial...)
extended = append(extended,
[]byte(`{"type":"user","uuid":"u3","timestamp":"2026-01-01T00:00:04Z","message":{"role":"user","content":"hello three"}}`+"\n")...)
err = store.Write(context.Background(), BackfillTranscript{
err = store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: redact.AlreadyRedacted(extended),
Mcmd/entire/cli/checkpoint/persistent_compact_transcript_test.go+7/-7
45 unmodified lines
46
47
48
49
49
50
51
52
45 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
cpID := id.MustCheckpointID("a1b2c3d4e5f6")
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "regression-no-opf-trailer",
Strategy: "manual-commit",
Mcmd/entire/cli/checkpoint/persistent_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.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-no-transcript",
Strategy: "manual-commit",
39 unmodified lines
cpID := id.MustCheckpointID("e5f6a1b2c3d4")
// Write a checkpoint WITH a transcript
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-with-transcript",
Strategy: "manual-commit",
Mcmd/entire/cli/checkpoint/persistent_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.Write(context.Background(), WriteSession{
require.NoError(t, store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session",
Strategy: "manual-commit",
Mcmd/entire/cli/checkpoint/persistent_read_store_test.go+1/-1
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.Write(ctx, WriteSession{
require.NoError(t, store.Write(ctx, Session{
CheckpointID: cpID,
SessionID: "session-a",
Strategy: "manual-commit",
1 unmodified line
AuthorName: "Test",
AuthorEmail: "test@example.com",
}))
require.NoError(t, store.Write(ctx, WriteSession{
require.NoError(t, store.Write(ctx, Session{
CheckpointID: cpID,
SessionID: "session-b",
Strategy: "manual-commit",
Mcmd/entire/cli/checkpoint/persistent_reader_test.go+2/-2
51 unmodified lines
52
53
54
55
55
56
57
58
61 unmodified lines
120
121
122
123
123
124
125
126
17 unmodified lines
144
145
146
147
147
148
149
150
18 unmodified lines
169
170
171
172
172
173
174
175
20 unmodified lines
196
197
198
199
199
200
201
202
14 unmodified lines
217
218
219
220
220
221
222
223
22 unmodified lines
246
247
248
249
249
250
251
252
10 unmodified lines
263
264
265
266
266
267
268
269
21 unmodified lines
291
292
293
294
294
295
296
297
36 unmodified lines
334
335
336
337
337
338
339
340
8 unmodified lines
349
350
351
352
352
353
354
355
22 unmodified lines
378
379
380
381
381
382
383
384
48 unmodified lines
433
434
435
436
436
437
438
439
15 unmodified lines
455
456
457
458
458
459
460
461
15 unmodified lines
477
478
479
480
480
481
482
483
151 unmodified lines
635
636
637
638
638
639
640
641
6 unmodified lines
648
649
650
651
651
652
653
654
100 unmodified lines
755
756
757
758
758
759
760
761
21 unmodified lines
783
784
785
786
786
787
788
789
5 unmodified lines
795
796
797
798
798
799
800
801
30 unmodified lines
832
833
834
835
835
836
837
838
2 unmodified lines
841
842
843
844
844
845
846
847
51 unmodified lines
store := NewGitStore(repo, DefaultV1Refs())
cpID := id.MustCheckpointID("a1b2c3d4e5f6")
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
61 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.Write(context.Background(), BackfillTranscript{
err := store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: redact.AlreadyRedacted(fullTranscript),
17 unmodified lines
t.Parallel()
_, store, cpID := setupRepoForUpdate(t)
err := store.Write(context.Background(), BackfillTranscript{
err := store.Write(context.Background(), SessionTranscript{
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.Write(context.Background(), BackfillTranscript{
err := store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: redact.AlreadyRedacted(fullTranscript),
20 unmodified lines
t.Parallel()
_, store, _ := setupRepoForUpdate(t)
err := store.Write(context.Background(), BackfillTranscript{
err := store.Write(context.Background(), SessionTranscript{
CheckpointID: id.MustCheckpointID("deadbeef1234"),
SessionID: "session-001",
Transcript: redact.AlreadyRedacted([]byte("should fail")),
14 unmodified lines
}
// Update only transcript
err = store.Write(context.Background(), BackfillTranscript{
err = store.Write(context.Background(), SessionTranscript{
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.Write(context.Background(), WriteSession{
err := store.Write(context.Background(), Session{
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.Write(context.Background(), BackfillTranscript{
err = store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: redact.AlreadyRedacted(fullTranscript),
21 unmodified lines
repo, store, cpID := setupRepoForUpdate(t)
// Update transcript
err := store.Write(context.Background(), BackfillTranscript{
err := store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: redact.AlreadyRedacted([]byte("new full transcript content\n")),
36 unmodified lines
t.Parallel()
_, store, _ := setupRepoForUpdate(t)
err := store.Write(context.Background(), BackfillTranscript{
err := store.Write(context.Background(), SessionTranscript{
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.Write(context.Background(), BackfillTranscript{
err := store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "nonexistent-session",
Transcript: redact.AlreadyRedacted(fullTranscript),
22 unmodified lines
t.Fatalf("Read() before error = %v", err)
}
err = store.Write(context.Background(), BackfillTranscript{
err = store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: redact.AlreadyRedacted([]byte("updated\n")),
48 unmodified lines
summary.CheckpointVersion = ""
})
if err := store.Write(context.Background(), BackfillAttribution{CheckpointID: cpID, Attribution: &Attribution{AgentLines: 7}}); err != nil {
if err := store.Write(context.Background(), CheckpointAttribution{CheckpointID: cpID, Attribution: &Attribution{AgentLines: 7}}); err != nil {
t.Fatalf("UpdateCheckpointSummary() error = %v", err)
}
15 unmodified lines
summary.CheckpointVersion = futureVersion
})
if err := store.Write(context.Background(), BackfillAttribution{CheckpointID: cpID, Attribution: &Attribution{AgentLines: 11}}); err != nil {
if err := store.Write(context.Background(), CheckpointAttribution{CheckpointID: cpID, Attribution: &Attribution{AgentLines: 11}}); err != nil {
t.Fatalf("UpdateCheckpointSummary() error = %v", err)
}
15 unmodified lines
summary.CheckpointVersion = futureVersion
})
if err := store.Write(context.Background(), WriteSession{
if err := store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-002",
Strategy: "manual-commit",
151 unmodified lines
// Write initial checkpoint
store := NewGitStore(repo, DefaultV1Refs())
cpID := id.MustCheckpointID("a1b2c3d4e5f6")
err = store.Write(context.Background(), WriteSession{
err = store.Write(context.Background(), Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
6 unmodified lines
}
// Call UpdateCommitted — this is the operation under test
err = store.Write(context.Background(), BackfillTranscript{
err = store.Write(context.Background(), SessionTranscript{
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.Write(context.Background(), BackfillTranscript{
if err := store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: transcript,
21 unmodified lines
transcript := redact.AlreadyRedacted([]byte("stable transcript content\n"))
if err := store.Write(context.Background(), BackfillTranscript{
if err := store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: transcript,
5 unmodified lines
// should never touch the chunking function.
calls := installChunkCounter(t)
if err := store.Write(context.Background(), BackfillTranscript{
if err := store.Write(context.Background(), SessionTranscript{
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.Write(context.Background(), BackfillTranscript{
if err := store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: first,
2 unmodified lines
}
hashBefore := readTranscriptBlobHash(t, repo, cpID)
if err := store.Write(context.Background(), BackfillTranscript{
if err := store.Write(context.Background(), SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: second,
Mcmd/entire/cli/checkpoint/persistent_update_test.go+22/-22
20 unmodified lines
21
22
23
24
24
25
26
27
27
28
29
29
30
31
32
32
33
34
34
35
36
36
37
38
39
40
41
41
42
43
43
44
45
46
47
48
49
48
49
50
51
50
51
52
53
54
55
56
5 unmodified lines
62
63
64
63
65
66
65
67
68
67
69
70
69
71
72
73
74
20 unmodified lines
isWriteRequest()
}
// WriteSession creates or replaces a session document within a checkpoint,
// Session 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 writeSession.)
type WriteSession WriteOptions
type Session WriteOptions
// BackfillTranscript replaces a session's transcript, prompts, and skill
// SessionTranscript replaces a session's transcript, prompts, and skill
// events at stop time without clobbering sibling fields. (Maps to the former
// backfillTranscript.)
type BackfillTranscript UpdateOptions
type SessionTranscript UpdateOptions
// BackfillSummary rewrites only the summary of the checkpoint's latest
// SessionSummary rewrites only the summary of the checkpoint's latest
// session. (Maps to the former backfillSummary.)
type BackfillSummary struct {
type SessionSummary struct {
CheckpointID id.CheckpointID
Summary *Summary
}
// BackfillAttribution rewrites the checkpoint root's combined attribution.
// CheckpointAttribution rewrites the checkpoint root's combined attribution.
// (Maps to the former backfillAttribution.)
type BackfillAttribution struct {
//
//nolint:revive // CheckpointAttribution stutter is accepted — the name makes the checkpoint (vs session) tier explicit alongside the Session* requests.
type CheckpointAttribution struct {
CheckpointID id.CheckpointID
Attribution *Attribution
}
func (WriteSession) isWriteRequest() {}
func (BackfillTranscript) isWriteRequest() {}
func (BackfillSummary) isWriteRequest() {}
func (BackfillAttribution) isWriteRequest() {}
func (Session) isWriteRequest() {}
func (SessionTranscript) isWriteRequest() {}
func (SessionSummary) isWriteRequest() {}
func (CheckpointAttribution) isWriteRequest() {}
// Writer is the committed-store write surface: a single Write that accepts any
// WriteRequest. It is the natural type for mirror fan-out.
5 unmodified lines
// Unknown request types are a programmer error, surfaced rather than ignored.
func (s *GitStore) Write(ctx context.Context, req WriteRequest) error {
switch r := req.(type) {
case WriteSession:
case Session:
return s.writeSession(ctx, WriteOptions(r))
case BackfillTranscript:
case SessionTranscript:
return s.backfillTranscript(ctx, UpdateOptions(r))
case BackfillSummary:
case SessionSummary:
return s.backfillSummary(ctx, r.CheckpointID, r.Summary)
case BackfillAttribution:
case CheckpointAttribution:
return s.backfillAttribution(ctx, r.CheckpointID, r.Attribution)
default:
return fmt.Errorf("checkpoint: unsupported write request %T", req)
Mcmd/entire/cli/checkpoint/persistent_write.go+18/-16
25 unmodified lines
26
27
28
29
30
29
30
31
32
33
2 unmodified lines
36
37
38
39
39
40
41
42
43
43
44
45
46
46
47
48
48
49
50
51
52
53
53
54
55
56
57
58
59
60
60
61
62
63
64
63
64
65
66
67
68
68
69
70
71
71
72
73
74
75
74
75
76
77
78
79
79
80
81
82
83
84
85
86
86
87
88
89
4 unmodified lines
94
95
96
97
97
98
99
100
47 unmodified lines
148
149
150
151
151
152
153
154
155
156
156
157
158
25 unmodified lines
ctx := context.Background()
cpID := id.MustCheckpointID("a1b2c3d4e5f6")
// WriteSession materializes the checkpoint on first session.
if err := store.Write(ctx, WriteSession{
// Session materializes the checkpoint on first session.
if err := store.Write(ctx, Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
2 unmodified lines
AuthorName: "Test",
AuthorEmail: "test@test.com",
}); err != nil {
t.Fatalf("Write(WriteSession) error = %v", err)
t.Fatalf("Write(Session) error = %v", err)
}
summary, err := store.Read(ctx, cpID)
if err != nil || summary == nil {
t.Fatalf("checkpoint not created by WriteSession: summary=%v err=%v", summary, err)
t.Fatalf("checkpoint not created by Session: summary=%v err=%v", summary, err)
}
// BackfillTranscript replaces the session transcript.
// SessionTranscript replaces the session transcript.
full := []byte("full line 1\nfull line 2\n")
if err := store.Write(ctx, BackfillTranscript{
if err := store.Write(ctx, SessionTranscript{
CheckpointID: cpID,
SessionID: "session-001",
Transcript: redact.AlreadyRedacted(full),
}); err != nil {
t.Fatalf("Write(BackfillTranscript) error = %v", err)
t.Fatalf("Write(SessionTranscript) error = %v", err)
}
content, err := store.ReadSessionContent(ctx, cpID, 0)
if err != nil {
t.Fatalf("ReadSessionContent() error = %v", err)
}
if string(content.Transcript) != string(full) {
t.Errorf("BackfillTranscript not applied: got %q want %q", content.Transcript, full)
t.Errorf("SessionTranscript not applied: got %q want %q", content.Transcript, full)
}
// BackfillSummary rewrites the latest session's summary.
if err := store.Write(ctx, BackfillSummary{
// SessionSummary rewrites the latest session's summary.
if err := store.Write(ctx, SessionSummary{
CheckpointID: cpID,
Summary: &Summary{Intent: "why", Outcome: "what"},
}); err != nil {
t.Fatalf("Write(BackfillSummary) error = %v", err)
t.Fatalf("Write(SessionSummary) error = %v", err)
}
if meta := readLatestSessionMetadata(t, repo, cpID); meta.Summary == nil || meta.Summary.Intent != "why" {
t.Errorf("BackfillSummary not applied: %+v", meta.Summary)
t.Errorf("SessionSummary not applied: %+v", meta.Summary)
}
// BackfillAttribution rewrites the checkpoint root combined attribution.
if err := store.Write(ctx, BackfillAttribution{
// CheckpointAttribution rewrites the checkpoint root combined attribution.
if err := store.Write(ctx, CheckpointAttribution{
CheckpointID: cpID,
Attribution: &Attribution{AgentLines: 42},
}); err != nil {
t.Fatalf("Write(BackfillAttribution) error = %v", err)
t.Fatalf("Write(CheckpointAttribution) error = %v", err)
}
rootSummary, err := store.Read(ctx, cpID)
if err != nil {
t.Fatalf("Read() error = %v", err)
}
if rootSummary.CombinedAttribution == nil || rootSummary.CombinedAttribution.AgentLines != 42 {
t.Errorf("BackfillAttribution not applied: %+v", rootSummary.CombinedAttribution)
t.Errorf("CheckpointAttribution not applied: %+v", rootSummary.CombinedAttribution)
}
}
4 unmodified lines
ctx := context.Background()
cpID := id.MustCheckpointID("b1b2c3d4e5f6")
if err := store.Write(ctx, WriteSession{
if err := store.Write(ctx, Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
47 unmodified lines
t.Fatalf("ensureSessionsBranch() error = %v", err)
}
err := store.Write(context.Background(), BackfillSummary{
err := store.Write(context.Background(), SessionSummary{
CheckpointID: id.MustCheckpointID("000000000000"),
Summary: &Summary{Intent: "x"},
})
if !errors.Is(err, ErrCheckpointNotFound) {
t.Errorf("Write(BackfillSummary) error = %v, want ErrCheckpointNotFound", err)
t.Errorf("Write(SessionSummary) error = %v, want ErrCheckpointNotFound", err)
}
}
Mcmd/entire/cli/checkpoint/persistent_write_test.go+19/-19
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.Write(context.Background(), checkpoint.WriteSession{
err = store.Write(context.Background(), checkpoint.Session{
CheckpointID: parsedID,
SessionID: "session-1",
Strategy: "manual-commit",
60 unmodified lines
if err != nil {
t.Fatal(err)
}
err = store.Write(context.Background(), checkpoint.WriteSession{
err = store.Write(context.Background(), checkpoint.Session{
CheckpointID: parsedID,
SessionID: "session-1",
Strategy: "manual-commit",
435 unmodified lines
t.Fatal(err)
}
err = store.Write(context.Background(), checkpoint.WriteSession{
err = store.Write(context.Background(), checkpoint.Session{
CheckpointID: cpID,
SessionID: "session-1",
Strategy: "manual-commit",
Mcmd/entire/cli/dispatch/mode_local_test.go+3/-3
941 unmodified lines
942
943
944
945
945
946
947
948
941 unmodified lines
}
elapsed := time.Since(start)
if err := store.Write(ctx, checkpoint.BackfillSummary{CheckpointID: checkpointID, Summary: summary}); err != nil {
if err := store.Write(ctx, checkpoint.SessionSummary{CheckpointID: checkpointID, Summary: summary}); err != nil {
return fmt.Errorf("failed to save summary: %w", err)
}
Mcmd/entire/cli/explain.go+1/-1
74 unmodified lines
75
76
77
78
78
79
80
81
84 unmodified lines
166
167
168
169
169
170
171
172
74 unmodified lines
opts.AuthorEmail = exportTestAuthorEmail
}
store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
require.NoError(t, store.Write(context.Background(), checkpoint.WriteSession(opts)))
require.NoError(t, store.Write(context.Background(), checkpoint.Session(opts)))
}
func TestRunExplainExport_JSONSingleCheckpoint(t *testing.T) {
84 unmodified lines
cpID := id.MustCheckpointID("777711112222")
v1 := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
require.NoError(t, v1.Write(context.Background(), checkpoint.WriteSession{
require.NoError(t, v1.Write(context.Background(), checkpoint.Session{
CheckpointID: cpID,
SessionID: "session-v1-only",
Strategy: "manual-commit",
Mcmd/entire/cli/explain_export_test.go+2/-2
74 unmodified lines
75
76
77
78
79
78
79
80
81
82
74 unmodified lines
func (s *stubTextAgent) ReadSession(*agent.HookInput) (*agent.AgentSession, error) {
return nil, nil //nolint:nilnil // test stub
}
func (s *stubTextAgent) WriteSession(context.Context, *agent.AgentSession) error { return nil }
func (s *stubTextAgent) FormatResumeCommand(string) string { return "" }
func (s *stubTextAgent) Session(context.Context, *agent.AgentSession) error { return nil }
func (s *stubTextAgent) FormatResumeCommand(string) string { return "" }
func (s *stubTextAgent) GenerateText(context.Context, string, string) (string, error) {
return `{"intent":"Intent","outcome":"Outcome","learnings":{"repo":[],"code":[],"workflow":[]},"friction":[],"open_items":[]}`, nil
}
Mcmd/entire/cli/explain_summary_provider_test.go+2/-2
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
236 unmodified lines
1011
1012
1013
1014
1014
1015
1016
1017
975 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
3199 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()).Write(ctx, checkpoint.WriteSession{
require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(ctx, checkpoint.Session{
CheckpointID: cpID,
SessionID: "session-auto",
Strategy: "manual-commit",
254 unmodified lines
id.MustCheckpointID("e7aaaaaaaaaa"),
id.MustCheckpointID("e7bbbbbbbbbb"),
} {
require.NoError(t, store.Write(ctx, checkpoint.WriteSession{
require.NoError(t, store.Write(ctx, checkpoint.Session{
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()).Write(ctx, checkpoint.WriteSession{
require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(ctx, checkpoint.Session{
CheckpointID: collisionID,
SessionID: "session-collision",
Strategy: "manual-commit",
236 unmodified lines
require.NoError(t, err)
store := stores.Persistent
cpID := id.MustCheckpointID("a1b2c3d4e5f6")
require.NoError(t, store.Write(ctx, checkpoint.WriteSession{
require.NoError(t, store.Write(ctx, checkpoint.Session{
CheckpointID: cpID,
SessionID: "session-001",
Strategy: "manual-commit",
975 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()).Write(context.Background(), checkpoint.WriteSession{
require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(context.Background(), checkpoint.Session{
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()).Write(ctx, checkpoint.WriteSession{
require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(ctx, checkpoint.Session{
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()).Write(ctx, checkpoint.WriteSession{
require.NoError(t, checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
require.NoError(t, v1Store.Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
require.NoError(t, v1Store.Write(ctx, checkpoint.Session{
CheckpointID: cpID,
SessionID: "session-v1",
Strategy: "manual-commit",
51 unmodified lines
`{"type":"assistant","message":{"content":"raw reply"}}` + "\n",
)
require.NoError(t, v1Store.Write(ctx, checkpoint.WriteSession{
require.NoError(t, v1Store.Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
require.NoError(t, v1Store.Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
require.NoError(t, v1Store.Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
require.NoError(t, v1Store.Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
require.NoError(t, v1Store.Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
require.NoError(t, v1Store.Write(ctx, checkpoint.Session{
CheckpointID: v1ID,
SessionID: "session-v1",
Strategy: "manual-commit",
3199 unmodified lines
// Write committed checkpoint metadata so getBranchCheckpoints can find it
store := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs())
if err := store.Write(context.Background(), checkpoint.WriteSession{
if err := store.Write(context.Background(), checkpoint.Session{
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.Write(context.Background(), checkpoint.WriteSession{
if err := store.Write(context.Background(), checkpoint.Session{
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.Write(context.Background(), checkpoint.WriteSession{
require.NoError(t, store.Write(context.Background(), checkpoint.Session{
CheckpointID: cpID,
SessionID: sessionID,
Strategy: "manual-commit",
Mcmd/entire/cli/explain_test.go+18/-18
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.Write(context.Background(), checkpoint.WriteSession{
require.NoError(t, store.Write(context.Background(), checkpoint.Session{
CheckpointID: cpID,
SessionID: "head-flags-session",
Strategy: "manual-commit",
Mcmd/entire/cli/head_checkpoint_flags_test.go+1/-1
211 unmodified lines
212
213
214
215
215
216
217
218
41 unmodified lines
260
261
262
263
263
264
265
266
17 unmodified lines
284
285
286
287
288
287
288
289
290
291
6 unmodified lines
298
299
300
301
301
302
303
304
5 unmodified lines
310
311
312
313
313
314
315
315
316
317
318
352 unmodified lines
671
672
673
674
674
675
676
677
44 unmodified lines
722
723
724
725
725
726
727
728
16 unmodified lines
745
746
747
748
749
748
749
750
751
752
6 unmodified lines
759
760
761
762
762
763
764
765
5 unmodified lines
771
772
773
774
774
775
776
776
777
778
779
289 unmodified lines
1069
1070
1071
1072
1072
1073
1074
1075
37 unmodified lines
1113
1114
1115
1116
1116
1117
1118
1119
16 unmodified lines
1136
1137
1138
1139
1140
1139
1140
1141
1142
1143
186 unmodified lines
1330
1331
1332
1333
1333
1334
1335
1336
45 unmodified lines
1382
1383
1384
1385
1385
1386
1387
1388
1389
1390
1391
1390
1391
1392
1393
1394
1393
1394
1395
1396
1397
211 unmodified lines
})
}
// TestAgentSessionOperations verifies ReadSession/WriteSession via agent interface.
// TestAgentSessionOperations verifies ReadSession/Session via agent interface.
func TestAgentSessionOperations(t *testing.T) {
t.Parallel()
41 unmodified lines
}
})
t.Run("WriteSession writes NativeData to file", func(t *testing.T) {
t.Run("Session writes NativeData to file", func(t *testing.T) {
t.Parallel()
env := NewTestEnv(t)
env.InitRepo()
17 unmodified lines
dstPath := filepath.Join(env.RepoDir, "dst.jsonl")
session.SessionRef = dstPath
// Verify file was written
6 unmodified lines
}
})
t.Run("WriteSession rejects wrong agent", func(t *testing.T) {
t.Run("Session rejects wrong agent", func(t *testing.T) {
t.Parallel()
ag, _ := agent.Get("claude-code")
5 unmodified lines
NativeData: []byte("data"),
}
err := ag.WriteSession(context.Background(), session)
err := ag.Session(context.Background(), session)
if err == nil {
t.Error("WriteSession() should reject session from different agent")
t.Error("Session() should reject session from different agent")
}
})
}
352 unmodified lines
})
}
// TestGeminiCLISessionOperations verifies ReadSession/WriteSession via Gemini agent interface.
// TestGeminiCLISessionOperations verifies ReadSession/Session via Gemini agent interface.
func TestGeminiCLISessionOperations(t *testing.T) {
t.Parallel()
44 unmodified lines
}
})
t.Run("WriteSession writes NativeData to file", func(t *testing.T) {
t.Run("Session writes NativeData to file", func(t *testing.T) {
t.Parallel()
env := NewTestEnv(t)
env.InitRepo()
16 unmodified lines
dstPath := filepath.Join(env.RepoDir, "dst.json")
session.SessionRef = dstPath
// Verify file was written
6 unmodified lines
}
})
t.Run("WriteSession rejects wrong agent", func(t *testing.T) {
t.Run("Session rejects wrong agent", func(t *testing.T) {
t.Parallel()
ag, _ := agent.Get("gemini")
5 unmodified lines
NativeData: []byte("data"),
}
err := ag.WriteSession(context.Background(), session)
err := ag.Session(context.Background(), session)
if err == nil {
t.Error("WriteSession() should reject session from different agent")
t.Error("Session() should reject session from different agent")
}
})
}
289 unmodified lines
})
}
// TestFactoryAIDroidSessionMethods verifies ReadSession, WriteSession, and GetSessionDir.
// TestFactoryAIDroidSessionMethods verifies ReadSession, Session, and GetSessionDir.
func TestFactoryAIDroidSessionMethods(t *testing.T) {
t.Parallel()
37 unmodified lines
}
})
t.Run("WriteSession round-trips with ReadSession", func(t *testing.T) {
t.Run("Session round-trips with ReadSession", func(t *testing.T) {
t.Parallel()
tmpDir := t.TempDir()
16 unmodified lines
session.SessionRef = restoredPath
ctx := context.Background()
if err := ag.WriteSession(ctx, session); err != nil {
t.Fatalf("WriteSession() error = %v", err)
if err := ag.Session(ctx, session); err != nil {
t.Fatalf("Session() error = %v", err)
}
restored, err := os.ReadFile(restoredPath)
186 unmodified lines
})
}
// TestOpenCodeSessionOperations verifies ReadSession/WriteSession via OpenCode agent interface.
// TestOpenCodeSessionOperations verifies ReadSession/Session via OpenCode agent interface.
func TestOpenCodeSessionOperations(t *testing.T) {
t.Parallel()
45 unmodified lines
}
})
t.Run("WriteSession validates input", func(t *testing.T) {
t.Run("Session validates input", func(t *testing.T) {
t.Parallel()
ag, _ := agent.Get("opencode")
if err := ag.WriteSession(context.Background(), nil); err == nil {
t.Error("WriteSession(nil) should error")
if err := ag.Session(context.Background(), nil); err == nil {
t.Error("Session(nil) should error")
}
if err := ag.WriteSession(context.Background(), &agent.AgentSession{}); err == nil {
t.Error("WriteSession with empty NativeData should error")
if err := ag.Session(context.Background(), &agent.AgentSession{}); err == nil {
t.Error("Session with empty NativeData should error")
}
})
}
Mcmd/entire/cli/integration_test/agent_test.go+24/-24
71 unmodified lines
72
73
74
75
75
76
77
78
71 unmodified lines
return nil, nil
}
func (m *mockLifecycleAgent) WriteSession(_ context.Context, _ *agent.AgentSession) error {
func (m *mockLifecycleAgent) Session(_ context.Context, _ *agent.AgentSession) error {
return nil
}
Mcmd/entire/cli/lifecycle_test.go+1/-1
986 unmodified lines
987
988
989
990
991
990
991
992
993
994
986 unmodified lines
NativeData: logContent,
}
// Write the session using the agent's WriteSession method
if err := ag.WriteSession(ctx, agentSession); err != nil {
// Write the session using the agent's Session method
if err := ag.Session(ctx, agentSession); err != nil {
logging.Error(ctx, "resume session failed during write",
slog.String("checkpoint_id", checkpointID.String()),
slog.String("session_id", sessionID),
Mcmd/entire/cli/resume.go+2/-2
60 unmodified lines
61
62
63
64
64
65
66
67
463 unmodified lines
531
532
533
534
534
535
536
537
134 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
60 unmodified lines
func (a *recordingResumeAgent) ReadSession(*agent.HookInput) (*agent.AgentSession, error) {
return nil, nil //nolint:nilnil // Not used by this test agent.
}
func (a *recordingResumeAgent) WriteSession(_ context.Context, session *agent.AgentSession) error {
func (a *recordingResumeAgent) Session(_ context.Context, session *agent.AgentSession) error {
a.writtenSession = session
return nil
}
463 unmodified lines
) {
t.Helper()
if err := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(context.Background(), checkpoint.WriteSession{
if err := checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(context.Background(), checkpoint.Session{
CheckpointID: checkpointID,
SessionID: sessionID,
CreatedAt: createdAt,
134 unmodified lines
},
}
for _, session := range sessions {
if err := store.Write(ctx, checkpoint.WriteSession{
if err := store.Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
if err := v1Store.Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
if err := v1Store.Write(ctx, checkpoint.Session{
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.Write(ctx, checkpoint.WriteSession{
if err := v1Store.Write(ctx, checkpoint.Session{
CheckpointID: cpID,
SessionID: "2025-01-01-test-session-uuid",
Strategy: "manual-commit",
Mcmd/entire/cli/resume_test.go+6/-6
961 unmodified lines
962
963
964
965
965
966
967
968
961 unmodified lines
func (manifestTokenTestAgent) ReadSession(*agent.HookInput) (*agent.AgentSession, error) {
return &agent.AgentSession{}, nil
}
func (manifestTokenTestAgent) WriteSession(context.Context, *agent.AgentSession) error {
func (manifestTokenTestAgent) Session(context.Context, *agent.AgentSession) error {
return nil
}
func (manifestTokenTestAgent) FormatResumeCommand(string) string { return "" }
Mcmd/entire/cli/review/manifest_test.go+1/-1
395 unmodified lines
396
397
398
399
399
400
401
402
395 unmodified lines
t.Fatalf("open repo: %v", err)
}
cpID := checkpointid.MustCheckpointID(checkpointID)
err = checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(context.Background(), checkpoint.WriteSession{
err = checkpoint.NewGitStore(repo, checkpoint.DefaultV1Refs()).Write(context.Background(), checkpoint.Session{
CheckpointID: cpID,
SessionID: checkpointID,
Strategy: "manual-commit",
Mcmd/entire/cli/review_context_test.go+1/-1
745 unmodified lines
746
747
748
749
749
750
751
752
38 unmodified lines
791
792
793
794
794
795
796
797
745 unmodified lines
SessionRef: sessionFile,
NativeData: content,
}
if err := agent.WriteSession(ctx, agentSession); err != nil {
if err := agent.Session(ctx, agentSession); err != nil {
return "", fmt.Errorf("failed to write session: %w", err)
}
return sessionID, nil
38 unmodified lines
SessionRef: sessionFile,
NativeData: content,
}
if err := agent.WriteSession(ctx, agentSession); err != nil {
if err := agent.Session(ctx, agentSession); err != nil {
return "", fmt.Errorf("failed to write session: %w", err)
}
return sessionID, nil
Mcmd/entire/cli/rewind.go+2/-2
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.Write(context.Background(), checkpoint.WriteSession{
if err := store.Write(context.Background(), checkpoint.Session{
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.Write(t.Context(), checkpoint.WriteSession{
require.NoError(t, store.Write(t.Context(), checkpoint.Session{
CheckpointID: cpID,
SessionID: sid,
Strategy: "manual-commit",
Mcmd/entire/cli/strategy/clean_test.go+1/-1
134 unmodified lines
135
136
137
138
138
139
140
141
148 unmodified lines
290
291
292
293
293
294
295
296
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.PersistentStore.Write with a checkpoint.WriteSession request for persistent storage.
// Uses checkpoint.PersistentStore.Write with a checkpoint.Session request for persistent 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.
148 unmodified lines
writeV1Start := time.Now()
writeCtx, writeCommittedSpan := perf.Start(ctx, "write_committed_v1")
if err := store.Write(writeCtx, cpkg.WriteSession(writeOpts)); err != nil {
if err := store.Write(writeCtx, cpkg.Session(writeOpts)); err != nil {
writeCommittedSpan.RecordError(err)
writeCommittedSpan.End()
return nil, fmt.Errorf("failed to write checkpoint metadata: %w", err)
Mcmd/entire/cli/strategy/manual_commit_condensation.go+2/-2
1157 unmodified lines
1158
1159
1160
1161
1161
1162
1163
1164
1665 unmodified lines
2830
2831
2832
2833
2833
2834
2835
2836
1157 unmodified lines
slog.Float64("agent_percentage", agentPercentage),
)
if err := store.Write(ctx, checkpoint.BackfillAttribution{CheckpointID: checkpointID, Attribution: combined}); err != nil {
if err := store.Write(ctx, checkpoint.CheckpointAttribution{CheckpointID: checkpointID, Attribution: combined}); err != nil {
return fmt.Errorf("persisting combined attribution: %w", err)
}
1665 unmodified lines
PrecomputedBlobs: precomputed,
}
updateErr := store.Write(ctx, checkpoint.BackfillTranscript(updateOpts))
updateErr := store.Write(ctx, checkpoint.SessionTranscript(updateOpts))
if updateErr != nil {
logging.Warn(logCtx, "finalize: failed to update checkpoint",
slog.String("checkpoint_id", cpIDStr),
Mcmd/entire/cli/strategy/manual_commit_hooks.go+2/-2
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.Write(context.Background(), checkpoint.WriteSession{
require.NoError(t, store.Write(context.Background(), checkpoint.Session{
CheckpointID: cpID,
SessionID: sessionID,
Strategy: "manual-commit",
Mcmd/entire/cli/strategy/manual_commit_opf_rewrite_test.go+1/-1
698 unmodified lines
699
700
701
702
702
703
704
705
74 unmodified lines
780
781
782
783
783
784
785
786
698 unmodified lines
}
// Checkpoint metadata comes from the shared entire/checkpoints/v1 branch
// and is attacker-influenceable. Reject path separators/absolute IDs before
// they reach ResolveSessionFile + WriteSession, which would otherwise let a
// they reach ResolveSessionFile + Session, which would otherwise let a
// crafted session ID overwrite files outside the agent session directory.
if err := validation.ValidateSessionID(sessionID); err != nil {
fmt.Fprintf(errW, " Warning: session %d has unsafe session ID %q, skipping: %v\n", i, sessionID, err)
74 unmodified lines
SessionRef: sessionFile,
NativeData: content.Transcript,
}
if writeErr := sessionAgent.WriteSession(ctx, agentSession); writeErr != nil {
if writeErr := sessionAgent.Session(ctx, agentSession); writeErr != nil {
if totalSessions > 1 {
fmt.Fprintf(errW, " Warning: failed to write session: %v\n", writeErr)
continue
Mcmd/entire/cli/strategy/manual_commit_rewind.go+2/-2
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.Write(t.Context(), checkpoint.WriteSession{
require.NoError(t, store.Write(t.Context(), checkpoint.Session{
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.Write(t.Context(), checkpoint.WriteSession{
require.NoError(t, store.Write(t.Context(), checkpoint.Session{
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
40 unmodified lines
663
664
665
666
666
667
668
669
27 unmodified lines
697
698
699
700
701
700
701
615 unmodified lines
) {
t.Helper()
err := cpkg.NewGitStore(repo, cpkg.DefaultV1Refs()).Write(context.Background(), cpkg.WriteSession{
err := cpkg.NewGitStore(repo, cpkg.DefaultV1Refs()).Write(context.Background(), cpkg.Session{
CheckpointID: checkpointID,
SessionID: sessionID,
CreatedAt: createdAt,
40 unmodified lines
func (a *restoreLogsOnlyAgent) ReadSession(*agent.HookInput) (*agent.AgentSession, error) {
return nil, nil //nolint:nilnil // Not used by this test agent.
}
func (a *restoreLogsOnlyAgent) WriteSession(_ context.Context, session *agent.AgentSession) error {
func (a *restoreLogsOnlyAgent) Session(_ context.Context, session *agent.AgentSession) error {
if err := os.MkdirAll(filepath.Dir(session.SessionRef), 0o750); err != nil {
return err
}
27 unmodified lines
func (f *fakeExternalAgent) ReadSession(_ *agent.HookInput) (*agent.AgentSession, error) {
return nil, nil //nolint:nilnil // test stub
}
func (f *fakeExternalAgent) WriteSession(_ context.Context, _ *agent.AgentSession) error { return nil }
func (f *fakeExternalAgent) FormatResumeCommand(_ string) string { return "" }
func (f *fakeExternalAgent) Session(_ context.Context, _ *agent.AgentSession) error { return nil }
func (f *fakeExternalAgent) FormatResumeCommand(_ string) string { return "" }
Mcmd/entire/cli/strategy/rewind_test.go+4/-4
48 unmodified lines
49
50
51
52
52
53
54
55
48 unmodified lines
return &agent.AgentSession{}, nil
}
func (s *stubTextGenerator) WriteSession(context.Context, *agent.AgentSession) error { return nil }
func (s *stubTextGenerator) Session(context.Context, *agent.AgentSession) error { return nil }
func (s *stubTextGenerator) FormatResumeCommand(string) string { return "" }
Mcmd/entire/cli/summarize/claude_test.go+1/-1
32 unmodified lines
33
34
35
36
37
36
37
38
39
40
32 unmodified lines
func (m *mockTextGenerator) ReadSession(*agent.HookInput) (*agent.AgentSession, error) {
return nil, nil //nolint:nilnil // test stub
}
func (m *mockTextGenerator) WriteSession(context.Context, *agent.AgentSession) error { return nil }
func (m *mockTextGenerator) FormatResumeCommand(string) string { return "" }
func (m *mockTextGenerator) Session(context.Context, *agent.AgentSession) error { return nil }
func (m *mockTextGenerator) FormatResumeCommand(string) string { return "" }
func (m *mockTextGenerator) GenerateText(_ context.Context, prompt string, model string) (string, error) {
m.prompt = prompt
m.model = model
Mcmd/entire/cli/summarize/text_generator_test.go+2/-2