Artifact 78e82316c170f22e6932a90facd329ec9a49777e6d71d802cd2156810d9c9438:
- File
conformance/rfcs/erratum/sync-protocol-01-s9.4-avoid-delta-manifests.md
— part of check-in
[600861484f]
at
2026-10-13 15:55:30
on branch main
— test(conformance): re-pin the -01 drafts with the 2026-10-13 errata (#430)
* test(conformance): re-pin the -01 drafts with the 2026-10-13 errata
Re-pin the repo-state and sync-protocol drafts to zit check-in 5a1b741b25d8, which applies five more -01 errata: repo-state §5.3, §7.3 and §8.3, sync-protocol §9.4/§9.5 and §10.1. zit now keeps each -01 text under the -00 file name; the copies keep their -01 names and conformance/rfcs/README.md records the zit path and check-in. The new errata are pinned, and the requirement tables are re-read against every changed hunk.
The §7.3 and §8.3 cases that were deviations now pass as written, and new cases cover a date tag's arrival order (§5.3), untagged leaves and a merge parent's recheck (§7.3).
The sync server answers each guard-passing ci-lock with pragma avoid-delta-manifests while forbid-delta-manifests is on, defaulting to on as the draft and fossil 2.29 do (fossil 2.28 defaults it off). The client leaves its transfer unchanged on that pragma. A file or cfile whose content does not match its hash now fails the client's round, in a pull and a clone: the reply rolls back, prefix included, and no further round starts.
The leaf table is still recomputed per crosslink batch, so a parent whose untagged child arrives in a later batch loses the verdict §7.3 keeps; that case is marked as a gap, tracked in #426.
* fix(sync): continue after a uvfile content error; renumber the avoid-delta-manifests row
A uvfile whose content does not match its HASH is a handler-reported content error: warn, commit the prefix and follow ordinary continuation (sync-protocol-01 10.1). The avoid-delta-manifests client row is SP-9.5-7 now that share-links took SP-9.5-5 and SP-9.5-6. Older unreleased changelog entries drop the pending-erratum wording. (user: [email protected], size: 6673) [annotate] [blame] [check-ins using]
# Erratum — draft-fossil-sync-protocol-01 §9.4 / §9.5 | | | |---|---| | **Document** | `draft-fossil-sync-protocol-01` | | **Section** | 9.4 — Commit-Lock Pragmas (the server's reply to ci-lock); 9.5 — Private-Content and Discovery Pragmas (the avoid-delta-manifests paragraph) | | **Type** | Technical (§9.4 omits a reply the server sends to every ci-lock; §9.5 gives the client the wrong behavior) | | **Status** | Applied in `draft-fossil-sync-protocol-01` (2026-10-13) | | **Reported** | 2026-10-13 | | **Submitter** | Dan Mestas | | **Found via** | Reading Fossil 2.29's `page_xfer()` ci-lock handler; confirmed by posting ci-lock requests to Fossil 2.28 | ## 1. Summary §9.4 says that after `pragma ci-lock` the server emits `ci-lock-fail` on a conflict and otherwise "emits no lock result" and "no positive lock acknowledgement". Fossil's ci-lock handler also emits `pragma avoid-delta-manifests` whenever the server's `forbid-delta-manifests` setting is on, which is the default, whether or not the lock was granted. §9.4 does not mention it. The pragma is listed in §9 and described in the last paragraph of §9.5, but that description is wrong: it has the client change which artifacts it sends during the sync. In Fossil the pragma changes no transfer behavior. It makes the client's pending commit write a baseline manifest instead of a delta manifest. ## 2. Location §9.4, first paragraph, from "If its stored CLIENT-ID differs" to "a matching live row prevents a new row", and second paragraph, "It emits no positive lock acknowledgement."; §9.5, the paragraph beginning "avoid-delta-manifests is a server-to-client control pragma". ## 3. The reference behavior Verified against Fossil 2.29 source; behavior run on Fossil 2.28. - Server: the `pragma ci-lock` handler (`src/xfer.c:1781-1834`), after the conflict scan and the lock write, runs `if( db_get_boolean("forbid-delta-manifests",1) ){ @ pragma avoid-delta-manifests }` (`:1831-1833`). The test is outside the `seenFault` branch, so the pragma follows a `ci-lock-fail` as well as a granted or kept lock. It is emitted only by a ci-lock that passes the handler's guard (exactly four tokens, a hash-name third token, `:1781-1783`). - Setting: `forbid-delta-manifests` is a boolean, default on (`src/db.c:4899-4906`), and is a project setting that `fossil configuration` can sync (`src/configure.c:146`). - Client: the reply handler sets the process flag `g.bAvoidDeltaManifests = 1` (`src/xfer.c:2864-2871`) and does nothing else. The only reader is `commit` (`src/checkin.c:2788-2792`), which then sets `forceBaseline`, so the check-in is written as a baseline manifest even with `--delta`. The flag is not stored in the repository and is not consulted by the transfer code. - When it is sent: `commit` runs its pre-commit autosync with `SYNC_CKIN_LOCK` for a non-private commit on an existing check-out without `--allow-fork` or `--force` (`src/checkin.c:2758-2768`, and again at `:3033-3040`); the client sends `pragma ci-lock` in the first request of that sync only (`src/xfer.c:2184-2189`, `:2382-2388`). A plain `sync`, `push` or `pull` sends no ci-lock and so never receives the pragma. - Run (Fossil 2.28, `fossil http` with an uncompressed `/xfer` body): a ci-lock with no live lock is answered with `pragma avoid-delta-manifests` alone; a ci-lock from a second client ID with `pragma ci-lock-fail LOGIN MTIME` then `pragma avoid-delta-manifests`; with `forbid-delta-manifests` off, the first reply is empty and the second carries only the `ci-lock-fail`. ## 4. Impact Observable. A server written from §9.4 omits a card Fossil sends on every commit-time autosync. A client written from §9.5 alters its transfer and still writes a delta manifest that a `forbid-delta-manifests` server asked it to avoid. ## 5. Correction §9.4, first paragraph: ```diff refresh or replacement. If its stored CLIENT-ID differs from the request CLIENT-ID, the server emits pragma ci-lock-fail LOGIN MTIME; if it matches, it emits no lock result. In either case, a matching - live row prevents a new row. + live row prevents a new row. After this processing, whether or not + a lock was written, the server emits pragma avoid-delta-manifests + when its forbid-delta-manifests setting (default on) is true; when + ci-lock-fail is emitted, avoid-delta-manifests follows it. A ci- + lock that fails the handler's argument guard emits neither. ``` §9.4, second paragraph: ```diff - the current server login value, CLIENT-ID, and current MTIME. It - emits no positive lock acknowledgement. The transfer dispatcher + the current server login value, CLIENT-ID, and current MTIME. It + emits no positive lock acknowledgement; the avoid-delta-manifests + pragma above is not one. The transfer dispatcher ``` §9.5, the avoid-delta-manifests paragraph: ```diff - avoid-delta-manifests is a server-to-client control pragma. Upon - receipt, the client removes manifest-delta candidates from any not- - yet-dispatched seeded request and sends full manifests for the - remainder of the current sync session; it does not affect non- - manifest artifacts, already-dispatched data, or persisted repository - state. The flag resets when the session ends. + avoid-delta-manifests is a server-to-client pragma with no arguments, + sent only in reply to ci-lock (Section 9.4). It asks the client not + to create delta manifests (manifests with a B card, [FossilArtifact]) + for the commit that requested the lock. Upon receipt, a client that + is about to commit SHOULD write that check-in as a baseline manifest, + even if a delta manifest was requested. The pragma does not change + which artifacts the client sends or requests, does not affect + artifacts already created, and is not stored in the repository. ``` ## 6. Rationale Puts the reply where a server implementer reads the ci-lock handler, with the setting that gates it and its position after ci-lock-fail, and replaces the §9.5 behavior with the one Fossil has: a hint to the commit that triggered the lock, not a transfer rule. SHOULD rather than MUST, because a client that never writes delta manifests has nothing to do. ## 7. Verification - Source: Fossil 2.29 `src/xfer.c:1781-1834`, `:1831-1833`, `:2184-2189`, `:2382-2388`, `:2864-2871`; `src/checkin.c:2758-2768`, `:2788-2792`, `:3033-3040`; `src/db.c:4899-4906`; `src/configure.c:146`; `src/main.c:305`. - Run: Fossil 2.28 `fossil http` against a scratch repository, with `forbid-delta-manifests` on and off, giving the replies in Section 3.