The company is not the performer.
31 July 2026 · the launch journal
The strongest version of a claim about what a standard lacks is a precise account of what it has. So before this estate says one more word about the missing Who, here is the Who that EPCIS 2.0 genuinely, rigorously has — the organisation-grain one — modeled exactly, in a fixture that validates. The absence worth caring about is only visible once the presence is stated fairly.
The three types, and there are exactly three
CBV 2.0 §7.4 defines the source/destination vocabulary — the answer to "between which parties is this transfer happening" — and it is a closed set of three:
- owning_party — the party that owns, or is intended to own, the objects at the originating (source) or terminating (destination) end of the business transfer.
- possessing_party — the party that has, or is intended to have, physical possession at each end. Ownership and possession are deliberately distinct: goods routinely belong to one company while sitting in another's building.
- location — the physical place at each end of the transfer, as distinct from either party.
§8.7 gives the identifier syntax: parties are PGLNs — party GLNs, urn:epc:id:pgln:… — and locations are SGLNs. The pinned JSON-LD context this gateway validates against carries precisely these three mappings (cbv:SDT-owning_party, cbv:SDT-possessing_party, cbv:SDT-location) and no fourth. The grain is the company: a PGLN names a legal entity, never a person, never a device, never a process actor.
The fixture: ownership moves, possession doesn't
The classic 3PL case, and the spec handles it beautifully. Goods sit at a third-party warehouse; a sale closes; ownership passes from seller to buyer while the 3PL keeps physical possession and the goods move between the parties' docks on paper only at the ownership grain. One ObjectEvent, validated against the pinned official EPCIS 2.0.1 schema, exit 0:
{ "type": "ObjectEvent", "action": "OBSERVE",
"eventTime": "2026-07-31T14:05:00.000Z", "eventTimeZoneOffset": "+00:00",
"epcList": ["urn:epc:id:sgtin:0614141.107346.2018"],
"bizStep": "shipping", "disposition": "in_transit",
"readPoint": { "id": "urn:epc:id:sgln:0614141.07346.1234" },
"bizTransactionList": [
{ "type": "po", "bizTransaction": "urn:epc:id:gdti:0614141.06012.1234" } ],
"sourceList": [
{ "type": "owning_party", "source": "urn:epc:id:pgln:0614141.00001" },
{ "type": "possessing_party", "source": "urn:epc:id:pgln:0614143.00001" },
{ "type": "location", "source": "urn:epc:id:sgln:0614141.07346.0" } ],
"destinationList": [
{ "type": "owning_party", "destination": "urn:epc:id:pgln:0614142.00001" },
{ "type": "possessing_party", "destination": "urn:epc:id:pgln:0614143.00001" },
{ "type": "location", "destination": "urn:epc:id:sgln:0614142.00777.0" } ] }
Read the party rows as a table and the model's precision shows: owning party changes (…0614141 → …0614142 — seller to buyer); possessing party is the same PGLN on both sides (…0614143, the 3PL — custody unbroken); and the PO that occasioned it all rides bizTransactionList per §7.3 and §8.5. Three companies, three roles, one event, fully conformant. Anyone who tells you EPCIS "can't model ownership versus possession" hasn't read §7.4.
Now ask the fixture one more question
Which person received it? Or: which forklift driver made the move, which QA tech released the hold, which software agent generated this event from the WMS feed at 14:05?
Walk the fields. owning_party: a company. possessing_party: a company. location: a place. readPoint: a place. bizTransactionList: documents. The event's five dimensions — what, when, where, why, how — are all present and all answered, and no field holds a performer. This is the proof the five-dimensions argument rests on, made concrete: the org-grain Who and the performer-grain Who are different questions, the spec answers exactly one of them, and the fixture that answers it perfectly is the cleanest demonstration that the other has no field — not an empty field, no field. A company at PGLN grain is not a person at badge grain, and no amount of party discipline turns one into the other.
The two grains that fill the gap are a design decision, stated here as precisely as §7.4 states its three: who is the attested observer — the human, agent, or embodied agent that made the observation — carried as a namespaced extension so the event stays conformant; capturedBy is the warrantor account, stamped by the gateway at the door, never supplied by the caller. They are different fields with different meanings, and they are never merged: an agent can observe under an account it does not own, and a dispute needs both facts separately. Party and organisation grain, meanwhile, stays exactly where this fixture puts it — and where it is derived at read time from grant chains, it is never stamped onto the event as if someone had observed it.
The spec-literate takeaway: use §7.4 to its full depth — the three types, PGLN grain, ownership-versus-possession modeled honestly — and let that very completeness mark the boundary where the performer grain begins. Validate the fixture yourself (npx epcis.dev validate, fixtures in the tarball); the custody story upstairs, in executive register, is at visibility.cloud, and identity for humans, agents, and things is id.org.ai. And when your events are ready to carry an attested observer through a real door, get a capture key — the intake asks who you are first, then routes by what you're building.
Sources: CBV 2.0 §7.4 (source/destination types, exactly three) and §8.7 (PGLN/SGLN identifier syntax), PDF text extraction 2026-07-31; SDT mappings in the pinned epcis-context.jsonld (digests at /conformance/); fixture validated with the packaged CLI 2026-07-31, exit 0.
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.