# The event

One job: read one event and know what every field is for. An EPCIS 2.0 event records
one observed moment. The standard defines five dimensions on it — what, when, where,
why, how. The event here has six: **who** — the attested observer — carried as
`spine:who` under a declared JSON-LD context, so the document stays valid against the
pinned official schema.

## One fixture, annotated by dimension

This event ships in the package at
`golden-corpus/valid-superset/object-event-attested-observer.json`:

```json
{
  "type": "ObjectEvent",
  "eventID": "urn:uuid:8a1b2c3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
  "eventTime": "2026-07-19T11:45:00.000Z",
  "eventTimeZoneOffset": "+02:00",
  "epcList": ["urn:epc:id:sgtin:0614141.107346.2021"],
  "action": "OBSERVE",
  "bizStep": "receiving",
  "disposition": "in_progress",
  "readPoint": { "id": "urn:epc:id:sgln:0614141.00999.0" },
  "spine:who": "https://id.org.ai/agents/dock-scanner-7",
  "spine:activity": "https://event-spine.internal/activities/inbound-receiving/run/42"
}
```

| dimension | fields | in this event |
|---|---|---|
| **What** | `epcList`, `action` | one serialized item, observed (`OBSERVE`: seen, not created or removed) |
| **When** | `eventTime`, `eventTimeZoneOffset` | when it happened, in local wall-clock terms; `recordTime` — when the door heard — is stamped at capture, never caller-supplied |
| **Where** | `readPoint`, `bizLocation` | the point that saw it; the business location it speaks for |
| **Why** | `bizStep`, `disposition`, `bizTransactionList`, `sourceList`, `destinationList` | receiving, in progress — the CBV's vocabulary, not free text |
| **How** | `sensorElementList` | absent here; present when an instrument observed |
| **Who** | `spine:who` | the attested observer — a human, an agent, or an embodied agent; the sixth dimension this spine adds |

**Grain** is the size of the thing a record is about. A company is one grain. A product
line is a finer one. A batch is finer still, and a single unit — this one, and not the
one behind it — is the finest there is. On the wire that ladder is a PGLN, a GTIN, a
GTIN plus lot, and a GTIN plus serial.

The standard's own party fields are organization-grain — GLNs and PGLNs name legal
entities, and no standard field names the performer. `spine:who` carries the performer
without forking the schema; the next page,
[who vs capturedBy](/docs/event-model/who-capturedby/), states the two grains exactly.

## The event supertype, and the five types

Every field above except `epcList` and `action` belongs to the event supertype — the
shape all five event types share. The types differ only in their What:

| type | its What |
|---|---|
| `ObjectEvent` | objects observed, added or removed |
| `AggregationEvent` | a parent (the pallet) and its children (the cases) — physical nesting, `action` ADD/OBSERVE/DELETE |
| `TransactionEvent` | objects declared against business transactions |
| `TransformationEvent` | inputs consumed, outputs produced — genealogy |
| `AssociationEvent` | an assembly relation (a sensor bolted to a reusable asset) |

## The diff, by dimension

The sixth dimension is exactly what the conformant projection removes — executed
2026-07-31 against the published package:

```
$ node --input-type=module -e '
  import { readFileSync, writeFileSync } from "node:fs";
  import { project } from "epcis.dev";
  const doc = JSON.parse(readFileSync(
    "node_modules/epcis.dev/golden-corpus/valid-superset/object-event-attested-observer.json",
    "utf8"));
  const ev = doc.epcisBody.eventList[0];
  writeFileSync("event.json", JSON.stringify(ev, null, 2) + "\n");
  writeFileSync("event.projected.json", JSON.stringify(project(ev), null, 2) + "\n");'

$ diff event.json event.projected.json
14,16c14
<   },
<   "spine:who": "https://id.org.ai/agents/dock-scanner-7",
<   "spine:activity": "https://event-spine.internal/activities/inbound-receiving/run/42"
---
>   }
```

Five dimensions survive projection untouched; the sixth lifts off cleanly. That
round-trip discipline is the whole envelope contract —
[the projection](/docs/event-model/projection/) states it, and proves the projected
event validates against the pinned official schema.

---

**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/.
