Participants and authority
How humans, agents, and services are declared, and how an agent's authority chains to a responsible human.
Every actor in a workflow is a participant, whether it breathes or not. That uniformity is deliberate: it is what lets human and machine work be scheduled, attributed, and audited under one contract.
{
"participants": [
{ "id": "podcast_host", "kind": "human", "name": "Podcast Host",
"role": "host", "organization_id": "org_studio_media" },
{ "id": "caption_agent", "kind": "agent", "name": "Caption Agent",
"operated_by": "podcast_host", "organization_id": "org_studio_media" },
{ "id": "publish_api", "kind": "service", "name": "Example Publishing" }
]
}Fields
id and kind are both required — kind is the only required field beyond an identifier anywhere in the entity registries, which signals how load-bearing it is.
| Field | Type | Notes |
|---|---|---|
id | string | Required |
kind | enum | Required. See below |
name | string | Display name |
role | string | Open set: host, editor, vfx-supervisor, colorist |
organization_id | string | The organization this participant belongs to |
works_for | string | Organization-level delegation (PROV actedOnBehalfOf) |
operated_by | string | For agents: the accountable participant |
identity | string | object | Verifiable identity. See below |
kind
| Value | Meaning |
|---|---|
human | A natural person |
agent | Autonomous software, including generative AI |
service | A deterministic software service |
department | An organizational unit |
organization | An organization acting as a participant |
The agent / service distinction is the one that matters most. A service does the same thing every time. An agent exercises judgement, which is why it needs an accountability chain that a service does not.
A participant with no
organization_idis a third party — an external SaaS, say. That is legitimate and used in practice, but it means nothing in the graph vouches for it. Treat unowned participants as a review signal.
Agent authority
An agent's authority is never ambient. It is a declared edge to a responsible principal:
{
"id": "agent_dubber",
"kind": "agent",
"name": "Localization Agent",
"operated_by": "s.okafor",
"organization_id": "org_studio",
"identity": {
"scheme": "did",
"id": "did:web:example.com:agents:dubber",
"credential_scope": ["read:assets", "write:outputs"]
}
}operated_bynames the participant on whose authority the agent acts. It maps to PROVactedOnBehalfOf. The generative-AI profile makes it required for agent executors.works_foris the organization-level equivalent.identity.credential_scopebounds what the agent may do.
This is what makes "who did this, and on whose say-so" a query rather than an investigation, and it is what makes AI disclosure fall out of the data instead of being compiled by hand. An asset produced by agent_dubber traces to s.okafor and org_studio with no extra record-keeping.
Chains
operated_by may chain — an agent operated by an agent operated by a human. The chain must terminate at a human or organization participant; an authority loop is meaningless, and a validator is required to reject one. See Validation.
Identity
identity accepts a bare string or an object:
| Field | Notes |
|---|---|
scheme | Open set. urn, did |
id | Required within the object form |
credential_scope | string[] — what this identity is permitted to do |
Decentralized identifiers (did:) are the intended direction for agent identity, so that an agent's identity is verifiable rather than merely asserted by whoever wrote the document.
credential_scopeis a declaration, not an enforcement mechanism. The specification defines where an agent's permitted scope is recorded; enforcing it is the implementation's responsibility. Do not assume a document that declares a scope was executed within it.
Organizations
{
"organizations": [
{ "id": "org_studio_media", "name": "Example Studio Media" },
{ "id": "org_vfx_north", "name": "North VFX", "role": "vfx-vendor" }
]
}Only id is required. role is an open set — studio, vfx-vendor, broadcaster, service-provider.
Organizations are the top of the delegation chain and the natural boundary for a turnover: cross-company work means edges that cross an organization boundary, which is exactly what a scoped subgraph controls.
Infrastructure
Infrastructure is where work runs. Declaring it is what makes cost attribution and multi-cloud portability properties of the graph rather than of a spreadsheet.
{
"infrastructure": [
{ "id": "studio_ws", "type": "workstation", "owner": "org_studio_media",
"apps": ["audacity", "premiere"] },
{ "id": "gpu_cloud", "type": "gpu_compute", "owner": "org_mediasvc",
"spec": "A100 80GB" },
{ "id": "cloud_platform", "type": "saas_platform" }
]
}| Field | Type | Notes |
|---|---|---|
id | string | Required |
type | string | Open set: cloud_gpu, gpu_compute, workstation, render_farm, saas_platform, storage, camera, facility |
owner | string | Organization id |
location | string | Region or physical site |
host, product | string | Platform detail |
spec | string | object | e.g. "A100 80GB" |
apps | string[] | Applications available on this target |
A task's ran_on points here. Because capability is described rather than assumed, an engine can match work to a target dynamically instead of relying on hand-routing — the difference between a workflow that runs where it was told and one that runs where it fits.