-
Notifications
You must be signed in to change notification settings - Fork 276
feat: v2 dual-write for checkpoints behind feature flag #759
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
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 594f54c
feat: add V2Store skeleton with ref management helpers
pfleidi f343da1
feat: add V2GitStore.writeCommittedMain for metadata writes to /main ref
pfleidi 96aff83
feat: add V2GitStore.writeCommittedFullTranscript
pfleidi e79e4a2
Merge branch 'main' of github.com:entireio/cli into feat/checkpoints-…
pfleidi 0c3244c
feat: add V2GitStore.WriteCommitted composing /main and /full/current…
pfleidi 4c754d4
Write content hash to ephemeral /full/current ref
pfleidi dc3beb0
feat: wire v2 dual-write into CondenseSession, gated by checkpoints_v2
pfleidi 6217021
feat: add V2GitStore.UpdateCommitted and wire into stop-time
pfleidi 2da036a
test: add integration tests for v2 dual-write workflow
pfleidi 20a37d5
fix: add omitempty to SessionFilePaths to avoid empty strings in v2
pfleidi 66841b2
fix: Remove redundant validation code
pfleidi 860efa8
Only mark optional attributes as `omitempty`
pfleidi 1a5840d
Revert changes to unrelated file
pfleidi 25b2d9a
fix: address PR review feedback on comments, logging, and context sco…
pfleidi 10ab903
Remove outdated comment lines
pfleidi 65d73a0
Evaluate v2 strategy settings only once
pfleidi 438e156
Apply suggestion from @Copilot
pfleidi 9b1fc99
fix: accumulate transcripts on /full/current ref instead of replacing
pfleidi 3ffb586
Merge branch 'feat/checkpoints-v2-refs' of github.com:entireio/cli in…
pfleidi 700e69f
Revert SessionFilePaths since they're not relevant at the moment
pfleidi 79915c8
Merge branch 'main' of github.com:entireio/cli into feat/checkpoints-…
pfleidi be7412b
Minor simplifications
pfleidi 3560d7b
Address PR review comments
pfleidi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.