Docs

Hash identity

One job: why an event's identity is computed, and what the computation excludes. The identity is the CBV 2.0 §8.9 standardized event hash — an ni:///sha-256 URI derived from the event's own canonicalized content, with GS1 Digital Link normalisation, so the same fact written as a URN or as a Digital Link URI hashes to the same identity.

What §8.9 excludes, and why

By construction the algorithm excludes eventID, recordTime and errorDeclaration. The exclusions are the point:

  • eventID — identity cannot depend on an assigned name, or two parties naming the same fact differently would make it two facts.
  • recordTime — identity cannot depend on when a door heard about the fact, or the same event captured twice would be two events. That is what makes capture idempotent: a replay computes the same identity and is recognised, not duplicated.
  • errorDeclaration — a correction points at the event it corrects; folding it into the hash would move the target as you declare against it.

The same event captured twice is the same event; a changed event is a different one.

Byte-matched to the reference

The suite is gated on the OpenEPCIS event-hash reference vectors (from the openepcis-event-hash-generator corpus — credit where the vectors live). Executed 2026-07-31 against the published package, on the epcisDocWithSingleEvent vector document:

$ npx epcis.dev hash epcisDocWithSingleEvent.jsonld
hash	0	ni:///sha-256;ffa491b16867e34a7791a8d5389d826afc24e63a121026b6a4004ace38631b4b?ver=CBV2.0

$ cat epcisDocWithSingleEvent.hashes
ni:///sha-256;ffa491b16867e34a7791a8d5389d826afc24e63a121026b6a4004ace38631b4b?ver=CBV2.0

Byte-identical to the reference's published expected hash.

The same digest from every door

One algorithm, one identity, regardless of which door computes it — local verb and live door, executed 2026-07-31 on the shipping fixture from the in-tarball corpus:

$ npx epcis.dev hash $CORPUS/valid-standard/object-event-shipping.json
hash	0	ni:///sha-256;e5624abcce4b2fc226743e8891f69c12a07ad508953749d9b9ede6771424f91e?ver=CBV2.0

$ curl -sS -X POST https://epcis.dev/hash \
    -H 'content-type: application/json' \
    --data-binary @$CORPUS/valid-standard/object-event-shipping.json
{
  "algorithm": "CBV 2.0 §8.9 event hash",
  "count": 1,
  "hashes": [
    "ni:///sha-256;e5624abcce4b2fc226743e8891f69c12a07ad508953749d9b9ede6771424f91e?ver=CBV2.0"
  ]
}

The canonicalization steps are exposed in the library barrel for anyone re-deriving the identity themselves:

import { eventHash, canonicalJson, preHashString } 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.