Artifact 5a1adf7f9cca379898eba40264e53099ed2b2c55a28c4d5407dfc88ebfce50c2:
- File
conformance/rfcs/erratum/artifact-format-01-s4.6.4-julian-day-grammar.md
— part of check-in
[8cc3d7c5e4]
at
2026-10-13 02:23:50
on branch test/conformance-01-drafts
— test(conformance): check the -01 drafts of artifact, repo-state and sync
Re-pin the conformance suite to draft-fossil-artifact-format-01, draft-fossil-repo-state-01 and draft-fossil-sync-protocol-01, copied byte for byte from zit check-in 100351e26c. The delta format has no -01 and stays on -00. The -00 errata are folded into -01 and are no longer pinned; the six -01 errata are pinned for the fossil 2.28 behavior they record. conformance/rfcs/README.md records where each copy came from.
The requirement tables are re-read against -01, and new cases cover the date tag's event time (repo-state §4.2 step 6), the Julian-day grammar, a delta manifest naming a delta, dropped reserved F cards, the trailing-punctuation retry, truncated payloads, errors N, a file card after a refused push, the end of a request after a failed login, and the answer to a gimme for private content.
No library behavior changes. Where -01 departs from fossil 2.28 and go-libfossil follows fossil (a cancelled, unparsable or 0 date tag), the cases are marked as deviations. The non-conformances the re-pin exposes are marked as gaps, tracked in #370, #371, #372, #373, #374 and #375. (user: [email protected], size: 3501) [annotate] [blame] [check-ins using] [more...]
# Erratum — draft-fossil-artifact-format-01 §4.6.4 | | | |---|---| | **Document** | `draft-fossil-artifact-format-01` | | **Section** | 4.6.4 — Timestamps (form 5, the bare Julian day number) | | **Type** | Technical (the lexical form and the out-of-range outcome are unstated) | | **Status** | Applied in `draft-fossil-artifact-format-01` (2026-10-12) | | **Reported** | 2026-10-12 | | **Submitter** | Dan Mestas | | **Found via** | A reader implementing §4.6.4 from the text alone | ## 1. Summary Form 5 says a timestamp token may be "a bare decimal number, treated as a Julian day number when its value r satisfies 0 < r < 5373484.5". It does not say what spellings count as a bare decimal number, and it gives no outcome for a number outside that range: "treated as ... when" states a condition without saying what happens when the condition fails. ## 2. Location §4.6.4, item 5, and the "Finally:" paragraph after the field-constraint paragraph. ## 3. The reference behavior Verified against Fossil 2.28 by reading `src/manifest.c` and the bundled SQLite. The D and E card tokens are handed unchanged to the storage engine's `julianday()` function (`manifest.c:644`, `:660`), and the card is rejected when the result is not positive. That function recognizes a numeric token by its text-to-float conversion (`sqlite3AtoF`, `parseDateOrTime`): an optional sign, digits with an optional fraction, and an optional decimal exponent, in the forms `[+-]digits[E[+-]digits]`, `[+-]digits.[digits][E[+-]digits]` and `[+-].digits[E[+-]digits]`. Hexadecimal, infinity and NaN spellings are not numbers. The value is converted to whole milliseconds, `(i64)(r*86400000 + 0.5)` (`setRawDateNumber`), and kept only when that lies in `0 .. 464269060799999` (`validJulianDay`); otherwise the function yields no value and Fossil rejects the card. A value that rounds to 0 milliseconds passes the engine's check but fails Fossil's positivity test. The accepted range is therefore `0 < r < 5373484.5` measured after rounding to the millisecond: a positive value below about 5.8e-9 is rejected, and so is a value within about 6e-9 below 5373484.5. ## 4. Impact Observable. Two readers can disagree on whether `2.45e6`, `+2451545.5` or `.5` is a valid D card, and on whether `5373484.5` is rejected or read some other way. Fossil accepts the first three and rejects the fourth. ## 5. Correction ```diff 5. A bare decimal number, treated as a Julian day number when its - value r satisfies 0 < r < 5373484.5. + value r satisfies 0 < r < 5373484.5. The number is an optional + sign, then digits with an optional fraction (at least one digit + in all), then an optional decimal exponent introduced by E or e + with an optional sign, such as 2451545.5, +2451545, .5 or 2.45e6. + No other numeric spelling is recognized. A number whose value + is zero, negative, or 5373484.5 or more MUST be rejected. The + check is made on the value rounded to the nearest millisecond, + so a positive value that rounds to zero is rejected, as is a + value just below 5373484.5 that rounds up to it. ``` ## 6. Rationale The grammar is the engine's own, stated so a reader need not consult it. The rejection outcome is what Fossil does; without it the text leaves the over-limit case open. ## 7. Verification - Source: Fossil 2.28 `src/manifest.c:642-646` and `:656-662`; bundled SQLite `parseDateOrTime`, `setRawDateNumber`, `validJulianDay`, and the `sqlite3AtoF` contract.