Artifact 6ed3e12fff07b80711b28bd516b1d7a636924d305ade6a3e132929b0a8ef9e48:
- File
conformance/rfcs/erratum/sync-protocol-00-s3.3-content-received-flag.md
— part of check-in
[57a558fcbf]
at
2026-10-10 23:52:34
on branch trunk
— test(conformance): harness for an RFC conformance suite (#262) (#264)
Adds the conformance package that the per-draft suites build on. Nothing in the repository has yet checked go-libfossil against the Fossil drafts requirement by requirement.
- A Case names its requirement. A Gap (an issue) or Deviation (a reason) marks a known difference. A marked case still runs: while it fails it is skipped, and once it conforms it fails until the mark is removed, so the list of known failures cannot go stale. - Requirements tables pin the SHA-256 of the drafts and errata they were written against. Those are copied unmodified into conformance/rfcs by scripts/refresh-conformance-rfcs.sh. A changed draft fails the coverage test until its table has been re-read and its pin moved. - Coverage is derived from the cases rather than recorded: - COVERED: every case conforms. - PARTIAL: the table's row says what its cases leave out. - DEVIATION: a case is marked as a deliberate difference. - FAILING: a case is marked with an open gap. - GAP: no case yet.
CONFORMANCE_REPORT=<path> writes the requirement-by-requirement report as Markdown. - fossil(1) is run on every case's input, through test-parse-manifest, so a case's expectation is checked against fossil each time the suite runs. withZ appends the Z card, so a case that edits one card never also breaks the checksum.
The harness's own rules are tested in harness_self_test.go. No suites are registered yet; the artifact-format suite is next (#263). (user: [email protected], size: 5582) [annotate] [blame] [check-ins using]
# Erratum — draft-fossil-sync-protocol-00 §3.3 | | | |---|---| | **Document** | `draft-fossil-sync-protocol-00` | | **Section** | 3.3 — Phantoms and Deferred Reconstruction (dangling-delta receipt) | | **Type** | Editorial (clarification — the normative actions are correct; one phrase invites a wrong reading) | | **Status** | Proposed — operator decision pending | | **Reported** | 2026-07-10 | | **Submitter** | Dan Mestas | | **Found via** | zit conformance implementation (sync §9.3-r5) + independent verification against the Fossil reference implementation | ## 1. Summary §3.3 correctly specifies the actions a receiver takes when a `file`/`cfile` card delivers HASH's content as a delta against a DELTASRC it does not hold. But its closing sentence — "the content-received flag is set" — reads, in isolation, as if a per-artifact tri-state ("received but unreconstructed") must be recorded against HASH. No such per-artifact flag exists in the reference implementation: the "received-but-unreconstructed" condition is represented *implicitly*, and the "content-received" flag §3.3 refers to is the *per-round* termination flag defined elsewhere. This erratum adds a cross-reference and one clarifying sentence. ## 2. Location §3.3 (Phantoms and Deferred Reconstruction), the dangling-delta paragraph (~lines 599-604), specifically the sentence: "…the delta payload for HASH is stored as received, the phantom record for HASH is deleted, and the content-received flag is set." ## 3. The reading hazard The three states in play are: (1) phantom / never-received; (2) content received but not yet reconstructable (its delta basis is still a phantom); (3) fully resolved. A reader implementing §3.3 in isolation naturally asks "where do I record state 2 per artifact?" — because "the content-received flag is set" sounds like a per-HASH flag. It is not. The reference implementation records no such per-artifact flag. A phantom is a stored object with a negative size and a phantom-table row. On dangling-delta receipt, the delta bytes are stored as HASH's content (its size becomes non-negative) and HASH's phantom row is deleted, while a phantom is created for the missing DELTASRC. State 2 is therefore *implicit*: HASH is a stored object whose delta-basis chain still terminates at a phantom. "Reconstructable" is *derived* on demand by walking that chain, not stored. Re-request suppression is automatic: `gimme` eligibility is driven solely by the phantom set, and HASH is no longer in it. The "content-received flag" the sentence names is the **per-round** flag defined by the protocol state table ("set when any file or cfile card delivers stored content"), which feeds the §3.7 termination decision — not a per-artifact state. The single word "flag," unqualified, is what conflates the two. ## 4. Impact No wire-byte change and no defect in the specified actions — they match the reference implementation action-for-action. The hazard is implementer-facing: the phrasing invites a superfluous per-artifact tri-state (a store-model change) that the protocol neither needs nor uses, and can lead to divergent `gimme` re-request and termination timing if an implementer gates on a per-artifact flag rather than the phantom set. ## 5. Correction (additive clarification) Amend the closing sentence and append a clarifying sentence: ```diff - the delta payload for HASH is stored as received, the phantom record - for HASH is deleted, and the content-received flag is set. + the delta payload for HASH is stored as received, the phantom record + for HASH is deleted, and the per-round content-received flag of + Section 3.7 is set. No per-artifact "received" state is recorded: the + received-but-unreconstructed condition is represented implicitly by the + stored delta payload whose basis remains a phantom, and a receiver + suppresses re-requests for HASH solely by removing it from the phantom + set. Reconstructability is derived when the basis arrives, not stored. ``` ## 6. Rationale - **Names the flag's scope.** "content-received flag" becomes "the per-round content-received flag of §3.7," removing the per-artifact reading. - **States the representation the reference implementation actually uses** — implicit via a stored delta over a phantom basis — so implementers do not add a store-model tri-state the protocol never requires. - **Ties re-request suppression to the phantom set**, which is where the reference implementation drives `gimme` eligibility. ## 7. Application and verification - The zit reference implementation keeps its artifact store binary (phantom / present) and derives the content-received condition at the sync layer from the stored/pending delta state, driving `gimme` eligibility from the phantom set — mirroring the reference implementation's design. - Verified by the §9.3 tests: a dangling-delta receipt removes HASH from the re-request set without introducing a per-artifact state, and `gimme` for HASH is not re-emitted while its DELTASRC is pending. --- *Prepared against `draft-fossil-sync-protocol-00`. Substantively faithful section; the correction is editorial. Surfaced when the zit port's §9.3 implementation and independent verification against the reference implementation showed the "content-received flag" phrasing invited a per-artifact tri-state the protocol does not use. The RFC remains the oracle; the reference implementation is used only to confirm the correct observable behavior, per the interop-verification policy.*