strategy: match checkpoint refs by one canonical key

Commit

Stefan Haubold3d ago

partitionLocalRefs now reports the spelling a checkpoint ref is stored under, which is what the git I/O needs but not what its callers compare. The waiting set was keyed by that stored name while waitingTargetSelection, missingCheckpointRefs and CheckpointWaiting all looked up the canonical one, so a checkpoint stored under its case-folded shard read as "not waiting". A targeted entire checkpoint push <id> skipped it even though the queue held it and --all would have sent it.

The same split ran through the reporting: checkpointPushOutcomes keyed pushed and changed by the stored name and read errors by the queued one, so a folded-shard checkpoint that did reach the remote was still reported as never sent.

Comparisons now go through canonicalCheckpointRefKey, which maps either shard spelling to the checkpoint's canonical ref name without touching the repository. That keeps one key for identity and leaves the choice of spelling for git I/O with resolveQueuedCheckpointRef, which is the only place that needs to know what exists on disk. partitionCheckpointRefPushes matches the selection by that key, so a ref queued under either spelling is still the one the user named.

CheckpointRefExists resolves before its lookup for the same reason. With it and CheckpointWaiting both answering false, session attach reported "checkpoint <id> was not found after it was written; run 'entire session attach' again" โ€” advice that could never succeed, because the ref was there under the other spelling the whole time.

The repository-level test packs the refs before reading them. Without that it passes on a case-insensitive filesystem for the wrong reason: a loose folded ref still answers to the canonical name there, and the bug is unconditional only once git packs it.

Refs #2402

Co-Authored-By: Claude Opus 5 noreply@anthropic.com Entire-Checkpoint: 01M6E7XKGV5XGAGSNY0RM3G4N4