Skip to content

feat(checkpoint): discover refs-native checkpoints on a second device via List remote enumeration#1771

Open
suhaanthayyil wants to merge 4 commits into
mainfrom
fix/1770-git-refs-remote-list-discovery
Open

feat(checkpoint): discover refs-native checkpoints on a second device via List remote enumeration#1771
suhaanthayyil wants to merge 4 commits into
mainfrom
fix/1770-git-refs-remote-list-discovery

Conversation

@suhaanthayyil

@suhaanthayyil suhaanthayyil commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

https://entire.io/gh/entireio/cli/trails/871

Problem

Under a git-refs primary, a second device running entire checkpoint list shows 0 refs-native checkpoints:

  • storage-level List enumerates local refs only;
  • the on-demand ref fetcher is ID-keyed — it can fetch a checkpoint you already know, not discover what exists.

PR #1719 fixed this for the git-branch backend by fetching/healing the entire/checkpoints/v1 branch, but refs-native checkpoints don't live on that branch, so the "device B sees zero" symptom survives under git-refs. This is a pure discovery problem (reads-by-ID already work), and it must land before git-refs becomes the default primary.

Approach

Add opt-in remote discovery to the git-refs List, per the issue's preferred direction (List-time ls-remote, hydrate lazily on read):

  • gitRefsStore.List gains a RemoteRefListFunc seam. When the context is marked WithRemoteListDiscovery and a lister is configured, List runs a single git ls-remote 'refs/entire/checkpoints/*'names only, no object transfer — and appends checkpoints that exist on the remote but have no local ref yet.
  • Each discovered checkpoint's CreatedAt is recovered from its ULID timestamp (via a new id.CheckpointID.Time()), so it sorts by real recency with no fetch; the rest of its contents hydrate lazily on the next read through the existing ID-keyed on-demand fetch.
  • The CLI lister ListCheckpointRefsOnRemote resolves the target with the same authority rule as fix(enable): fetch existing checkpoint_remote branch instead of orphan #1719: with a checkpoint_remote configured it enumerates that remote, never origin; with none configured it is a no-op, so List stays local-only and default behavior is unchanged.
  • Wired into the user-facing enumeration path (entire checkpoint list / the branch explain view) only; the marker keeps the per-turn commit-hook hot path network-free.
  • Discovery is best-effort and additive: an ls-remote failure logs and returns the local results rather than failing the listing.

Files

  • checkpoint/refs_store.goRemoteRefListFunc field/setter, WithRemoteListDiscovery marker, discovery in List.
  • checkpoint/fetching_tree.go, open.go, registry.go — the lister type + wiring through OpenOptions/OpenEnv.
  • checkpoint/id/id.goCheckpointID.Time() (ULID → creation time).
  • cli/git_operations.goListCheckpointRefsOnRemote + parseCheckpointRefNames (authority-scoped ls-remote).
  • cli/explain.go — opt getBranchCheckpoints into discovery.
  • docs/architecture/ref-checkpoint-backend.md — document List + remote discovery.

Test plan

  • checkpoint store tests: discovery surfaces a remote-only checkpoint when opted in; stays local-only without the marker / without a lister; no duplicate for a locally-present ref; enumeration failure degrades to local-only; routing store surfaces discovery through the union List.
  • id test: Time() recovers a ULID's creation instant and reports false for legacy/non-ID strings.
  • cli tests: parseCheckpointRefNames filters real git ls-remote 'refs/entire/checkpoints/*' output (incl. HEAD/branches/peeled tags); ListCheckpointRefsOnRemote is a no-op with no checkpoint_remote configured (behavior unchanged, never scans origin).
  • Full ./cmd/entire/cli/... unit tests green; golangci-lint clean on touched packages.

Closes #1770

Made with Cursor

Under a git-refs primary, a second device running `entire checkpoint
list` saw zero refs-native checkpoints: storage-level List enumerated
local refs only, and the on-demand ref fetcher is ID-keyed (it can fetch
a known checkpoint, not discover which exist). PR #1719 healed this for
the git-branch backend by fetching the v1 metadata branch, but refs-
native checkpoints do not live on that branch, so the symptom survived.

