Skip to content
zit Artifact [4010c8ea75]
Login

Artifact [4010c8ea75]

Artifact 4010c8ea75ba23bb63ac0923fea2403ad3213f8852348c062d4d56b5615361cd:


Erratum — draft-fossil-sync-protocol-00 §7.4

Document draft-fossil-sync-protocol-00
Section 7.4 — Delta Sources and Phantom Creation
Type Technical (correction — the draft forbids a side effect that Fossil always produces)
Status Proposed — operator decision pending
Reported 2026-10-11
Submitter Dan Mestas
Found via go-libfossil's conformance suite against Fossil 2.28 (scope note SP-7.4-1, cases sync.7.4.verified-duplicate and sync.7.4.verified-duplicate-server); confirmed by reading Fossil's source and by pushing it a duplicate delta

1. Summary

§7.4 says a receiver MUST first check whether a delta card's HASH is already verified locally and, if so, MUST NOT create a DELTASRC phantom. Fossil does the opposite order: it resolves DELTASRC, creating a phantom when it is absent, before the storage call notices that HASH is a duplicate. The verified target is left untouched, as the draft says, but the source phantom stays, and the receiver then asks the peer for it with gimme.

The 29 July copy of the draft described Fossil correctly here ("Fossil resolves or creates the DELTASRC record before the storage operation can detect that HASH already names a locally verified artifact"). zit's draft replaced that paragraph with the check-first MUST, which every Fossil peer violates.

2. Location

§7.4, first paragraph (~lines 1313-1317):

Before delta-source handling, a receiver MUST check whether HASH already names a locally verified artifact. If so, it consumes and ignores the duplicate card's payload; it MUST NOT replace or downgrade the verified target, create a DELTASRC phantom, or enqueue an edge.

3. The divergence

Source, Fossil 2.28:

Run: a fossil new repository, nobody given gioz. Its initial check-in manifest A (7ea4a5db…) is stored. A delta from an unrelated, absent text U (01256859…) to A was built with fossil test-delta-create and pushed as push 0000 PROJECTCODE / file A U SIZE through fossil http as application/x-fossil-debug. The reply contains gimme 01256859… with errors 0; afterwards blob holds U with size -1 and phantom holds its rid. A is unchanged.

4. Impact

Small and self-healing.

5. Correction

Restore the 29 July description of Fossil, and keep check-first as a permission rather than a requirement:

-   Before delta-source handling, a receiver MUST check whether HASH
-   already names a locally verified artifact.  If so, it consumes and
-   ignores the duplicate card's payload; it MUST NOT replace or
-   downgrade the verified target, create a DELTASRC phantom, or enqueue
-   an edge.
+   If HASH already names a locally verified artifact, the receiver
+   consumes and ignores the duplicate card's payload and MUST NOT
+   replace or downgrade the verified target.  For a delta-form file or
+   cfile, Fossil resolves or creates the DELTASRC record before its
+   storage operation detects the duplicate, so an absent DELTASRC is
+   left behind as a phantom and is requested by a later gimme.  A
+   receiver MAY check HASH first and skip delta-source handling; peers
+   MUST tolerate either behavior.

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.