# Run graph

> The run, and the graph of work inside it: groups, nodes and edges.

A run is one orchestration execution. Inside it, nodes are the units of work and edges say how they relate. Nodes carry identity; the [attempts](https://orchestrationcontextprotocol.io/specification/0.3/attempts) at each node carry almost everything a consumer learns from.

```mermaid
flowchart LR
  T1["T1 impl"] -- dep --> R1["R1 review"]
  T1 -- fan_in --> G1{{"G1 gate"}}
  R1 -- fan_in --> G1
```

## Run

- `id` (string, required): Producer-scoped stable run id.

  At most 200 characters.

- `title` ([ShortText](https://orchestrationcontextprotocol.io/specification/0.3/schema#shorttext))

- `started_at` ([Timestamp](https://orchestrationcontextprotocol.io/specification/0.3/schema#timestamp))

- `ended_at` ([Timestamp](https://orchestrationcontextprotocol.io/specification/0.3/schema#timestamp))

- `workspace` (string): Opaque project/workspace locator for task-mix stratification (a name or hash, not necessarily a path).

  At most 500 characters.

- `labels` ([Labels](https://orchestrationcontextprotocol.io/specification/0.3/schema#labels))

- `task` ([Task](https://orchestrationcontextprotocol.io/specification/0.3/schema#task))

- `configuration` ([Configuration](https://orchestrationcontextprotocol.io/specification/0.3/schema#configuration))

- `provenance` ([Provenance](https://orchestrationcontextprotocol.io/specification/0.3/schema#provenance))

- `acceptance_rule` ([AcceptanceRule](https://orchestrationcontextprotocol.io/specification/0.3/schema#acceptancerule))

- `signals` ([Signal](https://orchestrationcontextprotocol.io/specification/0.3/schema#signal)[]): Verdicts, scores and late events, each timestamped.

- `slate` ([Slate](https://orchestrationcontextprotocol.io/specification/0.3/schema#slate))

- `preferences` ([Preference](https://orchestrationcontextprotocol.io/specification/0.3/schema#preference)[])

- `rescue` ([RunRescue](https://orchestrationcontextprotocol.io/specification/0.3/schema#runrescue))

- `receipt` ([Receipt](https://orchestrationcontextprotocol.io/specification/0.3/schema#receipt))

- `ext` ([Ext](https://orchestrationcontextprotocol.io/specification/0.3/schema#ext))

- `run.id` is REQUIRED and SHOULD stay stable when the same run is written again.
- `workspace` is an opaque locator (a name or a hash), so consumers can group runs by project without learning a path.
- The fields from `task` on are the [observation](https://orchestrationcontextprotocol.io/specification/0.3/task) added in 0.3.

## Groups

A group is an optional named scope, such as a project or a phase of a run. Groups answer where work is shown; edges answer what work blocks. The two stay independent.

- `id` (string, required): At most 200 characters.

- `title` ([ShortText](https://orchestrationcontextprotocol.io/specification/0.3/schema#shorttext))

- `parent` (string): Another group id; parent edges must be acyclic.

  At most 200 characters.

- `ext` ([Ext](https://orchestrationcontextprotocol.io/specification/0.3/schema#ext))

- A group's `parent` MUST name an existing group ([E120](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e120)), and parent links MUST NOT form a cycle ([E121](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e121)).
- A node's `group` MUST name an existing group ([E115](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e115)). A node without a group belongs to the run root.

## Nodes

A node is a unit of work whose identity does not depend on any attempt at it.

- `id` (string, required): Stable identity independent of any attempt. Never a runtime locator such as a pane id.

  At most 200 characters.

- `kind` (string, required): Open set. Recommended vocabulary: impl, review, test, gate, question, docs, ship, plan, ops, task, unknown. `gate` marks an acceptance fan-in point. `task` is a generic task; `unknown` means the producer cannot determine a more specific kind.

  At most 100 characters.

- `title` ([ShortText](https://orchestrationcontextprotocol.io/specification/0.3/schema#shorttext))

- `group` (string): Optional group id; omitted means the run root.

  At most 200 characters.

- `state` (string): Producer's current projection over the node's attempts. Recommended vocabulary: queued, working, review, blocked, done, failed, rejected, canceled, settled_unverified. Consumers learning from settled runs should trust attempt outcomes over this field.

  At most 100 characters.

- `labels` ([Labels](https://orchestrationcontextprotocol.io/specification/0.3/schema#labels))

- `ext` ([Ext](https://orchestrationcontextprotocol.io/specification/0.3/schema#ext))

- `vertex` (string): The workflow piece id this node executes.

  At most 200 characters.

- `gate` (object): Present when the node is a gate.

  *properties*

  - `rule` (string): The acceptance rule this gate implements, when it is one.

    Recommended values (open set): `referee`, `tests`, `merge`, `ci`.

    At most 100 characters.

  - `disposition` (object): Opaque references to how the gate judges.

    *properties*

    - `rubric` (string): At most 500 characters.

    - `severity_map` (string): At most 500 characters.

    - `grammar` (string): At most 500 characters.

    - `ext` ([Ext](https://orchestrationcontextprotocol.io/specification/0.3/schema#ext))

  - `command` (string): The command a mechanical gate runs.

    At most 1000 characters.

  - `ext` ([Ext](https://orchestrationcontextprotocol.io/specification/0.3/schema#ext))

- A node id MUST NOT be a runtime locator, such as a terminal pane id or a process id.
- `kind` is an open set. A gate is a node whose kind is `gate`, marking a point where acceptance is decided; it needs no separate entity.
- `state` is the producer's summary of the node's attempts. A consumer learning from settled runs SHOULD trust attempt outcomes over node state.
- From 0.3, `vertex` names the workflow piece the node executes, linking the run graph to its [configuration](https://orchestrationcontextprotocol.io/specification/0.3/configuration).

## Edges

An edge is a directed pair of node ids with a kind.

- `from` (string, required): Source node id (the prerequisite / input / spawner / launcher / producer's node).

  At most 200 characters.

- `to` (string, required): Target node id (the dependent / gate / spawned node / launched node / consumer's node).

  At most 200 characters.

- `kind` (string, default dep): dep: `to` cannot start before `from` settles. fan_in: `from` is a member of gate `to`'s acceptance input set. spawn: node `to` was dynamically created by work on `from` inside the same harness (a Claude Code subagent through the Task tool). launch: work on `from` started node `to` as a separate harness session through its CLI (a Bash call running `codex exec` or `claude -p`). artifact: an attempt at `from` wrote the artifact named by `artifact` and an attempt at `to` later read it; from_attempt and to_attempt name the two attempts. Other values are accepted, but only dep and fan_in participate in the acyclicity rule.

  Recommended values (open set): `dep`, `fan_in`, `spawn`, `launch`, `artifact`.

- `tier` ([EvidenceTier](https://orchestrationcontextprotocol.io/specification/0.3/schema#evidencetier), required): How the edge is known. Required on every v0.2 edge, whoever the producer is: an edge without an evidence tier does not conform.

- `artifact` (string): For kind `artifact` (required there): the id of the artifact that flowed along this edge. Must name an entry in `artifacts`.

  At most 200 characters.

- `from_attempt` (string): For kind `artifact` (required there, optional elsewhere): the producing attempt id. Must be an attempt at node `from` and equal to the artifact's producer.

  At most 200 characters.

- `to_attempt` (string): For kind `artifact` (required there, optional elsewhere): the consuming attempt id. Must be an attempt at node `to` and among the artifact's consumers.

  At most 200 characters.

- `evidence` ([ShortText](https://orchestrationcontextprotocol.io/specification/0.3/schema#shorttext)): Short producer-authored note on what established the edge, e.g. `Task tool_use id matched subagent meta` or `codex session began 3 s after codex exec in the same workspace`.

- `ext` ([Ext](https://orchestrationcontextprotocol.io/specification/0.3/schema#ext))

| Kind | Meaning |
|---|---|
| `dep` | `to` cannot start before `from` settles. |
| `fan_in` | `from` is a member of the acceptance input set of the gate `to`. |
| `spawn` | Work on `from` created node `to` inside the same harness, such as a subagent. This is how runtime-discovered topology is recorded. |
| `launch` | Work on `from` started `to` as a separate harness session through its command line. |
| `artifact` | An attempt at `from` wrote an artifact that an attempt at `to` later read. |

- `from` and `to` MUST name existing nodes ([E110](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e110), [E111](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e111)).
- Every edge MUST carry an evidence `tier`, whoever the producer is ([E160](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e160)). An edge read directly from a record the tool keeps is `verified`; one inferred from timing, text or paths is `heuristic`; one taken from a session's own claim is `reported`.
- `dep` and `fan_in` edges together MUST form a directed acyclic graph ([E122](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e122)). `spawn`, `launch` and `artifact` edges record observed lineage and MAY form cycles.
- An `artifact` edge MUST name an existing artifact ([E116](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e116), [E117](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e117)) and MUST carry `from_attempt` and `to_attempt` ([E125](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e125)). They MUST name existing attempts ([E123](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e123)) at the edge's `from` and `to` nodes ([E124](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e124)); `from_attempt` MUST be the artifact's producer and `to_attempt` one of its consumers ([E164](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e164)).
- Edges are optional. A producer that knows only which steps ran writes nodes and attempts and adds edges when it can.