Add opt-in remote discovery to the git-refs List: when the context is
marked with WithRemoteListDiscovery and a remote lister is configured,
List runs a single `git ls-remote refs/entire/checkpoints/*` (names
only, no object transfer) and surfaces checkpoints that exist on the
remote but have no local ref yet. Each discovered checkpoint's CreatedAt
is recovered from its ULID timestamp so it sorts correctly, and its
contents are hydrated lazily on the next read via the existing ID-keyed
fetch.

Enumeration follows the same authority rule as #1719: with a
checkpoint_remote configured it queries that remote, never origin; with
none configured it is a no-op, so List stays local-only and default
behavior is unchanged. The discovery marker is set only on user-facing
enumeration (`checkpoint list` / the branch `explain` view), never the
per-turn commit hook, so the hot path stays network-free. Enumeration
is best-effort: an ls-remote failure logs and returns the local list.

Closes #1770

Co-authored-by: Cursor <cursoragent@cursor.com>
@suhaanthayyil
suhaanthayyil requested a review from a team as a code owner July 15, 2026 22:21
Copilot AI review requested due to automatic review settings July 15, 2026 22:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 adds opt-in remote discovery for the git-refs checkpoint backend so that a second device can discover refs-native checkpoints that exist only on the configured checkpoint_remote, without fetching checkpoint objects up front. It extends the checkpoint store interface via a remote-ref listing seam, recovers CreatedAt from ULID timestamps for correct sorting, and wires the feature into user-facing enumeration paths (while keeping hook hot paths network-free).

Changes:

  • Add a RemoteRefListFunc seam and WithRemoteListDiscovery context marker so gitRefsStore.List can enumerate remote checkpoint refs via a single git ls-remote (names only) and append remote-only checkpoints for lazy hydration.
  • Add CheckpointID.Time() (ULID timestamp recovery) to support correct recency sorting for remote-discovered (not-yet-hydrated) checkpoints.
  • Wire remote ref listing through checkpoint.Open(...) and enable discovery for the branch explain view; add docs + tests covering discovery, parsing, and routing-store behavior.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/architecture/ref-checkpoint-backend.md Documents storage-level List behavior and the new opt-in remote discovery flow.
cmd/entire/cli/git_operations.go Adds ListCheckpointRefsOnRemote and parseCheckpointRefNames for checkpoint-remote-scoped ls-remote enumeration.
cmd/entire/cli/git_operations_test.go Adds unit + “real ls-remote” tests for parsing and authority gating behavior.
cmd/entire/cli/explain.go Opts user-facing branch explain enumeration into remote discovery via WithRemoteListDiscovery.
cmd/entire/cli/checkpoint/routing_store_test.go Verifies discovery flows through the routing store union listing.
cmd/entire/cli/checkpoint/registry.go Threads RemoteRefLister through the backend factory env wiring.
cmd/entire/cli/checkpoint/refs_store.go Implements remote discovery in List and context marker helpers.
cmd/entire/cli/checkpoint/refs_store_test.go Adds coverage for discovery opt-in behavior, dedupe, and best-effort failure handling.
cmd/entire/cli/checkpoint/open.go Adds OpenOptions.RemoteRefLister and passes it through to backend construction.
cmd/entire/cli/checkpoint/id/id.go Adds CheckpointID.Time() to recover creation time from ULIDs.
cmd/entire/cli/checkpoint/id/id_test.go Adds tests for CheckpointID.Time().
cmd/entire/cli/checkpoint/fetching_tree.go Introduces the RemoteRefListFunc type used by the git-refs store.

Comment thread cmd/entire/cli/checkpoint/id/id_test.go
Comment thread cmd/entire/cli/git_operations.go Outdated
suhaanthayyil and others added 3 commits July 15, 2026 18:55
Shorten ls-remote discovery timeout to 5s, pin FetchURL/ls-remote to the
worktree root, and mint the ULID Time() fixture with deterministic entropy.

Co-authored-by: Cursor <cursoragent@cursor.com>
Names-only remote-discovered CheckpointInfos left SessionID empty, so
`entire checkpoint list --session` silently dropped the second-device
checkpoints this path is meant to surface. Hydrate on collect (and match
archived SessionIDs in the human list filter).

Co-authored-by: Cursor <cursoragent@cursor.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.

git-refs: complete #1374's intent — second device can't discover refs-native checkpoints

2 participants