Extract checkpoint write helpers into treeWriter (no behavior change) · Entire

Extract checkpoint write helpers into treeWriter (no behavior change)

9ae0014main·

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 // into the v1 tree, so the committed v1 tree is byte-identical. writeCheckpointSummary now takes the checkpoint-version to stamp.

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

\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 ////... as before. existing, err := s.subtreeObjAt(rootTreeHash, opts.CheckpointID.Path()) if err != nil { return err }

// 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 }