be://) sync — reachability-based upload-pack, cross-file serving, redundant-pack GC
Make be:// keeper-to-keeper sync as efficient as git's own transport: the serving keeper should ship only the objects the requesting keeper lacks, across any number of pack files and divergent branches, and never let a shard accumulate duplicates. This is the umbrella ticket for the beagle-side upload-pack; GET-007 landed the first increment (5124b2ee: wire_locate_sha resolves to the LATEST copy, so the byte-offset watermark stops re-shipping duplicate tails for the common linear/dup-reingest case), but the watermark model is structurally a single contiguous byte-range of one log file — it cannot do reachability across files or exclude duplicates mid-range. The remaining work is to replace it with true object-level negotiation and to reclaim already-bloated shards. This is a be://-only concern: fetches from a git remote (ssh:/https:) use real git-upload-pack reachability and are unaffected. See GET, POST, GET-007, CLAUDE.
The beagle upload-pack (keeper/WIRE.c WIREBuildSegments/WIREServeUpload) prunes by a byte-offset watermark over one pack-log file, not by object reachability.
[watermark .. end_offset) of one .keeper file; it has no notion of closure(wants) − closure(haves). Any duplicate or unrelated object inside that range is shipped regardless of whether the client has it. GET-007's latest-copy fix tightens the anchor but not the model.file_id haves are dropped. if (hfid != want_fid) continue (WIRE.c:283) ignores a have in a different pack-log file, and the file-open hardcodes the trunk file (WIRE.c:308, wire_pack_path(…, want_fid)) — "multi-shard tba". A client whose common ancestor lives in an older file_id than the want gets no anchor → whole-log ship.WIREServeUpload sends one NAK then the pack (no multi_ack/ACK common), so the client cannot iteratively narrow the common set; the haves are a one-shot best-effort list capped at WIRE_MAX_HAVES.The keeper pack log is append-only; a reachability serve must build a fresh pack of only-missing objects (it cannot rely on a contiguous byte range). GC/compaction must also stay append-only-safe (write a new compacted pack/shard, swap, never mutate a live one mid-read). Decide whether to reuse git's pack-objects-style closure or implement over the keeper's LSM index + commit walk.
Replace the offset watermark with object-level negotiation; add cross-file serving and a compaction pass. Stage it.
5124b2ee): latest-copy wire_locate_sha so the watermark stops re-shipping duplicate tails on a clean linear log; re-fetch of an unchanged repo ships ~0. Regressions keeper/test/WIREREFETCH + WIREE2EREFETCH.WIREBuildSegments/WIREServeUpload to compute closure(wants) − closure(haves) using the existing KEEPIsAncestor/KEEPEmitCommitsSince/WALKTree primitives and emit a freshly-built pack of exactly the missing objects (handle thin-pack delta bases the client already has). Repro: divergent two-branch peers fetch only the disjoint objects; cross-file_id ancestor have prunes correctly. Drop the byte-watermark path once covered.be gc? a keeper maintenance verb) that rewrites a bloated shard into one deduplicated pack (dedup by full sha, not 60-bit hashlet — avoid the silent-drop risk noted in GET-007), append-only-safe (new shard, atomic swap). Repro: a polluted shard compacts back toward fresh-clone size.multi_ack/ACK common so large divergent fetches narrow iteratively instead of one-shot.be:// re-fetch transfers object-count ≈ git's minimal set; a fresh be:// clone's shard ≈ a fresh git clone's .git; assert in a load test. Update keeper/INDEX.md.