fix: resolve RFC 9557 compliance findings from expert review - #26
Conversation
Address all findings from the v0.4.0 pre-release spec review: - Serialize offset time zones in the RFC 3339 form: keep "+09:00" as the FixedZone name instead of Go's "+0900" convention, so Parse -> Format -> Parse round-trips offset annotations per RFC 9557 Section 1.2 and the Section 4.1 time-numoffset grammar. Previously Format emitted "[+0900]", which strict re-parsing rejected and non-strict re-parsing silently dropped. - Reject duplicate suffix keys when either occurrence is critical (ErrCriticalExtension) per the Section 3.3 MUST; elective duplicates still keep the first occurrence. Previously the second occurrence was silently ignored and its "!" flag lost. - Reject unrecognized critical suffix keys (only "u-ca" is understood) in strict mode per Section 3.3; non-strict mode keeps delegating to the caller via the Critical map, now documented in the README. - Enforce the Section 4.1 grammar "suffix = [time-zone] *suffix-tag": a second time-zone annotation is rejected even when the first was an unknown zone ignored by a non-strict parse, and a time-zone annotation after a suffix tag is rejected in both modes. Tracking moved from ext.Location (nil for ignored zones) to explicit parse state. - Apply the critical "!" flag to the fallback zone taken from the timestamp when ext.Location is unset, instead of rejecting; Format still errors when no zone is available at all. - Add ParseError.Unwrap so sentinel errors match with errors.Is. Tests now cover the RFC's own Section 3.3 example strings ([!u-ca=chinese][u-ca=japanese], [u-ca=chinese][!u-ca=japanese], [!knort=blargel]), the Section 1.2 offset example (+08:45[+08:45]), and offset-annotation round trips including the critical variant. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #26 +/- ##
==========================================
- Coverage 94.76% 94.45% -0.31%
==========================================
Files 1 1
Lines 382 397 +15
==========================================
+ Hits 362 375 +13
- Misses 12 13 +1
- Partials 8 9 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@codex review |
There was a problem hiding this comment.
Pull request overview
This PR addresses RFC 9557 compliance findings for IXDTF parsing/formatting, including stricter grammar enforcement for suffix ordering/duplication rules, correct offset time-zone serialization, and improved error interoperability via ParseError.Unwrap.
Changes:
- Fix offset time-zone annotation round-tripping by preserving RFC 3339
+HH:MMform as theFixedZonename and updating offset-name detection accordingly. - Enforce RFC 9557 §4.1 suffix grammar (single time-zone annotation, must precede tags) and RFC 9557 §3.3 handling for critical duplicate/unknown keys.
- Add spec-conformance tests (round trips, ordering violations,
errors.IsviaParseError.Unwrap) and document strict vs non-strict critical-tag responsibilities in the README.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| README.md | Documents strict/non-strict responsibility for unknown critical tags and clarifies offset-annotation behavior and suffix ordering constraints. |
| ixdtf.go | Implements RFC 9557 compliance fixes: offset zone naming, stricter suffix parsing state, critical-key duplicate/unknown handling, and ParseError.Unwrap. |
| ixdtf_test.go | Adds/updates tests for offset annotation round-trips, suffix ordering errors, critical duplicates/unknown critical keys, and errors.Is behavior. |
| ixdtf_internal_test.go | Removes tests tied to the deleted formatOffsetName and updates offset-name detection expectations and parser helper callsites. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
Fixes all findings from the v0.4.0 pre-release RFC 9557 compliance review (blocking PR #25):
Formatemitted offset zones as[+0900](RFC grammar violation, round-trip loss)+09:00as theFixedZonename (RFC 9557 §1.2 serialization);formatOffsetNameremovedErrCriticalExtensionwhen either occurrence is criticalu-ca; non-strict delegation viaCriticalmap documented in READMEseenTimezone) decoupled fromext.Locationsuffix = [time-zone] *suffix-tagordering unenforcedErrInvalidSuffixin both modesFormatrejectedCriticalLocationeven when the timestamp's own zone would be emittedParseErrorlackedUnwraperrors.IsSpec-conformance tests added
[!u-ca=chinese][u-ca=japanese],[u-ca=chinese][!u-ca=japanese],[!knort=blargel]2022-07-08T00:14:07+08:45[+08:45]errors.Ismatching throughParseError.UnwrapVerification
go test -race ./...passes (all packages)golangci-lint run: 0 issuesgo vet,gofmt: clean🤖 Generated with Claude Code