Skip to content

fix: bootstrap metadata branch from checkpoint_remote during enable#1382

Draft
alishakawaguchi wants to merge 3 commits into
mainfrom
entire-enable-bug
Draft

fix: bootstrap metadata branch from checkpoint_remote during enable#1382
alishakawaguchi wants to merge 3 commits into
mainfrom
entire-enable-bug

Conversation

@alishakawaguchi
Copy link
Copy Markdown
Contributor

@alishakawaguchi alishakawaguchi commented Jun 5, 2026

Fixes #1374

Problem

When entire enable runs on a second device in a repo with a configured checkpoint_remote and an existing entire/checkpoints/v1 branch on that remote, it created a fresh empty orphan branch locally instead of fetching the existing one. Consequences:

  • entire checkpoint list returned 0 results (local ref exists but points at an empty tree, so the origin fallback never triggers)
  • git fetch <checkpoint-remote> entire/checkpoints/v1:entire/checkpoints/v1 was rejected as non-fast-forward (the orphan shares no ancestry with the real branch)

Root cause: EnsureMetadataBranch only consults the local ref and origin/entire/checkpoints/v1 before minting an empty orphan — it never consults the configured checkpoint_remote, even though entire resume already fetches from it first.

Fix

EnsureSetup now calls a new bootstrapMetadataFromCheckpointRemote before opening the repo handle: remote.Configuredremote.FetchURLfetchMetadataBranchIfMissing. Notes on placement and behavior:

  • In EnsureSetup, not EnsureMetadataBranch — covers both enable paths and the lifecycle hook path (lifecycle.go), keeps EnsureMetadataBranch a pure repo-handle function (existing unit tests call it with CWD = real repo, which itself has a checkpoint_remote configured — an in-function fetch would mutate the real repo during tests), and the repo handle opened afterward sees the freshly fetched packfiles
  • Before the handle is opened — avoids go-git's stale packfile cache after a CLI fetch
  • Best-effort and one-time — only fetches when the local branch is missing; failure (e.g. remote branch doesn't exist before the first push from any device) falls back to orphan creation as before, so device A's first enable is unchanged
  • fetchMetadataBranchIfMissing now returns (fetched bool, err error) so enable can print ✓ Created local branch 'entire/checkpoints/v1' from checkpoint remote

Testing

  • New regression test TestHTTPS_EnableBootstrapsMetadataFromCheckpointRemote (watched fail before the fix): device A pushes checkpoints to a separate HTTPS checkpoint remote; device B clones origin and runs entire enable via the real binary; asserts the local metadata branch tip equals the checkpoint remote tip and contains device A's checkpoint metadata
  • Strengthened existing fetchMetadataBranchIfMissing tests with the new fetched return assertions
  • mise run test:integration: 395/395 pass; E2E canary: all pass; mise run fmt && mise run lint: clean
  • Pre-existing unrelated failures in cmd/entire/cli unit tests (TestRunAuthStatus_RendersSessionsTable, TestExplainCmd_*) fail identically on the clean tree — environment-sensitive, not from this change

🤖 Generated with Claude Code


Note

Medium Risk
Changes shared setup/enable metadata initialization for multi-repo checkpoint routing; failures still fall back to orphan creation, but wrong fetch behavior could hide checkpoints or cause sync conflicts.

Overview
Fixes #1374: on a fresh clone with a separate checkpoint_remote, entire enable no longer creates an unrelated empty entire/checkpoints/v1 orphan when checkpoints only exist on that remote (not on origin).

EnsureSetup now runs bootstrapMetadataFromCheckpointRemote before opening the go-git repo handle: if a checkpoint remote is configured, it resolves the fetch URL and calls fetchMetadataBranchIfMissing so EnsureMetadataBranch sees real history instead of minting an empty branch. Bootstrap is best-effort (warnings + orphan fallback when the remote branch does not exist yet). When a fetch actually creates the local branch, enable prints ✓ Created local branch 'entire/checkpoints/v1' from checkpoint remote.

fetchMetadataBranchIfMissing returns (fetched bool, err error); callers (including push settings resolution) ignore the bool except for that message.

Tests: new HTTPS integration TestHTTPS_EnableBootstrapsMetadataFromCheckpointRemote (device A pushes to checkpoint remote; device B clones origin and runs enable; local tip and checkpoint metadata must match the remote). Unit tests assert the new fetched return value.

Reviewed by Cursor Bugbot for commit aa5169f. Configure here.

When a checkpoint_remote is configured and the repo is freshly cloned on a
second device, neither the local entire/checkpoints/v1 branch nor origin's
remote-tracking ref exists — the real branch lives on the checkpoint
remote. EnsureSetup previously went straight to EnsureMetadataBranch,
which minted an unrelated empty orphan, hiding existing checkpoints from
`entire checkpoint list` and rejecting later fetches as non-fast-forward.

EnsureSetup now fetches the metadata branch from the configured
checkpoint_remote first (best-effort, only when no local branch exists),
mirroring what `entire resume` already does. The fetch failing — e.g. the
remote branch doesn't exist before the first push from any device — falls
back to orphan creation as before.

Fixes #1374

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 5, 2026 21:41
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 fixes a multi-device enable/setup bug where a fresh clone with a configured checkpoint_remote would create an unrelated orphan entire/checkpoints/v1 locally instead of bootstrapping it from the checkpoint remote, which could hide existing checkpoints and later cause non-fast-forward fetch rejections.

Changes:

  • Run a best-effort metadata-branch bootstrap from checkpoint_remote during EnsureSetup before opening the main repo handle.
  • Extend fetchMetadataBranchIfMissing to return (fetched bool, err error) so callers can report when a local branch was created from a remote fetch.
  • Add/strengthen unit + integration regression coverage, including an HTTPS multi-remote enable test reproducing #1374.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
cmd/entire/cli/strategy/common.go Calls checkpoint-remote bootstrap during setup and clarifies EnsureMetadataBranch’s local-ref-only behavior.
cmd/entire/cli/strategy/checkpoint_remote.go Adds bootstrapMetadataFromCheckpointRemote and changes fetchMetadataBranchIfMissing to return a fetched boolean.
cmd/entire/cli/strategy/checkpoint_remote_test.go Updates tests to assert the new fetched return value in missing/no-op scenarios.
cmd/entire/cli/integration_test/http_remote_test.go Adds HTTPS regression test ensuring enable bootstraps metadata from checkpoint_remote instead of minting an orphan.

Comment thread cmd/entire/cli/strategy/checkpoint_remote.go Outdated
A first `entire enable` whose checkpoint-remote fetch fails (no token,
network down, remote branch not pushed yet) falls back to minting an
empty local orphan. fetchMetadataBranchIfMissing skipped the fetch
whenever the local branch existed, so that orphan permanently closed
the bootstrap window — a later enable with working auth (or after a
teammate's first checkpoint push) never recovered.

The skip-on-exists gate now exempts empty branches: a local metadata
branch with no checkpoint data no longer blocks the bootstrap fetch.
SafelyAdvanceLocalRef discards the no-op orphan commit during the
promote, so the local branch lands exactly on the remote tip.

Also log a warning when the bootstrap fetch fails instead of silently
swallowing it (auth/network problems were invisible in .entire/logs),
and fix the stale comment claiming promote errors are returned.

Follow-up to aa5169f (issue #1374).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alishakawaguchi alishakawaguchi self-assigned this Jun 5, 2026
Conflict in strategy/common.go: main renamed EnsureMetadataBranch to
EnsurePrimaryRef and rewrote it around refs.Primary. Kept main's
implementation plus this branch's doc note pointing at
bootstrapMetadataFromCheckpointRemote. Updated the recovery regression
test to call EnsurePrimaryRef.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

entire enable creates empty orphan entire/checkpoints/v1 instead of fetching from configured checkpoint_remote`

2 participants