# who vs capturedBy

One job: the two grains, exactly, so no integration ever collapses them.

| | `spine:who` | `spine:capturedBy` |
|---|---|---|
| meaning | the attested observer — a human, an agent, or an embodied agent | the warrantor — the account whose key opened the door |
| origin | asserted by the caller | stamped by the gateway |
| the door's half | **graded**: the door sets `spine:attestationGrade`, and the grade reaches only `claimed` until identity attestation lands | **stamped**: whatever the caller sent in this field is stripped and replaced |
| resolution | resolves via id.org.ai — Agent. Human. Thing. | the account itself |

One is stamped, the other is graded; they never merge. Party and organization grain
are derived at read time from grant chains, never stamped on an event — the record
survives your reorg and your revocations.

The grade ladder this surface stamps has two rungs: `anonymous` — no observer
asserted, the grade every capture without `spine:who` receives (the read-back on
[the seams overview](/docs/seams/overview/) shows one) — sits below `claimed`,
an observer asserted by the caller and graded no further until identity
attestation lands. The enumeration is the engine's own capture rule, not this
page's: `spine:who` present stamps `claimed`, absent stamps `anonymous`.

## The transcript

Capture the attested-observer fixture through the MCP door, then read it back —
executed 2026-07-31 against `epcis.dev@0.1.0` over stdio. What went in carried
`spine:who` and no warrantor:

```json
{
  "spine:who": "https://id.org.ai/agents/dock-scanner-7",
  "spine:activity": "https://event-spine.internal/activities/inbound-receiving/run/42"
}
```

What came back out of `query` carries the caller's assertion graded, and the door's
stamps beside it:

```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",
  "recordTime": "2026-07-31T18:42:58.622Z",
  "spine:capturedBy": "urn:epcis.dev:cli:local",
  "spine:attestationGrade": "claimed"
}
```

Read the last three lines as the door's signature: `recordTime` (when the door
heard), `spine:capturedBy` (the local CLI account — the warrantor on your bench), and
`spine:attestationGrade` at `claimed` — the caller asserted an observer, and the door
recorded exactly how far that assertion reaches. Had the payload arrived with its own
`recordTime`, `spine:capturedBy` or `spine:attestationGrade`, the trust-boundary rule
applies: stripped, then stamped.

## Why two fields

`capturedBy` answers "whose key wrote this record" — an accountability fact the door
can warrant, so the door stamps it. `who` answers "who observed the moment" — a claim
about the world the door cannot warrant, so the door grades it instead. Collapse the
two and you either promote a claim to a warranty or demote a warranty to a claim;
either way the record stops being evidence. The grade names the gap honestly, and the
grade is queryable: `spine:who`, `spine:activity`, `spine:attestationGrade` and
`spine:warrantedBy` are usable as query predicates, subject to the reader's grain.

---

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