The blog · 2026-07-31
Grammars are data, and data has provenance — GRAMMAR-PINS.json
Written for ED-3 — the in-house supply-chain platform team — the security / architecture reviewer with a dependency-provenance questionnaire to fill.
One thesis: the grammar layer of this engine is data, not code — one self-authored file per (transaction set × version), each carrying a provenance block naming its sources, each pinned by sha256 in GRAMMAR-PINS.json, changed only by journaled human ruling — and the verify gate refuses to run against a file whose digest has drifted.
You review dependencies for a living. This post is the answer to the three questions your questionnaire asks about any parsing layer: where did the structural knowledge come from, who can change it, and how would you know if someone did.
What a grammar file contains — and deliberately omits
A grammar is the structural definition the validator runs against: segment order, loop structure, requirement designators, min/max use, element types and lengths, for one transaction set at one version — 856 at 004010, 850 at 005010, and so on. It contains structure. It deliberately omits prose: no element names copied from a licensed dictionary, no definitions, no code-value catalogs. The engine needs to know that position 2 of a segment is mandatory and numeric; it does not need — and must not carry — anybody else's copyrighted sentence about what position 2 means. Where a human needs element-level meaning, the page links the canonical public X12 reference, which publishes under a negotiated license this repository does not have and does not need — the whole licensing posture is stated plainly on its own page.
The provenance block
Every grammar file opens with its own paper trail:
{
"set": "856", "version": "004010",
"provenance": {
"method": [
"public implementation conventions (US government ICs, cited by URL)",
"corpus observation over license-tagged fixtures",
"differential parser behavior (pyx12, gozer, node-x12)"
],
"brightLine": "no content transcribed from X12 Glass or any licensed reference",
"authored": "2026-07",
"rulings": ["RJ-0007", "RJ-0012"]
},
"segments": [ ... ]
}
Three source classes, and only three: implementation conventions that government agencies publish openly, observation of what real documents in the license-tagged corpus actually do, and what independent open-source parsers agree the structure is. The bright line is stated inside the artifact itself because that is where an auditor looks: nothing in a grammar file is transcribed from a licensed reference, ever. Reading to understand and copying into data files are different acts, and the provenance block is the standing declaration of which one happened.
The pin ledger
GRAMMAR-PINS.json holds one entry per grammar file — sha256, authorship date, ruling journal references — and the corpus has its twin, CORPUS-PINS.json, where every fixture carries its source URL, license, and retrieval date. The idiom is inherited, not invented: the family's event door pins the official GS1 artifacts the same way (the digests are published on epcis.dev's conformance page), and the governance sentence is identical on both sides of the family: pins change only by journaled human ruling. A ruling names what changed, why, who decided, and the date; the journal is append-only. transactions.dev pins prints the current ledger, so the digests you audit against are one command away, not buried in a repository you have to trust us about.
The gate that refuses
Pins without enforcement are decoration. The verify gate hashes every grammar file against its ledger entry before the engine will use it:
$ npx transactions.dev pins --verify
GRAMMAR-PINS 856/004010 sha256 mismatch
pinned: 9f31c4…e2a8
actual: b04d17…99c1
refusing to load — grammar changed without a journaled ruling
$ echo $?
1
A tampered file — or an honest edit that skipped the ruling step — does not degrade the engine into "probably fine"; it stops it, with a typed error and the exit-code contract the whole family honors.
Why anti-tamper on your own files is not paranoia
The obvious objection: these are our grammars — why gate ourselves? Because the grammar layer is exactly where an optimizing process cheats. This engine is built and improved by agent swarms hill-climbing against a conformance harness, and the cheapest way to make a failing test pass is to quietly loosen the grammar the test validates against. Pinning the grammars and routing every change through a journaled human ruling makes the target fixed: the swarm climbs conformance to the grammar, never the grammar itself. It is the anti-Goodhart move, and it is the same reason the differential harness's spec files are digest-bound too. Your questionnaire calls this change control; we agree, and it is load-bearing rather than ceremonial.
What this answers on the questionnaire
- Origin of structural knowledge: three named source classes, declared per file, bright line against licensed content stated in the artifact.
- Change control: sha256 pins, append-only ruling journal, verify gate that fails closed.
- Auditability: pins prints the ledger; the fidelity and validation reports cite grammar digests, so any verdict is traceable to the exact grammar version that produced it.
- Blast radius of a bad ruling: one file, one digest, one journal entry to revert — grammar-as-data means rollback is a data operation.
The layer this governs — what validation actually checks and what the harness holds it to — is the differential harness post. The access flow, if the questionnaire comes back clean, is at /get-access/.
862 words. The access flow is at /get-access/; the family's event door is epcis.dev.