# git-refs: don't mask real errors as not-found; honor checkpoint policy on pre-push

`e99a03a`·

Soph·2w ago·4 files·+80 added/-20 removed

Addresses the open review threads on the git-refs store.

Error handling (was: any ref-resolution error treated as "missing"):
- refBase: only a plumbing.ErrReferenceNotFound starts a new orphan checkpoint;
a real lookup error (IO/corruption) is surfaced instead of silently
overwriting the ref's history.
- resolveRefMaybeFetch: a failed on-demand fetch (offline, network, ctx
cancellation) now returns the real error; only a genuinely absent ref (or a
successful fetch that finds nothing) resolves to not-found.
- checkpointTree / Read: distinguish ErrCheckpointNotFound (→ nil summary) from
real commit/tree/fetch errors, which now propagate instead of reading as
"checkpoint doesn't exist" (which risked silent data loss).
- partitionLocalRefs: a transient/IO error looking up a ref keeps it as pushable
(retried next pre-push) instead of dropping it from the queue as stale.

Pre-push policy (was: git-refs skipped the check the v1 path runs):
- prePushCheckpointRefs now calls syncCheckpointPolicyForPrePush first; a
diverged or unsupported-format checkpoint policy skips the ref push (leaving
refs queued), matching the v1 branch path. Policy governs checkpoint format
compatibility, which is independent of the storage backend.

Updates the fetch-failure test to assert the corrected contract (error
propagates; genuine absence still reads as not-found).

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

## Sessions

7c18df0a2b25View transcript

## Changes

4

- cmd/entire/cli

- checkpoint

- Mrefs_store.go+35/-10

- Mrefs_store_test.go+26/-7

- strategy

- Mmanual_commit_push.go+9

- Mpush_common.go+10/-3

```
78 unmodified lines

```

```

```

```

func (s *gitRefsStore) resolveRefMaybeFetch(ctx context.Context, cid id.CheckpointID) (*plumbing.Reference, error) {
refName, err := RefName(cid)
if err != nil {

```

```

```

```

```

if err != nil {
return plumbing.ZeroHash, nil, fmt.Errorf("resolve checkpoint ref %s: %w", refName, err)
}
commit, err := s.repo.CommitObject(ref.Hash())
if err != nil {

```

```

```

```

}

```

```

```

```

if s.refFetcher == nil {
return nil, err //nolint:wrapcheck // caller maps any error to ErrCheckpointNotFound

```

```

```

// sessionTree resolves the FetchingTree for one session within a checkpoint ref.

func (s *gitRefsStore) Read(ctx context.Context, checkpointID id.CheckpointID) (*CheckpointSummary, error) {
ct, err := s.checkpointTree(ctx, checkpointID)
if err != nil {
return nil, nil //nolint:nilnil,nilerr // No ref means no checkpoint exists
if errors.Is(err, ErrCheckpointNotFound) {
return nil, nil //nolint:nilnil // absent ref → no checkpoint; contract normalizes to ErrCheckpointNotFound
return nil, err
}
return readSummaryFromCheckpointTree(ct)
}
```

Mcmd/entire/cli/checkpoint/refs_store.go+35/-10

```

```

```

```

func TestGitRefsStore_OnDemandRefFetch_FailureIsNotFound(t *testing.T) {
// TestGitRefsStore_OnDemandRefFetch_FailurePropagates: a fetch that fails
// (offline, network error, context cancellation) must surface as a real error
// rather than be masked as "checkpoint not found" — otherwise a transient
// failure looks like missing data. A fetch that succeeds but still finds no such
// ref on the remote is a genuine not-found and reads as (nil, nil).

// TestGitRefsStore_WriteAllVariantsAndRead(t *testing.T) {
```

Mcmd/entire/cli/checkpoint/refs_store_test.go+26/-7

```

```

rating
