blog · 2026-07-31 · written for: ED-4 — the arriving self-principal agent (AC-1 coding class — judges the layer on a command's exit code); B2A motion

resolve(generate(x)) === x: generation and resolution are one function, tested

One thesis: generation and resolution are one function viewed from two sides, and the package treats that as a tested law — resolve(generate(x)) === x for every identity, every carrier, every release — enforced by a differential harness over a published corpus, gated in CI. Not a design preference. A gate: releases that break it do not ship.

This post is written for the reader that verifies claims by running them. Every claim below has a check attached, and the checks are cheaper than trusting us.

The law, stated precisely

For every identity x in the supported schemes and every carrier c the package can write:

resolve(render(generate(x), c)).canonical === x.canonical

Unpacked into its three load-bearing terms:

  • x.canonical is the canonical identity — scheme, canonical-form identifier, complete AI/field map. Not the input string: the normalized identity. A GTIN entered as 12 digits and the same GTIN entered as 14 are one x.
  • render(_, c) ranges over carriers: GS1 element string, Digital Link URI in both canonical and compressed forms, and the rendered symbols — QR, GS1 DataMatrix, GS1-128, ITF-14 — decoded back off the emitted SVG, not off an internal intermediate. The round trip crosses the pixel boundary, because that is the boundary your scans cross.
  • === is equality of canonical identities, byte-compared on the serialized canonical form. Not "equivalent." Not "close." A comparison a machine performs and a human never adjudicates.

Exit-code contract, since that is the interface that matters: resolve and generate exit 0 on success with payload-only JSON on stdout under --json; domain-negative verdicts exit 1 with a typed error on stderr; usage errors exit 2. The round-trip law is what makes those exit codes composable — you can pipe generate into resolve in a script and assert on the diff, with no human in the loop.

Where round trips legitimately normalize — and how that is recorded

An honest inverse law names its quotient. Three normalizations are inherent to the standards themselves, and the harness records each one as a declared normalization in the result — never as a silent pass:

  1. Length canonicalization. GTIN-8/12/13 inputs canonicalize to the zero-padded GTIN-14. The source form is preserved as metadata (sourceForm: "gtin-12"); the identity compared is canonical. The round trip is exact on the canonical form, and the response says which form you gave it.
  2. Digital Link compression. The compressed DL URI form is a different byte string from the canonical URI by construction. The law holds on the decoded AI map: compressed and canonical forms of one identity resolve to the identical map, and the harness asserts that equality, labeling the pair as compression-related rather than pretending the strings match.
  3. AI ordering. Element strings admit multiple valid orderings of variable-length AIs. generate emits one deterministic ordering (fixed-length AIs first, pinned order); resolve accepts any valid ordering; equality is on the parsed map. Deterministic emission is itself part of the contract — the same x generates the same bytes forever, which is what makes outputs diffable across versions.

Anything outside these three is a failure. There is no fourth category of "acceptable drift."

The corpus and the harness

The law is only as strong as the set it is tested over. The golden corpus is published, digest-pinned, and split three ways:

  • valid-standard — identities and payloads exactly conformant to the pinned normative artifacts: GenSpecs-derived AI table, Digital Link grammar, check-digit vectors, TDS serial rules.
  • valid-labeled-beyond — payloads the package accepts and labels: non-GS1 schemes (VIN, ISBN, tracking grammars), and inputs valid against a wider grammar than the standard's, every one carrying an explicit marker of what it is. The house rule in corpus form: conformant to the standard, explicit about everything beyond it — the boundary is data, not prose.
  • invalid — payloads that must fail, with the typed failure asserted: wrong check digit must fail as checkdigit, not as length. A validator that fails for the wrong reason is wrong.

The harness runs N identities × M carriers per release, byte-compares canonical forms, and publishes the result as a fidelity report — pass counts, declared normalizations, and failures typed by rule — the same per-job fidelity idiom epcis.dev publishes for event round-trips. The normative inputs it tests against are themselves pinned: barcoding pins prints the sha256 digests of the AI table, prefix tables, check-digit vectors, and DL grammar the release was gated on, so "tested against the standard" is a claim with a hash on it, and pins change only by journaled human ruling.

Why you should demand this law from any identifier vendor

A checkable claim, and the reasoning is short. An identifier layer sits between things you print and things you parse, usually years apart. If write and read are two implementations, they drift — and identifier drift is silent, physical, and discovered at a dock. The only structural defense is one core under both verbs, proven inverse over a corpus you can inspect, on a cadence you can see.

So the demand generalizes beyond this package: whatever layer you adopt, ask it for (a) the round-trip law stated over canonical forms, (b) the declared-normalization list, (c) the corpus split including typed invalids, and (d) the pinned digests of the normative artifacts it gates against. A vendor that has these will show you. A vendor that does not will send prose.

Check this one now — pure, local, no account, judged on exit codes:

$ npx barcoding.dev generate --gtin 09506000134352 --serial 987 --json \
    | npx barcoding.dev resolve --json | diff <(npx barcoding.dev resolve "(01)09506000134352(21)987" --json) -
$ npx barcoding.dev pins

Empty diff, exit 0, digests printed. That is the entire argument. The write-side walkthrough of what generate emits for a brand's own mark is in See your 2D mark today.

Keys open the network half of the verb set. Get an API key — say what arrives at your door, and the provisioning order follows the list.

We answer in writing. We take at most five conversations a month, only when you ask for one, and only after you already have the written read.