Skip to content
zit Erratum — draft-fossil-sync-protocol-00 §8.6 / §3.7(c)
Login

Erratum — draft-fossil-sync-protocol-00 §8.6 / §3.7(c)

Document draft-fossil-sync-protocol-00
Section 8.6 — Announcement and Request Cards; 3.7 — Loop Termination, limb (c)
Type Technical (correction — the draft attaches the peer-date gate and the extra round to the wrong private igot)
Status Proposed — operator decision pending
Reported 2026-10-11
Submitter Dan Mestas
Found via go-libfossil's conformance suite against Fossil 2.28 (GAP rows SP-3.7-3 and SP-8.6-1); confirmed by reading Fossil's source and by running a Fossil client against a scripted peer

1. Summary

Fossil sends igot HASH 1 from two different places, and the draft merges them:

  1. Private-sync inventory. With private sync on, the client lists every private artifact as igot HASH 1 in every push-carrying request, starting with the first. There is no peer-date check, nothing is held until server-version arrives, and these cards never cause another round.
  2. Private answer to a gimme. With private sync off, a side asked for an artifact it holds as private answers with igot HASH 1 instead of the content, but only when the peer's date is 2020-04-13 or later. On the client, an answer appended while processing the first reply is what buys the one extra round.

§8.6 applies the date gate and the hold-until-server-version rule to (1). §3.7(c) ties the extra round to (1) as well. Fossil does neither.

2. Location

§8.6 (~lines 1751-1760):

For peer dates before 2020-04-13, omit private igot entirely rather than sending flag 1. Until server-version establishes the peer date, hold local private inventory; if the reply establishes a date on or after 2020-04-13, append the eligible private igot cards to that reply's next-request buffer, and let Section 3.7(c) dispatch that buffer.

§3.7(c) (~lines 588-594):

The current request emitted at least one private igot HASH 1 and the post-increment round number is exactly 1, or processing server-version in this reply made private inventory eligible and the post-reply remaining-inventory step appended at least one such igot. …

3. The divergence

Source, Fossil 2.28 (src/xfer.c):

Runs, Fossil 2.28 client with one private check-in, against a scripted peer:

Command Peer's first reply Observed
fossil sync --private server-version … 20260311 …, nothing else request 1 carries both igot HASH 1 cards; 1 round
fossil sync --private server-version 21000 20190101 000000, igot NEW request 1 and request 2 both carry the private igots (peer dated 2019)
fossil sync server-version … 20260311 …, gimme PRIVHASH request 2 carries igot PRIVHASH 1; 2 rounds
fossil sync server-version 21000 20190101 000000, gimme PRIVHASH no private igot; 1 round

4. Impact

5. Correction

-   igot HASH announces public possession; igot HASH 1 private
-   possession; gimme HASH requests content.  Section 3.3 governs.  No
-   ordering constraint exists between igot and gimme.  For peer dates
-   before 2020-04-13, omit private igot entirely rather than sending
-   flag 1.  Until server-version establishes the peer date, hold local
-   private inventory; if the reply establishes a date on or after
-   2020-04-13, append the eligible private igot cards to that reply's
-   next-request buffer, and let Section 3.7(c) dispatch that buffer.
+   igot HASH announces public possession; igot HASH 1 private
+   possession; gimme HASH requests content.  Section 3.3 governs.  No
+   ordering constraint exists between igot and gimme.  When private
+   sync is in effect, a client lists its private inventory as igot
+   HASH 1 in every request that carries push, starting with the first,
+   and a server lists its own in every pull or clone reply; no peer
+   date is consulted.  When private sync is not in effect, a
+   gimme for content held as private is answered with igot HASH 1 only
+   if the peer's date is 2020-04-13 or later; for an earlier or unknown
+   date, send nothing for it.
-   *(c)* The current request emitted at least one private igot HASH 1
-   and the post-increment round number is exactly 1, *or* processing
-   server-version in this reply made private inventory eligible and the
-   post-reply remaining-inventory step appended at least one such igot.
-   The latter continuation dispatches the newly appended first private
-   inventory exactly once; the former permits only one first-cycle
-   discovery continuation.
+   *(c)* The post-increment round number is exactly 1 and processing
+   this reply appended at least one igot HASH 1 answering a gimme
+   (Section 8.6, private sync not in effect).  Private-inventory igot
+   cards sent under private sync never satisfy this condition.

6. Rationale

7. Verification


Prepared against draft-fossil-sync-protocol-00. The RFC remains the oracle; the reference implementation is used only to confirm the observable behavior.