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
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-646and:656-662; bundled SQLiteparseDateOrTime,setRawDateNumber,validJulianDay, and thesqlite3AtoFcontract.