Tolerant Reader / Strict Writer Policy¶
Interface strictness policy — instantiates Asymmetric Interface Tolerance Calibration
Sets the interface's standing regime as deliberately asymmetric — strict about what the system emits, liberal about what it accepts — and writes that choice down as policy rather than leaving it to each parser.
Tolerant Reader / Strict Writer Policy is the archetype's namesake move stated as a standing rule: emit conservatively, accept liberally, on purpose and in writing. Its defining contribution is the decision itself — it fills in the strictness matrix's asymmetric cell and defines how wide the accept side may open, so the interface's tolerance is a governed choice rather than an accident of whatever each implementer happened to code. It does not itself lint output or normalize input; it declares the regime those tools then carry out. The point of writing it down is that "be liberal in what you accept" is only safe when paired with a bound: the policy states both which asymmetry the interface runs and how far the tolerance extends before it stops.
Example¶
A city's open-data platform ingests spreadsheets from dozens of departments — police, transit, parks — each maintained by different people with different habits: date formats, column names, encodings, stray header rows. A brittle importer would reject most of them and generate endless tickets. So the platform adopts a tolerant-reader / strict-writer policy. As a reader it accepts a wide, explicitly-bounded envelope: several date formats, case-insensitive headers, common encodings, blank lines. As a writer it emits exactly one canonical form to every downstream consumer — ISO dates, a fixed schema, UTF-8 — no exceptions. The policy document names both sides: here is the list of input variations we tolerate (and everything outside it is rejected, not guessed); here is the single output shape we guarantee. Departments get frictionless ingestion; every dashboard and API downstream sees one clean shape, because the messiness was absorbed at the reader and never re-emitted.
How it works¶
- Name the regime explicitly. The policy states the interface is strict-out / liberal-in — one cell of the strictness matrix — so the asymmetry is a recorded decision, not an emergent one.
- Bound the accept side. "Liberal" is defined as a specific enumerated envelope of tolerated variations, with a hard edge beyond which input is rejected rather than charitably interpreted.
- Delegate enforcement. The strict-emit clause is handed to an output linter; the normalization of accepted variants to a canonicalizing parser. The policy sets direction; other mechanisms execute it.
- Keep the two sides from leaking. Crucially, tolerated inbound variety is never propagated outbound — what the reader accepts loosely, the writer still emits strictly, so tolerance stops at the boundary.
Tuning parameters¶
- Accept-envelope width — how many inbound variations are tolerated. Wider eases integration but enlarges the surface the reader must handle correctly and safely.
- Asymmetry direction — the usual strict-out / liberal-in can be flipped to strict-in / liberal-out for a source-of-truth publisher; the policy is where that per-direction choice is made.
- Envelope explicitness — whether tolerated variants are enumerated or left to "be reasonable." Enumerated envelopes are safe and testable; vague ones invite scope creep and silent protocol expansion.
- Repair visibility — whether accepted-but-nonstandard input is silently normalized or normalized-and-flagged, trading a quiet interface against a signal that a producer is drifting.
- Review cadence — how often the envelope is revisited, so "temporary" tolerances don't harden into a permanent second contract.
When it helps, and when it misleads¶
Its strength is resilience without decay when — and only when — both halves are honored: strict emission keeps the ecosystem's de-facto contract from rotting, while bounded liberal acceptance keeps harmless variation from causing needless failure. Writing the regime down is what makes it auditable and testable instead of a folk practice scattered across parsers.
Its danger is the half-applied version. The interface-design canon is Postel's robustness principle — "be conservative in what you send, be liberal in what you accept"[1] — and its much-discussed failure is that liberal acceptance, left unbounded and unmonitored, teaches producers that the written contract is optional: the real protocol quietly becomes whatever receivers happen to tolerate, and every reader must forever bug-for-bug match every other. The classic misuse is invoking "tolerant reader" to justify accepting anything while quietly neglecting the strict-writer half — the discipline that actually holds the contract. The guard is to bound and enumerate the accept envelope, monitor what enters it, and enforce the emit side with real teeth: tolerance with an edge and a gauge, never tolerance as a shrug.
How it implements the components¶
strictness_regime_matrix— it is the filled-in matrix for this interface: the recorded per-direction decision that emission is strict and acceptance is liberal.inbound_acceptance_envelope— it defines the bounded set of inbound variations the receiver will tolerate, and the hard edge past which input is rejected rather than guessed.
It declares but does not enforce: the strict-emit side is carried out by Strict Output Linter, the actual normalization of accepted variants by Lenient Parser with Canonicalizer, and the specific treatment of unrecognized fields by the Unknown-Field Handling Rule.
Related¶
- Instantiates: Asymmetric Interface Tolerance Calibration — it is the explicit statement of the asymmetric regime the whole archetype turns on.
- Sibling mechanisms: Strict Output Linter · Unknown-Field Handling Rule · Strict Bidirectional Contract Gate · Lenient Parser with Canonicalizer · Quarantine and Manual Review Queue
References¶
[1] Postel's robustness principle — "be conservative in what you do, be liberal in what you accept from others," articulated by Jon Postel in the early TCP specifications. It is the origin of the strict-writer / tolerant-reader stance, and its much-discussed downside — that unbounded acceptance lets the de-facto protocol drift away from the written one — is exactly why this policy insists the accept side be bounded and the emit side enforced. ↩