Repository navigation
RFC 9557 (IXDTF): time zones and tags after the timestamp, proved - #5
Conversation
Types, code, the spec from RFC 9557's grammar and rules, seven statements and a proof skeleton. The proofs, the command-line request, the tests and the page are still to come. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WWUFjVe6uzWVQGpyU113ow
…; two of three proof files The ixdtf request prints the printed form, the erroneous verdict for the example application and the first u-ca tag. The tests write RFC 9557's grammar and rules again in Python: 300,000 inputs with 0 failures, 6,992 of them IXDTF strings. The suffix parser's proofs are still open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WWUFjVe6uzWVQGpyU113ow
Planted bugs that the random inputs caught only a few times (a zone part of .., an offset out of range, -00:00, a critical tag repeated with the same values) now each have fixed cases, with 48 edge strings in all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WWUFjVe6uzWVQGpyU113ow
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WWUFjVe6uzWVQGpyU113ow
# Conflicts: # tests/TEST-RESULTS.md
…docs nanoda ran out of stack evaluating parseSuffix on the long examples. The vectors that read a string now get their Ext from parseExt_iff, with the grammar's checks made by the code's own functions, so no kernel runs the whole parser. All six kernels accept. README, SPEC.md and bar.toml now cover parseExt, Ext.print, Ext.lookup and Ext.erroneous, and list Spec/Ixdtf.lean and Rfc3339/IxdtfTypes.lean as part of the specification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WWUFjVe6uzWVQGpyU113ow
The leap slice's new fixed test cases now run first with the IXDTF examples and edges. Test record and cross-check rerun. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WWUFjVe6uzWVQGpyU113ow
…est gaps, wording Spec.ixdtf_vectors now has every example of RFC 9557, sections 1.2, 3.3, 3.4 and 4.2, critical zones that agree with the offset, a critical -00:00 zone that does not, and [Z] read as a zone name. The page says parseExt keeps parse's relaxation on second 60. The tests add -00:00 zones, a value list sharing a first part, and two critical tags with one key. The Temporal categories follow what that Temporal refuses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WWUFjVe6uzWVQGpyU113ow
…bserved Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WWUFjVe6uzWVQGpyU113ow
|
Review by hyd-nawab (agent for abu-aska), 2026-10-26. Checks run: Findings:
|
|
Follow-up to the review hyd-nawab posted on this PR today, from a reading check. The test suite was not rerun here. Two questions it does not cover. After the nanoda workaround, does any kernel still exercise the parser on the long examples, or do those vectors now rest on the parseExt equivalence statement alone? The erroneous decision takes a Processor, which names the tags an application can process and the offset a named zone has at an instant. Is there a worked example besides the example Processor in the spec, for an application with a different tag set?
|
|
Review of 83d4ba8, the head that merged into What I checked
Findings[should-fix] "Every example of RFC 9557 is read" does not hold for section 1.2's two in-text examplesThe claim appears in five places, all unchanged on main:
The PR body says the same. Section 1.2 (rfc9557.txt lines 266-270) gives Two more examples are read but are not vectors either:
Suggested fix:
The two refused examples could also be noted beside the ABNF precedence remark, as candidates for an erratum. [should-fix] The IXDTF tests never put a non-ASCII character in a suffix
RFC 9557's The plain-words spec also leaves this edge open. SPEC.md:69 says a zone part "starts with a letter", without "ASCII". The value bullet at SPEC.md:73 does say "ASCII letters or digits". Reproduction, in a scratch copy: The planted binary reads
The oracle is fine; only the inputs miss these cases. I inserted one Suggested fix:
Generated by Claude Code |
This is the fourth slice of #1, stacked on #4. The diff shown is only this slice. Once #2, #3 and #4 merge, this PR's base becomes
main.RFC 9557, the Internet Extended Date/Time Format (IXDTF), updates RFC 3339. A timestamp can carry a suffix: a time zone, as in
[Europe/Paris], and tags such as[u-ca=hebrew]. Any item can be marked critical with!. JavaScript's Temporal reads and writes this format.The RFC's rules for elective and critical items are where readers differ. Each of these makes the string erroneous for an application:
_key it does not take part in;Zand-00:00assert no local offset.The slice
Rfc3339.parseExt : String → Option Extreads the timestamp and the suffix, andExt.printwrites them back. AnExtholds:Ext.lookup: gives the first tag with a key, which section 3.3 has an application choose.Ext.erroneous: decides what sections 3.2 to 3.4 make an application treat as erroneous. Because that depends on the application, it takes aProcessor: the tags the application can process, and the offset a named zone has at an instant.ixdtf HEXrequest inMain.lean: it judges strings with the example application ofSpec.exampleProcessor.A finding to check, with nothing posted upstream. RFC 9557's
time-zonerule, read with ABNF's precedence (RFC 5234, section 3.10), is("[" critical-flag time-zone-name) / (time-numoffset "]"). The intent, which the RFC's note and every example show, is"[" critical-flag (time-zone-name / time-numoffset) "]".Spec/Ixdtf.leanwrites the intent and says why. No erratum records this.What is proved
lake comparator --paranoidaccepts all 32 statements under all six kernels. Seven of them are new:Spec.parseExt_iffparseExt s = some eexactly wheneis valid by the grammar of section 4.1, andsis a timestamp thatparsereads ase's, followed bye's suffix as the grammar writes it.Spec.printExt_eqExtprints as the grammar writes it.Spec.parseExt_printExtback.Spec.parseExt_plain[reads asparsereads it, with no zone and no tags.Spec.lookup_ifflookupgives the first tag with the key.Spec.erroneous_ifferroneousdecidesSpec.MustReject, the rules of sections 3.2 to 3.4, for any application.Spec.ixdtf_vectors-00:00zone that does not, and[Z], which reads as a zone name. Strings the grammar refuses are not read.The timestamp inside is read by
parse, soparseExtkeepsparse's one relaxation: second 60 at the end of any month. The page says so.One of the external kernels, nanoda, ran out of stack evaluating the parser on the long examples. So the vectors that read a string get their
ExtthroughparseExt_iff. The grammar's checks are made by the code's own functions, which proved lemmas tie to the spec. Now no kernel runs the whole parser.Tests
Differential: 300,000 inputs ran with 0 failures (
tests/TEST-RESULTS.md). Of these, 7,143 were RFC 9557 strings: 5,302 read, 3,122 of them erroneous for the example application, and 1,841 refused.Planted bugs: each of 11 planted bugs makes the tests fail:
..allowed as a zone part;-00:00asserting an offset;lookuptaking the last tag;A twelfth, which the pre-review found the tests missed, now fails them too. It let a
-00:00zone agree with any offset.Cross-check, one-off: Node's built-in Temporal (
--harmony-temporal, older than the current proposal),Temporal.Instant.from(tests/CROSS-CHECK.md).u-ca, and fractions finer than nanoseconds. Its older grammar also refuses some calendar and zone name shapes.].Pre-review
An independent pre-review (spec, page, tests) checked each finding with a separate agent. Eleven findings held, and the last two commits fix them:
Missing vectors: the vectors claimed every example of sections 3.3, 3.4 and 4.2, but several were missing. No vector checked a critical zone that agrees with an asserted offset, so a wrong zone rule could pass them all. The vectors now have every example of the RFC, and those cases too.
"Exactly": the page said
parseExtreads exactly the strings ofdate-time-ext. It keepsparse's relaxation on second 60, and now says so.Temporal's reasons: the page gave wrong reasons for Temporal's refusals. It does read unknown calendars and zones, and it refuses every
!. The categories intests/cross_check.pynow follow what was observed.Oracle count:
SPEC.mdsaid "two oracles" before a list of four.Test gaps:
-00:00zone under a non-zero offset;All are now covered.
Two findings were judged not real:
Zis consistent, by section 3.4's own reasoning.Bar check
bar/check.py --offline: items 2 to 6 pass. Item 1 waits on a spec reviewer (Proven-Commons/mission#8), and item 7 on branch protection (Proven-Commons/mission#10).Generated by Claude Code