Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0eb9599
feat: add v2 checkpoint ref name constants
pfleidi Mar 23, 2026
594f54c
feat: add V2Store skeleton with ref management helpers
pfleidi Mar 23, 2026
f343da1
feat: add V2GitStore.writeCommittedMain for metadata writes to /main ref
pfleidi Mar 23, 2026
96aff83
feat: add V2GitStore.writeCommittedFullTranscript
pfleidi Mar 23, 2026
e79e4a2
Merge branch 'main' of github.com:entireio/cli into feat/checkpoints-…
pfleidi Mar 23, 2026
0c3244c
feat: add V2GitStore.WriteCommitted composing /main and /full/current…
pfleidi Mar 23, 2026
4c754d4
Write content hash to ephemeral /full/current ref
pfleidi Mar 23, 2026
dc3beb0
feat: wire v2 dual-write into CondenseSession, gated by checkpoints_v2
pfleidi Mar 23, 2026
6217021
feat: add V2GitStore.UpdateCommitted and wire into stop-time
pfleidi Mar 23, 2026
2da036a
test: add integration tests for v2 dual-write workflow
pfleidi Mar 23, 2026
20a37d5
fix: add omitempty to SessionFilePaths to avoid empty strings in v2
pfleidi Mar 23, 2026
66841b2
fix: Remove redundant validation code
pfleidi Mar 23, 2026
860efa8
Only mark optional attributes as `omitempty`
pfleidi Mar 23, 2026
1a5840d
Revert changes to unrelated file
pfleidi Mar 24, 2026
25b2d9a
fix: address PR review feedback on comments, logging, and context sco…
pfleidi Mar 24, 2026
10ab903
Remove outdated comment lines
pfleidi Mar 24, 2026
65d73a0
Evaluate v2 strategy settings only once
pfleidi Mar 24, 2026
438e156
Apply suggestion from @Copilot
pfleidi Mar 24, 2026
9b1fc99
fix: accumulate transcripts on /full/current ref instead of replacing
pfleidi Mar 24, 2026
3ffb586
Merge branch 'feat/checkpoints-v2-refs' of github.com:entireio/cli in…
pfleidi Mar 24, 2026
700e69f
Revert SessionFilePaths since they're not relevant at the moment
pfleidi Mar 24, 2026
79915c8
Merge branch 'main' of github.com:entireio/cli into feat/checkpoints-…
pfleidi Mar 24, 2026
be7412b
Minor simplifications
pfleidi Mar 25, 2026
3560d7b
Address PR review comments
pfleidi Mar 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
481 changes: 481 additions & 0 deletions cmd/entire/cli/checkpoint/v2_committed.go

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions cmd/entire/cli/checkpoint/v2_store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package checkpoint

import (
"fmt"

"github.com/go-git/go-git/v6"
"github.com/go-git/go-git/v6/plumbing"
"github.com/go-git/go-git/v6/plumbing/object"
)

// V2GitStore provides checkpoint storage operations for the v2 ref layout.
// It writes to two custom refs under refs/entire/:
// - /main: permanent metadata + compact transcripts
// - /full/current: active generation of raw transcripts
//
// V2GitStore is separate from GitStore (v1) to keep concerns isolated
// and simplify future v1 removal. It composes GitStore internally to
// reuse ref-agnostic entry-building helpers (tree surgery, session
// indexing, summary aggregation).
type V2GitStore struct {
repo *git.Repository
gs *GitStore // shared entry-building helpers (same package)
}

// NewV2GitStore creates a new v2 checkpoint store backed by the given git repository.
func NewV2GitStore(repo *git.Repository) *V2GitStore {
return &V2GitStore{
repo: repo,
gs: &GitStore{repo: repo},
}
}

// ensureRef ensures that a custom ref exists, creating an orphan commit
// with an empty tree if it does not.
func (s *V2GitStore) ensureRef(refName plumbing.ReferenceName) error {
_, err := s.repo.Reference(refName, true)
if err == nil {
return nil // Already exists
}

emptyTreeHash, err := BuildTreeFromEntries(s.repo, make(map[string]object.TreeEntry))
if err != nil {
return fmt.Errorf("failed to build empty tree: %w", err)
}

authorName, authorEmail := GetGitAuthorFromRepo(s.repo)
commitHash, err := CreateCommit(s.repo, emptyTreeHash, plumbing.ZeroHash, "Initialize v2 ref", authorName, authorEmail)
if err != nil {
return fmt.Errorf("failed to create initial commit: %w", err)
}

ref := plumbing.NewHashReference(refName, commitHash)
if err := s.repo.Storer.SetReference(ref); err != nil {
return fmt.Errorf("failed to set ref %s: %w", refName, err)
}

return nil
}

// getRefState returns the parent commit hash and root tree hash for a ref.
func (s *V2GitStore) getRefState(refName plumbing.ReferenceName) (parentHash, treeHash plumbing.Hash, err error) {
ref, err := s.repo.Reference(refName, true)
if err != nil {
return plumbing.ZeroHash, plumbing.ZeroHash, fmt.Errorf("ref %s not found: %w", refName, err)
}

commit, err := s.repo.CommitObject(ref.Hash())
if err != nil {
return plumbing.ZeroHash, plumbing.ZeroHash, fmt.Errorf("failed to get commit for ref %s: %w", refName, err)
}

return ref.Hash(), commit.TreeHash, nil
}

// updateRef creates a new commit on a ref with the given tree, updating the ref to point to it.
func (s *V2GitStore) updateRef(refName plumbing.ReferenceName, treeHash, parentHash plumbing.Hash, message, authorName, authorEmail string) error {
commitHash, err := CreateCommit(s.repo, treeHash, parentHash, message, authorName, authorEmail)
if err != nil {
return fmt.Errorf("failed to create commit: %w", err)
}

ref := plumbing.NewHashReference(refName, commitHash)
if err := s.repo.Storer.SetReference(ref); err != nil {
return fmt.Errorf("failed to update ref %s: %w", refName, err)
}

return nil
}
Loading
Loading