v2 checkpoints: add deterministic /full/root anchor commit#1201
Open
Soph wants to merge 4 commits into
Open
Conversation
/full/root is a shared empty-tree commit constructed with fixed inputs (empty tree, fixed author/time/message, no signature). Every client produces an identical SHA, so concurrent creation across machines converges to the same object rather than producing diverging orphans. This commit only adds the helper and the ref name constant — no callers yet. The well-known SHA is pinned in a test so any accidental change to the deterministic inputs is caught immediately. Changing the inputs on purpose would create a migration problem (old and new clients would produce different SHAs), so the test guards against silent drift. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> Entire-Checkpoint: 9f2569e09fe1
Replace plumbing.ZeroHash with the /full/root commit hash in two
orphan-creation sites:
1. ensureRef, when initializing /full/current for the first time.
2. RotateCurrentGenerationIfNeeded, when creating the empty
/full/current after archiving the previous generation.
Both sites now call EnsureV2FullRoot before creating the commit, so the
deterministic root commit object is materialized lazily on first need.
/main keeps ZeroHash — different namespace, no shared-ancestry
expectation. Existing archive refs from before this change are
untouched; only newly-created /full/current orphans get the new parent.
The rotation test is updated to assert the new parent. Adds a defensive
test that ListArchivedGenerations excludes /full/root (it is already
filtered by the existing 13-digit suffix pattern, but the test pins
the behavior so a future regex change can't silently make /full/root
a deletion candidate).
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Entire-Checkpoint: 6ab3b23e3857
v2RefsToPush now includes /full/root alongside /main and /full/current. Ordered so /full/root goes out first: clones that fetch only the v2 namespace see the anchor before any descendant ref, which keeps the star topology intact for any subsequent rotation that lands. Because /full/root is constructed deterministically, two clients pushing it concurrently send identical bytes. The push is either a no-op (remote already has the same SHA) or a clean create — no non-fast-forward conflict surface is introduced. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> Entire-Checkpoint: 94d5919413d6
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a deterministic refs/entire/checkpoints/v2/full/root commit as a permanent anchor for v2 /full/* generations, enabling shared ancestry and reducing cross-machine divergence when the anchor is created concurrently.
Changes:
- Add helpers to deterministically build and lazily ensure the v2
/full/rootanchor commit/ref. - Parent newly-created and post-rotation
/full/currentcommits on/full/rootinstead ofplumbing.ZeroHash. - Include
/full/rootin the default v2 push set and update tests accordingly.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| cmd/entire/cli/strategy/push_v2.go | Adds /full/root to the list of v2 refs pushed to the remote. |
| cmd/entire/cli/strategy/push_v2_test.go | Updates push output expectation to include v2/full/root. |
| cmd/entire/cli/paths/paths.go | Defines the new V2FullRootRefName ref constant and documents its intent. |
| cmd/entire/cli/checkpoint/v2_store.go | Ensures initial /full/current creation is parented on /full/root. |
| cmd/entire/cli/checkpoint/v2_root.go | New deterministic root commit builder + ensureV2FullRoot helper on V2GitStore. |
| cmd/entire/cli/checkpoint/v2_root_test.go | New tests pinning the well-known deterministic root SHA and idempotency. |
| cmd/entire/cli/checkpoint/v2_generation.go | Parents the post-rotation “Start generation” commit on /full/root. |
| cmd/entire/cli/checkpoint/v2_generation_test.go | Adds coverage that /full/root is excluded from archive listings; updates rotation expectations to require /full/root parent. |
Five tweaks from review: 1. Push-order comment in v2RefsToPush previously said "/full/root is pushed first," but /main is actually first in the slice. The intent was "before /full/current"; the comment now says that explicitly. 2. The doc on V2FullRootRefName said "Created lazily on first rotation," missing the other call site (ensureRef for /full/current). Now mentions both, in the order they'd typically fire. 3. ensureV2FullRoot did not validate that an existing /full/root ref matches the deterministic SHA. A corrupted or repointed ref would silently become the anchor for future generations. Added a tripwire: on hash mismatch, log a warning with expected/actual and return the existing hash (no auto-repair — that could clobber an intentional override). The expected SHA moves into a package-level constant v2FullRootHash so production code and tests share one source of truth. A new test, TestEnsureV2FullRoot_WarnsOnUnexpectedHash, exercises the tamper path. 4. Deleted TestEnsureV2FullRoot_PreservesPreexistingRef; its assertions duplicated TestEnsureV2FullRoot_IsIdempotent and the name oversold what it tested. 5. TestPushV2Refs_SkipsUnrecordedArchiveRefs asserted the push output string mentioned v2/full/root but did not check the ref landed in the bare repo. Added the explicit Reference() assertion next to /main and /full/current. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> Entire-Checkpoint: d610153a9309
pfleidi
approved these changes
May 13, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
https://entire.io/gh/entireio/cli/trails/370
Summary
Introduces
refs/entire/checkpoints/v2/full/root— a single permanent ref that anchors every/full/*archived generation. Constructed deterministically (empty tree, fixed author, fixed Unix-epoch timestamp, fixed message, no signature) so every client independently produces an identical SHA. That makes concurrent first-time creation across machines converge to the same object instead of producing diverging orphans.This is prep work for a larger v2 rotation rework. On its own it does not change any user-visible behavior.
What changes
buildV2FullRootCommit+ensureV2FullRoothelpers (cmd/entire/cli/checkpoint/v2_root.go).ensureRef, when creating/full/currentfor the first time, parents it on/full/rootinstead ofplumbing.ZeroHash.RotateCurrentGenerationIfNeededparents the post-rotation orphan-reset commit on/full/rootinstead ofplumbing.ZeroHash./full/rootis pushed alongside/mainand/full/current. Deterministic SHA means concurrent pushes of/full/rootfrom different clients send identical bytes — no non-fast-forward conflict surface.The well-known SHA
c095af40b171ff4c3c4a781abacd39aa499e183bis pinned in a test so any accidental change to the deterministic inputs is caught immediately.What does NOT change
/maincontinues to useZeroHashas its initial-commit parent (different namespace, no shared-ancestry expectation)./full/currentorphans and future rotations.ListArchivedGenerationsand cleanup retention already filter/full/rootout via the existing 13-digit suffix pattern; added a defensive test to pin that behavior.Why three commits
Each commit leaves the codebase compiling, linting clean, and tests passing:
Add deterministic /full/root anchor commit for v2 checkpoints— introduces the helpers and ref name constant. No call sites change.Parent v2 orphan commits on /full/root— rewiresensureRefandRotateCurrentGenerationIfNeededto parent on/full/root.Push /full/root with the v2 main and current refs— adds/full/rootto the push ref list, ordered first so clones fetch the anchor before any descendant ref.Test plan
🤖 Generated with Claude Code
Note
Medium Risk
Changes how v2
/full/currentis initialized and rotated by introducing a shared parent commit and pushes a new ref, which could affect checkpoint history topology and push/recovery behavior if misordered or miscomputed.Overview
Introduces a new deterministic
refs/entire/checkpoints/v2/full/rootanchor commit and ref, pinned to a well-known SHA, to give all v2/full/*generations a shared ancestor.Updates v2 generation initialization and rotation so new
/full/current“reset” commits are parented on/full/root(instead of being true orphans), and ensures/full/rootis created lazily when needed.Extends the v2 push set to include
/full/root(pushed before/full/current) and adds tests to lock in determinism, ancestry expectations, and that/full/rootis never treated as an archived generation.Reviewed by Cursor Bugbot for commit 34c7ba7. Configure here.