Lenient Parser with Canonicalizer¶
Tolerant-reader tool — instantiates Asymmetric Interface Tolerance Calibration
A tolerant front-door parser that accepts a wide envelope of input variants and reduces each to a single canonical form before anything downstream sees it.
A Lenient Parser with Canonicalizer is a receiver's front door: it accepts a deliberately wide envelope of input variants — different casings, orderings, encodings, near-miss formats — and reduces each to one canonical form before anything downstream sees it. Its defining move is to make the receiver liberal in what it accepts while keeping everything behind it strict and uniform, because the canonicalizer collapses the accepted variety to a single shape. It is the concrete embodiment of the "tolerant reader" half of Postel's principle. It differs from the Adapter or Translation Shim in what it spans: the parser tolerates variants of one contract at its own door, not translation between two distinct contracts.
Example¶
A scheduling API must ingest dates from many clients: 2026-07-23, 07/23/2026, 23 Jul 2026, 2026-07-23T14:00Z, even today+3d. A lenient parser accepts all of them, then canonicalizes every one to a single internal form — RFC 3339 UTC timestamps — so every downstream component sees exactly one date shape and never has to branch on format. When it meets genuine ambiguity — 04/05/2026, which is April 5 or May 4 depending on locale — it does not guess: it spends from its ambiguity budget by rejecting with a diagnostic rather than silently picking a meaning. Setup to outcome: broad, forgiving intake at the edge; strict, uniform data everywhere inside.
How it works¶
- It defines an explicit envelope of what it will accept — broad, but bounded and written down, not "anything at all."
- It normalizes every accepted variant to one canonical output, so the tolerance never propagates inward.
- It draws a repair boundary: it fixes mechanical, meaning-preserving deviations (case, whitespace, field order) but stops short of guessing at content.
- On genuine ambiguity it refuses rather than defaults, spending explicitly from a bounded ambiguity budget instead of inventing a meaning.
Tuning parameters¶
- Envelope width — how far from canonical it still accepts. Wider keeps more producers working but expands the de-facto contract the ecosystem learns.
- Repair aggressiveness — accept-as-canonical, auto-fix, or reject. Aggressive repair hides producer defects and teaches them the contract is optional; strict repair surfaces them.
- Ambiguity policy — on true ambiguity, reject with a diagnostic or pick a default. Defaulting is convenient and is exactly where silent wrong-meaning bugs enter.
- Repair telemetry — whether every tolerated variant and repair is logged. Logging feeds the Malformation Rate Dashboard and keeps tolerance visible; silent repair hides the drift.
- Canonical-output strictness — how strict the normalized form must be, so everything downstream can trust a single shape.
When it helps, and when it misleads¶
Its strength is that it lets an interface be forgiving at the edge without paying for that forgiveness everywhere inside — the messy variety is absorbed and flattened at one point. The classic misuse is the canonicalizer that repairs ambiguity by guessing, silently turning an unclear input into one specific valid meaning, which is how a tolerant reader becomes a security and correctness hazard. The subtler cost is that broad silent tolerance teaches producers the written contract does not matter, so variants proliferate and the real contract quietly becomes "whatever the parser happens to accept."[1] The discipline that guards against this is to keep the repair boundary meaning-preserving, reject genuine ambiguity instead of defaulting, log every repair so tolerance stays measurable, and pair the parser with a tightening path so the envelope can be narrowed as producers clean up.
How it implements the components¶
The parser fills the accept-and-normalize side of the archetype's machinery — the parts a tolerant front door owns:
inbound_acceptance_envelope— it defines and enforces the envelope: the explicit, bounded set of input variants the receiver will accept at its door.normalization_and_repair_boundary— its canonicalizer is the normalizer, and it draws the line between the meaning-preserving repairs it will make and the deviations it refuses.ambiguity_budget— it decides, case by case, how much ambiguity to resolve versus reject, spending from a bounded budget rather than always guessing.
It does not translate between two distinct contracts — that is the Adapter or Translation Shim — nor lint the strict output on the emit side (Strict Output Linter), nor chart the repairs it logs, which is the Malformation Rate Dashboard.
Related¶
- Instantiates: Asymmetric Interface Tolerance Calibration — it is the "liberal accept" half of an asymmetric regime, made safe by canonicalizing what it accepts.
- Sibling mechanisms: Adapter or Translation Shim · Malformation Rate Dashboard · Unknown-Field Handling Rule · Tolerant Reader / Strict Writer Policy · Strict Output Linter · Fuzz Testing Against Acceptance Boundary
Notes¶
The parser's tolerance is only safe when it is bounded and measured: the ambiguity budget is its real safety valve, and the repair log is what keeps the envelope from silently widening. An envelope that only ever grows, with no telemetry and no tightening path, is how a protocol drifts into having no contract at all.
References¶
[1] Postel's robustness principle — "be conservative in what you send, be liberal in what you accept" (RFC 761 / 1122). This tool is the "liberal accept" half; its well-documented downside is that unbounded liberal acceptance drifts the de-facto contract, which is why the accept envelope must be bounded, logged, and tightened over time. ↩