The developer door, in depth
Build the part that's yours. The EPCIS 2.0 standards layer is a pinned dependency.
You were handed a build mandate and a date. Under the interesting part — the thing that is actually specific to your company — sits EPCIS 2.0 conformance, a decade of vendor XML, and an event hash that has to match what other people compute. That layer is the boring 40% of the platform, and it is the part that will still be eating your Fridays in three years. You do not need a squad to maintain it. You need it to already exist — pinned, tested, and readable.
epcis.dev is the EPCIS 2.0 capture gateway from the developer and agent side. It validates every event against GS1's official JSON schema, hashes by CBV 2.0, translates a decade of legacy XML, and exposes the same interface to a person and to that person's agent through one door. Its executive lens — traces, custody evidence, retention — is visibility.cloud. Same event spine, two faces.
Check it yourself in four minutes: no capture key has ever been issued, and no conformance attestation has ever gone out — the registry's own lifecycle refuses an unsigned run. Everything below that says translate, validate or hash answers today, two ways: POST /translate, /validate and /hash on this origin — no key, no account — and npx epcis.dev on your own bench. resolve refuses honestly — a tool error naming id.org.ai, never a fabricated resolution — every time. The dated ledger of every open gate is What ships today.
Why buy the standards layer instead of building it? (the operational cost, not the deadline)
The cost isn't the first implementation. You can write an EPCIS translator in a sprint that handles the four file shapes you had on day one. The cost is the second implementation: the translator that is 90% the same as everyone else's and 100% yours to maintain — unpinned to a standard that moved, undocumented, load-bearing, and eventually the reason you can't leave the team.
The operational ROI of taking the standards layer as a dependency is the Fridays you get back:
- You stop re-implementing a moving standard. GS1 EPCIS 2.0 and CBV 2.0 are versioned; the official schemas move; the reference vectors change. A pinned dependency with published sha256 provenance absorbs that churn so your roadmap doesn't.
- You stop owning the fidelity problem. A decade of EPCIS 1.1 / 1.2 XML has to become 2.0 JSON-LD without silently dropping fields. A per-job round-trip fidelity report is the difference between a migration you can sign off and one you find out about in an audit.
- You stop guessing at the hash. The CBV 2.0 §8.9 event hash has to match what your customer, your auditor, and your trading partner compute independently. If your hash and theirs disagree, the event is not shared — it's disputed.
FSMA 204 sits underneath all of this as a de-risking floor, not a countdown: the traceability obligation is why an in-house team is asked to build a conformant repository at all. But the reason to take the standards layer as a dependency today is engineering time, not a date — and the date has its own honest story below.
How do I validate an EPCIS 2.0 event against GS1's official JSON schema?
You point it at the schema GS1 actually publishes — not a hand-copied subset — and you make the pin provable.
Here that is a law, not a feature: project(event) must always validate against the official EPCIS 2.0 JSON schema. The validators are precompiled over the pinned official GS1 schemas, at EPCIS 2.0.1, with sha256 provenance recorded in PINS.json, and the whole thing is gated in CI. When it rejects an event it does so as RFC 7807 application/problem+json, carrying the standard's own exception types — so the error your caller sees is the error the standard names, not a string we invented.
# validate — no account, no gate
npx epcis.dev validate ./event.json
# → conforms | RFC 7807 problem+json with the EPCIS exception type
Proof: npx epcis.dev validate answers on your bench, and POST /validate answers on this origin — no key, no account. Same engine, same pinned schema, same exception types.
What does "conformance" actually mean here — can I check your work?
Yes — that is the whole design. For this hero, authority is only artifacts you can inspect, never a logo or a claim:
- Open source, MIT — so the 40% you're taking as a dependency is readable before you depend on it.
- PINS.json with sha256 provenance over the pinned official GS1 schemas at EPCIS 2.0.1.
- An automated conformance suite run over the GS1 test requirements, gated in CI.
- The projection law (project(event) validates against the official schema) enforced on every path, not asserted in a README.
GS1 has not reviewed or endorsed this. It conforms to EPCIS 2.0 and CBV 2.0 and makes no claim above them.
Is there a CLI / npx to translate EPCIS XML to EPCIS 2.0 JSON-LD?
Yes. Translation is the first thing you should run, because it is the boring, expensive, exactly-the- same-for-everyone problem — and it is the honest evaluation: point it at a real file you already have.
# translate — the evaluation IS the first value
npx epcis.dev translate ./legacy-events.xml
# → EPCIS 2.0 JSON-LD + a per-job round-trip fidelity report
It reads EPCIS 1.1 / 1.2 / 2.0 XML and emits EPCIS 2.0 JSON-LD, and every job comes back with a round-trip fidelity report so you can see what survived and what didn't before you trust it. No account. No form. No email. The evaluation is yours, offline, in four minutes.
Proof: npx epcis.dev translate answers on your bench, and POST /translate on this origin returns the JSON-LD plus the fidelity report — no key, no account. Run it against your own file; don't take our word for it.
How do I build an EPCIS 2.0 capture repository without re-implementing the standard?
You take the interfaces as a dependency and build the part that's yours on top. epcis.dev implements the EPCIS 2.0 capture and query interfaces against GS1's official OpenAPI description, pinned by digest, and enforces eight laws the standard implies but doesn't hand you as code:
- Every captured event validated against the official GS1 EPCIS 2.0 JSON schema before it lands.
- Errors as RFC 7807 application/problem+json with the standard's own exception types.
- The standardized CBV 2.0 §8.9 event hash, checked against pinned reference vectors.
- Append-only storage: no service identity holds an UPDATE or DELETE grant.
- Minimally scoped reads: out-of-scope data is absent, not redacted.
- Gateway stamping of recordTime, capturedBy, and attestationGrade — caller-supplied values in those fields are stripped, so provenance is something the gateway asserts, not something a payload can claim about itself.
That last law answers a question the spec quietly leaves open. EPCIS 2.0 §7.2.2 defines five event dimensions — what, when, where, why, how — and no performer among them. The party fields are organisation-grain (EPCIS §7.3.6.4, CBV §7.4.3, §8.7.1 PGLN). A Company doing a Process is answered by the standard; a worker or agent doing a task at the moment of the scan has no field of its own — the standard's Who stops at the company, a GLN. So the gateway stamps capturedBy and attestationGrade at the door: the grain the spec doesn't carry, added where it can be trusted rather than asserted by the sender. §7.2.2 · §8.7.1 — ten minutes, the specs are public, don't take our word for it.
Engineering ledger (for the reviewer, not the exec). OpenAPI pinned by digest · schemas pinned in PINS.json with sha256 at EPCIS 2.0.1 · RFC 7807 problem types = the EPCIS exception set · CBV §8.9 hash gated against OpenEPCIS reference vectors · append-only enforced by grant, not convention (no identity holds UPDATE/DELETE) · conformance suite over the GS1 test requirements — 683/683 against GS1's normative artefacts this build. This is what a security or architecture reviewer needs to close most of their questionnaire before it's sent — the published pins (/conformance/, re-hashable against ref.gs1.org), and the open-source tree itself.
Proof: npx epcis.dev capture runs the whole pipeline — strip, validate, stamp, append — on your bench with the full durable substrate, and every open launch gate is dated in the ledger.
Is there an MCP server for EPCIS / supply-chain events my agent can call?
Yes — and it is a door, not a second path. The MCP door exposes capture, query, get_event, trace_epc, and translate as tools, and it is re-dispatched through the same worker fetch, with the same key, as the HTTP interface. There is no parallel agent implementation to drift from the human one — the agent path and the HTTP path cannot diverge, because they are the same path.
This matters more for an agent than for a person. A CBV §8.9 hash gated against someone else's reference vectors is exactly what lets a verifier agent trust a result it did not compute itself. Read-only tools carry readOnlyHint: true where it's true, plus complete tool descriptions — which is what clears an agent's auto-approval so those verbs fire inside already-granted scope without a human round-trip. Write authority never auto-grants: absent a pre-registered notification channel, every human-gated scope fail-closes — never a silent grant.
If your agent arrived here, it should read the machine contract, not this page:
- /icp.json — the derivation contract, built from the same frozen constants the runtime selects on, so the published contract and the runtime selection cannot drift. (live on this origin)
- /agent-classes.json — the one enumeration of arriving agent classes, each with its entry verb, verbs in scope, and the residency artifact that lets a provisioned seat survive a cold start. (live on this origin)
Most vendors in this market ship a sales door and no machine door — a contact form, a demo request, a login — and the agent arrives capable and mandated and is met with a form. That's the whole failure. The commitment here is the opposite: a system that expects an agent says so in a machine-readable way and refuses to grant authority silently.
Proof: npx epcis.dev mcp serves the five tools over stdio on your bench, and /icp.json and /agent-classes.json are live on this origin. install, claimApiKey, requestGrant and provisionAgentSeat are dated in the ledger.
How do I compute the CBV 2.0 §8.9 event hash in code?
You compute it the way the standard specifies and then you prove it matches, because a hash only one party can reproduce is worthless.
# hash — the standard's own event identity
npx epcis.dev hash ./event.json
# → the CBV 2.0 §8.9 event hash (ni:///sha-256;…?ver=CBV2.0)
The implementation is gated against the OpenEPCIS reference vectors in CI — the same vectors your trading partner's stack is likely checking against — so the hash this produces is the hash they compute. That is the point of a standardized hash: independent parties arrive at the same identifier for the same event, and the event becomes shareable rather than disputable.
Proof: npx epcis.dev hash answers on your bench, gated in CI against the pinned OpenEPCIS reference vectors, and POST /hash answers on this origin — so both parties can recompute the same identifier today.
Is the FSMA 204 deadline the reason to do this now? (no — here's the honest date)
No. Lead your business case on engineering cost, not on a countdown, because the countdown is falsifiable in one search. The FSMA 204 compliance date moved from January 2026 to July 20, 2028 in the proposed rule of 2025-08-07; it was never finalised as a rule, it rests on the Continuing Appropriations Act of 2026, and the FDA is soliciting further flexibilities (Fed. Reg. 2026-05-28). Treat 2028 as a de-risking floor under the work, never a gun to the head. The reason to take the standards layer as a pinned dependency this quarter is that the second implementation you'd otherwise write is a permanent tax — and that's true on any timeline.
What does it cost to record an event?
Our intent is that recording an event never costs money, and it is never shown as a meter — the allowance is abuse governance, never a bill. No published terms bind this yet, so it is stated as intent, not as a standing price. Revenue attaches to answers on the executive side (visibility.cloud) — traces, custody evidence, seats, retention, grants — not to capture.
The plan: three steps, none of them a meeting
- npx epcis.dev — bare invocation, never @latest. translate a real file you already have. Zero accounts, zero forms. The first value is the evaluation — and POST /translate on this origin answers the same way, zero install.
- Check the provenance — the checkable half is published today: the pins table at epcis.dev/conformance renders PINS.json, the sha256s and the OpenEPCIS vector gate, and you can re-hash the same artefacts from ref.gs1.org yourself. The round-trip suite and the source live in the open-source tree, dated in the ledger. Decide whether we're serious. This step is an invitation to audit us; it's the only credibility move that counts.
- npx epcis.dev mcp — write the MCP entry / AGENTS.md line so translate, validate, and hash are available to you and to your agent with no gate on compute. This is the retention model: the tool writing itself into your durable toolchain, not a login. (install as a verb is dated in the ledger.)
Where this goes if you do nothing: you write the translator. It works for the four file shapes you had on day one. Two years later it's load-bearing, undocumented, unpinned to a standard that moved, and it's the reason you can't leave the team.
Where this goes if it works: you move from "we're building an EPCIS layer" to "the EPCIS layer is a pinned dependency with published provenance, and we built the part that's actually ours."
Get a capture key (the one thing to sign up for)
A capture key opens the write half of the door, and keys are provisioned from the list, in order — a real store backs it. Tell us what you'll point at the door:
- Migrating legacy XML — you have EPCIS 1.1 / 1.2 / 2.0 XML and want 2.0 JSON-LD out, with a fidelity report per job. → /get-a-key?segment=translate
- Evaluating conformance — you want to check capture against GS1's official schema and the CBV 2.0 event hash. → /get-a-key?segment=conformance
- Building on the SDK — you want a typed SDK/library over the interface, not raw HTTP. → /get-a-key?segment=sdk
- Reading events back — you query the standard interfaces and want minimally-scoped, append-only reads. → /get-a-key?segment=query
- Capturing from my own systems — you POST EPCIS 2.0 events from a WMS, an ERP, or a line, and you want a key and the schema. → /get-a-key?segment=integration
- An agent captures for me — a logistics or coding agent captures and queries over MCP, with the same key a person would use. → /get-a-key?segment=agent
The promise, in full: Keys are provisioned from this list, in order. One email when yours is ready — one, not a drip campaign. Nothing else, ever — no newsletter, no sequence. If we stop working on this, you get one message saying so and your address is deleted. Either way it is one message.
Prefer not to wait? The translate · validate · hash verbs answer right now — npx epcis.dev on your own bench, and POST /translate, /validate, /hash on this origin, no key, no account.
If you'd rather talk it through: 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.
Related
- visibility.cloud → the executive lens — the same spine from the supply-chain executive's side: traces, custody evidence, retention, seats. Send your programme office there; keep the repo here.
- What ships today — the dated ledger of built vs unbuilt, so nothing on this page has to be taken on faith.
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.