# 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 normalization, 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 recognized, 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 CBV 2.0 §8.9 reference vectors published by Ralph Troeger,
co-chair of the EPCIS & CBV 2.0 MSWG, in
[RalphTro/epcis-event-hash-generator](https://github.com/RalphTro/epcis-event-hash-generator)
(MIT) — the reference implementation of the algorithm. The corpus is vendored under
`vendor/epcis-event-hash/` and sha256-pinned. Fetch the vector pair from its
source, then run — executed 2026-07-31 against the published package:

```
$ V=https://raw.githubusercontent.com/RalphTro/epcis-event-hash-generator
$ curl -sSO $V/master/tests/examples/epcisDocWithSingleEvent.jsonld
$ curl -sSO $V/master/tests/examples/epcisDocWithSingleEvent.hashes

$ 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:

```
$ CORPUS=node_modules/epcis.dev/golden-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:

```js
import { eventHash, canonicalJson, preHashString } from "epcis.dev";
```

---

**Proof, not adjectives.** This build could not verify the gateway's test suite green, so no sentence on this page claims a passing run — the last verified run is recorded in the repository's own CI, not here. Live on this origin, no key: POST /translate, /validate, /hash. No conformance attestation has ever been issued. The dated ledger is /what-ships-today/.
