Docs

The projection

One job: the envelope contract, and its proof. The envelope is a conformant superset of the standard's event — extension fields ride under a declared JSON-LD context, and project(event) always validates against the pinned official EPCIS 2.0.1 schema. One half of that sentence without the other is not the claim.

The declared context

An envelope document declares its extension namespace in @context, beside the standard's own:

"@context": [
  "https://ref.gs1.org/standards/epcis/epcis-context.jsonld",
  { "spine": "https://epcis.dev/ns/spine/v1" }
]

Every extension field is prefixed (spine:who, spine:activity, spine:warrantedBy, …), so a standard EPCIS 2.0 consumer reads the document as what it is: a standard document carrying declared, namespaced extensions — not a fork.

project() — and the proof

project(event) returns the event with the envelope removed: a plain EPCIS 2.0 event. The contract is not "usually validates" — the capture pipeline refuses any event whose projection does not validate, so nothing enters the record that cannot leave it conformant. Executed 2026-07-31 against the published package, on the fixture that carries the fullest envelope in the corpus:

$ npx epcis.dev validate --project --json \
    $CORPUS/valid-superset/object-event-full-envelope.json
{
  "valid": true,
  "schema": {
    "artefact": "epcis-json-schema.json",
    "version": "2.0.1",
    "sha256": "0f46ff694efffd8d8ce840a33dfde84228add11b516b8b258f3200740ae210af"
  },
  "errors": []
}
$ echo $?
0

The verdict names the artefact and the digest it judged against — the pinned official GS1 schema, the same sha256 published on /conformance/ and returned by the live door at POST /validate on this origin.

What projection removes is enumerable

Projection is lossy by design, and the loss is exactly the envelope: the per-dimension diff on the event shows spine:who and spine:activity lifting off while all five standard dimensions survive untouched. Nothing else moves — project() never rewrites, reorders or "fixes" standard fields. The library export is the same function the CLI and the doors run:

import { project, validateEpcis } from "epcis.dev";

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.