ADR 0015: Add ICU Authoring Diagnostics Without Owning Runtime Formatting
Accepted architecture decision record: icu authoring diagnostics.
ADR 0015: Add ICU Authoring Diagnostics Without Owning Runtime Formatting
- Status: Accepted
- Date: 2026-05-12
Context
Ferrocat already treats ICU MessageFormat v1 as the native semantic center for modern catalog workflows. The existing parser validates syntax and exposes a compact AST, and runtime artifact compilation validates final ICU strings.
The next useful product layer is not a full formatter. Teams need earlier authoring feedback while catalogs are still being reviewed or packaged:
- source and translation argument sets should stay compatible
- formatter kinds and styles should not drift silently
- rich-text tags should remain balanced and available
- select and plural structures should preserve required source branches
- opaque number/date/time pattern styles should be visible because ICU recommends predefined styles or skeletons for portable formatting
ICU MessageFormat 2 is visible and important, but it is not a current Ferrocat
implementation target. ICU still documents its MessageFormatter surface as a
Technical Preview successor to the long-standing MessageFormat API, and ICU's
own guide notes that implementation support may lag the MF2 specification in
early releases. For Ferrocat's catalog layer, the immediate product value is
also not urgent enough to justify taking on a second message syntax now: MF1
already covers the practical plural/select/formatter workflows users are most
likely to need, and authoring diagnostics around MF1 close the more immediate
quality gap.
Decision
Add host-neutral ICU authoring diagnostics around MessageFormat v1.
Concretely:
ferrocat-icuexposes structural analysis helpers for arguments, formatters, plurals, selects, and rich-text tags.ferrocat-icuexposes source/translation compatibility checks with stable diagnostic codes.ferrocat-poartifact compilation can opt into those checks withicu_compatibility.- syntax validation remains separate:
strict_icustill controls whether an invalid final ICU string is a hard compile error. - Ferrocat does not format locale-aware runtime output for number, date, time, list, or plural values.
- Ferrocat does not implement MessageFormat 2 parsing, conversion, validation, or runtime formatting in this phase.
MF2 should only be reconsidered when there is a stable, widely deployed implementation surface that materially improves Ferrocat's catalog workflows over MF1 plus diagnostics. A future MF2 investigation should start with a new ADR instead of being added implicitly to the existing ICU parser.
Consequences
Positive:
- catalog CI can catch risky ICU translation drift before runtime packaging.
- Palamedes and other host adapters can reuse one diagnostic contract instead of reimplementing ICU QA.
- Ferrocat's runtime artifact boundary gets stronger without becoming a framework runtime.
- MF2 remains a deliberate future decision instead of scope creep inside the current ICU parser.
Negative:
- the public ICU API surface grows.
- compatibility checks are structural and conservative, not a proof that a translated sentence is linguistically correct.
- callers that want full runtime formatting still need a host/runtime layer.
Alternatives Considered
Implement a Full ICU Runtime Formatter
Rejected because locale-aware formatting would pull Ferrocat into CLDR data loading, formatter lifecycles, number/date/time skeleton semantics, BiDi policy, and host-specific output handling. That belongs above the catalog layer.
Wait for MessageFormat 2
Rejected because the practical MF1 authoring problems exist today and can be handled without committing Ferrocat to MF2 syntax or runtime semantics. Even though MF2 is promising, the current Ferrocat value proposition does not depend on it: catalog teams get more near-term benefit from MF1 compatibility checks, artifact diagnostics, conformance growth, and clear Palamedes handoff points.
Keep ICU Checks in Palamedes Only
Rejected because the checks are catalog semantics and should stay available to Rust users and non-Palamedes host adapters.