Artifact c795f3b902131a91c524fbbf8977bd23412e4f69f6035d9a3f66683577fd9b4b:
- File
conformance/rfcs/erratum/artifact-format-00-s4.6.4-field-constraints-scope.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: 5119) [annotate] [blame] [check-ins using]
Erratum — draft-fossil-artifact-format-00 §4.6.4
| Document | draft-fossil-artifact-format-00 |
| Section | 4.6.4 — Timestamps (accepted parser grammar) |
| Type | Editorial (clarification — the field constraints are correct; their placement scopes them to the wrong form) |
| Status | Proposed — operator decision pending |
| Reported | 2026-10-08 |
| Submitter | Dan Mestas |
| Found via | libfossil conformance triage (artifact.4.6.4.invalid-month) + independent verification against the Fossil reference implementation |
1. Summary
§4.6.4 lists five token forms a parser accepts. The paragraph giving the field constraints (digit counts and ranges for year, month, day, hour, minute, second and fraction) is printed inside item 5, the bare-decimal Julian day number. Item 5 has none of those fields. Read literally, the constraints apply to nothing, and items 1 to 3 have no range checks at all. The constraints belong to the forms that carry those fields. This erratum moves the paragraph out of the list.
2. Location
§4.6.4 (Timestamps), list item 5 (~lines 1013-1019):
5. A bare decimal number, treated as a Julian day number when its
value r satisfies 0 < r < 5373484.5. Field constraints, with
exact digit counts: the year is exactly 4 digits, the month
exactly 2 digits in 01-12, the day exactly 2 digits in 01-31 with
no calendar-aware check (2024-02-31 is accepted), the hour 2
digits in 00-24, the minute and second 2 digits each in 00-59,
and the fraction one or more digits.
3. The reading hazard
The fields the constraints name exist only in items 1 to 3: year, month and
day in the date-time and date-only forms, hour, minute, second and fraction
in the date-time and time-only forms. Item 4 is a literal and item 5 is a
single number. Nesting the paragraph under item 5 gives a reader two wrong
choices: apply the ranges to the Julian-day form, where they cannot apply,
or treat items 1 to 3 as unconstrained and accept 2026-13-02T03:04:05.
The reference implementation applies the ranges to the date and time
fields. Verified with fossil test-parse-manifest (fossil 2.28):
D 2026-13-02T03:04:05is rejected ("cannot parse date on D-card").D 2026-01-02(date only) is accepted.
4. Impact
No wire-byte change and no change to which tokens are valid. The hazard is implementer-facing: an implementation that follows the list structure can skip the month and day range checks. libfossil's parser does, and it accepts the month-13 token above, which the reference implementation rejects.
5. Correction (editorial move)
End item 5 after its Julian-day sentence, and move the field constraints into their own paragraph after the list, naming the forms they govern:
5. A bare decimal number, treated as a Julian day number when its
- value r satisfies 0 < r < 5373484.5. Field constraints, with
- exact digit counts: the year is exactly 4 digits, the month
- exactly 2 digits in 01-12, the day exactly 2 digits in 01-31 with
- no calendar-aware check (2024-02-31 is accepted), the hour 2
- digits in 00-24, the minute and second 2 digits each in 00-59,
- and the fraction one or more digits.
+ value r satisfies 0 < r < 5373484.5.
+
+ In forms 1 through 3, each field present has exact digit counts and
+ ranges: the year is exactly 4 digits, the month exactly 2 digits in
+ 01-12, the day exactly 2 digits in 01-31 with no calendar-aware
+ check (2024-02-31 is accepted), the hour 2 digits in 00-24, the
+ minute and second 2 digits each in 00-59, and the fraction one or
+ more digits.
6. Rationale
- Scopes the constraints to the forms that have the fields. "In forms 1
through 3, each field present" says where they apply, so the Julian-day
form keeps only its own
0 < r < 5373484.5bound. - Leaves the constraint text unchanged. Only the placement and the lead-in change; every digit count and range is the same.
- Matches the reference implementation, which rejects an out-of-range month in a date-time token and accepts the date-only form.
7. Application and verification
- The libfossil conformance case
artifact.4.6.4.invalid-monthalready assumes the corrected reading: it expectsD 2026-13-02T03:04:05to be rejected. - Verified against the reference implementation (fossil 2.28,
test-parse-manifest):2026-13-02,2026-01-32,2026-01-32T03:04:05,2026-01-02T25:04:05and2026-01-02T03:60:05are rejected ("cannot parse date on D-card");2026-01-02,2026-01-02T03:04:05and the Julian-day number2461000.5are accepted.
Prepared against draft-fossil-artifact-format-00. The section is
substantively faithful; the correction is editorial. Surfaced when libfossil
conformance triage found its parser following the list structure literally.
The RFC remains the oracle; the reference implementation is used only to
confirm the correct observable behavior, per the interop-verification
policy.