Skip to content

v2 checkpoints: add deterministic /full/root anchor commit#1201

Open
Soph wants to merge 4 commits into
mainfrom
soph/improve-v2
Open

v2 checkpoints: add deterministic /full/root anchor commit#1201
Soph wants to merge 4 commits into
mainfrom
soph/improve-v2

Conversation

@Soph
Copy link
Copy Markdown
Collaborator

@Soph Soph commented May 13, 2026

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

  • New buildV2FullRootCommit + ensureV2FullRoot helpers (cmd/entire/cli/checkpoint/v2_root.go).
  • ensureRef, when creating /full/current for the first time, parents it on /full/root instead of plumbing.ZeroHash.
  • RotateCurrentGenerationIfNeeded parents the post-rotation orphan-reset commit on /full/root instead of plumbing.ZeroHash.
  • /full/root is pushed alongside /main and /full/current. Deterministic SHA means concurrent pushes of /full/root from different clients send identical bytes — no non-fast-forward conflict surface.

The well-known SHA c095af40b171ff4c3c4a781abacd39aa499e183b is pinned in a test so any accidental change to the deterministic inputs is caught immediately.

What does NOT change

  • /main continues to use ZeroHash as its initial-commit parent (different namespace, no shared-ancestry expectation).
  • Existing archive refs from before this change are untouched; the star topology is established only for newly-created /full/current orphans and future rotations.
  • ListArchivedGenerations and cleanup retention already filter /full/root out 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:

  1. Add deterministic /full/root anchor commit for v2 checkpoints — introduces the helpers and ref name constant. No call sites change.
  2. Parent v2 orphan commits on /full/root — rewires ensureRef and RotateCurrentGenerationIfNeeded to parent on /full/root.
  3. Push /full/root with the v2 main and current refs — adds /full/root to the push ref list, ordered first so clones fetch the anchor before any descendant ref.

Test plan

  • mise run fmt && mise run lint passes
  • mise run test:ci passes (unit + integration + canary E2E)
  • Manually verify a fresh local repo creates /full/root with the well-known SHA on first checkpoint write
  • Manually verify an existing repo with pre-change archive refs continues to operate (no migration required)
  • Manually verify /full/root is pushed alongside /main and /full/current

🤖 Generated with Claude Code


Note

Medium Risk
Changes how v2 /full/current is 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/root anchor 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/root is 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/root is never treated as an archived generation.

Reviewed by Cursor Bugbot for commit 34c7ba7. Configure here.

Soph and others added 3 commits May 13, 2026 17:51
/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
Copilot AI review requested due to automatic review settings May 13, 2026 15:52
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/root anchor commit/ref.
  • Parent newly-created and post-rotation /full/current commits on /full/root instead of plumbing.ZeroHash.
  • Include /full/root in 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.

Comment thread cmd/entire/cli/strategy/push_v2.go Outdated
Comment thread cmd/entire/cli/paths/paths.go Outdated
Comment thread cmd/entire/cli/checkpoint/v2_root.go
Comment thread cmd/entire/cli/checkpoint/v2_root_test.go Outdated
Comment thread cmd/entire/cli/strategy/push_v2_test.go
@Soph Soph requested review from computermode and pfleidi May 13, 2026 16:00
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
@Soph Soph marked this pull request as ready for review May 13, 2026 16:07
@Soph Soph requested a review from a team as a code owner May 13, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants