Artifact 3a8104565cb5d73c4b9ece3ad8ac7280ec4db95332343c7bafc90a8a45b0693f:
- File docs/rfcs/erratum/submanifests-00-s7.2-commits-during-the-session.md — part of check-in [1839e2b0da] at 2026-10-19 17:12:07 on branch trunk — submanifests §7.2, §8.1: define the sync session; avoid-submanifests binds commits created inside one and does not gate receipt (user: dmestas, size: 3697) [annotate] [blame] [check-ins using]
Erratum — draft-fossil-submanifests-00 §7.2 / §8.1
| Document | draft-fossil-submanifests-00 |
| Section | 7.2 — Peer Capability Gate (the client's duty after avoid-submanifests); 8.1 — Emission Gate (the same duty) |
| Type | Technical ("commits created during the session" names a situation neither implementation produces) |
| Status | Applied in draft-fossil-submanifests-00 (2026-10-19) |
| Reported | 2026-10-18 |
| Submitter | Dan Mestas |
| Found via | Implementing the pragma in go-libfossil and finding no code path the rule could apply to |
1. Summary
§7.2 says a client that received avoid-submanifests "MUST NOT emit S cards in commits created during the session", and §8.1 repeats the rule as "in a commit against a server from which it has received the avoid-submanifests pragma in the current sync session". Neither zit nor go-libfossil creates a commit inside a sync session: a commit is made, and then autosync pushes it in a separate exchange. The rule as written never applies, and the draft does not say what "session" means across a commit-then-push, so an implementer cannot tell whether a pragma received on yesterday's push binds today's commit. The text should define the session and say plainly what the pragma binds.
2. The text in error
§7.2: "A client receiving it MUST NOT emit S cards in commits created during the session (Section 8.1)."
§8.1: "and MUST NOT emit one in a commit against a server from which it has received the avoid-submanifests pragma in the current sync session (Section 7.2)."
3. What the implementations do
zit records the pragma in a per-session, one-way latch
(Client.avoid_submanifests in src/sync.zig) that a new session starts
clear, and reads it together with the setting in clientMayEmitSCards.
Its commit path runs outside any session, so the latch never reaches a
commit; emission is governed by the repository's own setting. A zit
server whose setting is false still stores an S-bearing artifact pushed
to it, because the setting gates emission, not receipt. go-libfossil
behaves the same way and recorded the rule as partially met (SM-7.2-3).
4. Corrected text
§7.2, replace the sentence with:
A sync session is one exchange between a client and a server, from its first request to its last reply. A client that receives the pragma MUST NOT emit S cards in a commit it creates during that session. A commit created outside a session is governed by the client's own enable-submanifests setting alone (Section 8.1); an implementation that commits first and pushes afterwards therefore never creates a commit the pragma binds, and the pragma informs it that the server's operator has not enabled emission there. The pragma does not gate receipt: a server stores an S-bearing artifact pushed to it whatever its setting, as Section 8.1 says of existing artifacts.
§8.1, replace "and MUST NOT emit one in a commit against a server from which it has received the avoid-submanifests pragma in the current sync session (Section 7.2)" with "and MUST NOT emit one in a commit created during a sync session in which it has received the avoid-submanifests pragma (Section 7.2)".
5. Observable consequence of the uncorrected text
An implementer can read the rule as binding every commit made while a server that sent the pragma is the autosync target, and build a writer that falls flat after one push to such a server, while zit and go-libfossil keep writing trees. The corrected text makes the two implementations' behaviour the specified one.
6. Implementations
zit and go-libfossil already behave this way; no change.