Extract checkpoint write helpers into treeWriter (no behavior change) · Entire
Extract checkpoint write helpers into treeWriter (no behavior change)
9ae0014→main·
Soph·2w ago·4 files·+356 added/-266 removed
Refactor toward the per-checkpoint git-ref store (#1471): isolate the repo-only "build one checkpoint's subtree" machinery from the git-branch store so a second backend can share it instead of duplicating it.
- The repo-only entry/subtree builders (writeStandardCheckpointEntries,
writeTaskCheckpointEntries, writeSessionToSubdirectory, writeCheckpointSummary,
findSessionIndex, reaggregateFromEntries, replaceTranscript, replaceSkillEvents,
writeTranscript/writeCompactTranscript, copyMetadataDir, readSummaryFromBlob,
readMetadataFromBlob, buildCommitMessage) move from *GitStore to a new
*treeWriter; GitStore embeds *treeWriter so call sites resolve via promotion.
- GitStore's four write methods route through shared appliers anchored at the
checkpoint-dir root; the git-branch store keeps splicing the result under
Behavior-preserving: the git-branch checkpoint, strategy, and integration suites are unchanged. Nothing constructs a second backend yet.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
99d650653e0cView transcript
Changes
4
cmd/entire/cli/checkpoint
Mpersistent.go+327/-259
Mpersistent_tripwire_test.go+1/-1
Mpersistent_update_test.go+11/-3
Mstore.go+17/-3
\n``` 81 unmodified lines
// Use sharded path: <id[:2]>/<id[2:]>/ basePath := opts.CheckpointID.Path() + "/" checkpointPath := opts.CheckpointID.Path()
// Flatten only the checkpoint subtree (O(files in checkpoint))
entries, err := s.flattenCheckpointEntries(rootTreeHash, checkpointPath)
// Build the new checkpoint subtree from its current state on the v1 branch,
// then splice it back at the shard path. basePath keeps the v1 sharded layout
// so stored session-file pointers stay /
// Track task metadata path for commit trailer var taskMetadataPath string
// Handle task checkpoints if opts.IsTask && opts.ToolUseID != "" { taskMetadataPath, err = s.writeTaskCheckpointEntries(ctx, opts, basePath, entries) if err != nil { return err } }
// Write standard checkpoint entries (transcript, prompts, context, metadata) if err := s.writeStandardCheckpointEntries(ctx, opts, basePath, entries); err != nil { return plumbing.ZeroHash, "" }
checkpointSubtree, taskMetadataPath, err := s.applySessionWrite(ctx, opts, existing, opts.CheckpointID.Path()+"/", CheckpointVersionBranchV1) if err != nil { return err }
// Build checkpoint subtree and splice into root (O(depth) tree surgery) newTreeHash, err := s.spliceCheckpointSubtree(ctx, rootTreeHash, opts.CheckpointID, basePath, entries) newTreeHash, err := s.spliceCheckpointSubtree(rootTreeHash, opts.CheckpointID, checkpointSubtree) if err != nil { return err } }
return s.setPrimaryRef(newCommitHash)
// flattenCheckpointEntries reads only the entries under a specific checkpoint path // from the sessions branch tree. This is O(files in checkpoint) instead of O(all checkpoints). // Returns an empty map if the checkpoint doesn't exist yet. func (s *GitStore) flattenCheckpointEntries(rootTreeHash plumbing.Hash, checkpointPath string) (map[string]object.TreeEntry, error) { entries := make(map[string]object.TreeEntry) }
// subtreeObjAt returns the tree object for one checkpoint's subtree within a root tree, or (nil, nil) when the root or the checkpoint path does not exist yet. // path is the in-tree checkpoint path (e.g. "a3/b2c4d5e6f7"); pass "" to return // the root tree itself (the per-checkpoint-ref layout, where the whole tree is // the checkpoint subtree). func (s *treeWriter) subtreeObjAt(rootTreeHash plumbing.Hash, path string) (*object.Tree, error) { if rootTreeHash == plumbing.ZeroHash { return entries, nil } return nil, nil //nolint:nilnil // absent checkpoint (no tree yet), not an error }