Execution Graphs

Plans as typed DAGs — proposed by the model, enforced by the runtime.

An execution graph is what a plan becomes when you stop trusting prose. When a run needs more than one step, the reasoning layer composes a directed acyclic graph: nodes are typed steps (fetch, transform, decide, act), edges are data dependencies, and the whole structure is validated before anything executes. That validation is the point. The runtime checks that every step's required scope is actually held by the key, that the graph fits inside max_steps, that act-nodes marked consequential have their approval gates attached, and that there is no path to a tool the run was never granted — all before step one. During execution the graph is the contract: steps run when their dependencies resolve, independent branches run in parallel, a failed step fails its downstream cleanly while parallel branches complete, and the final trace is the graph annotated with what actually happened. Graphs are also reusable: a graph that worked can be saved as a template with parameter slots, which is the bridge from one-off runs to the workflows pillar. The practical effect is that 'the agent did something unexpected' stops being a category of incident — the set of things a run can do is fixed and inspectable before it does anything.

[ 01 ]Key features

Validated before execution

Scopes, ceilings, and approval gates are checked against the whole graph up front — invalid plans are rejected, not attempted.

Typed steps

fetch, transform, decide, and act are distinct node types with distinct permissions — an act-node cannot hide inside a transform.

Parallel branches, clean failure

Independent branches execute concurrently; a failed step fails its downstream and nothing else, with partial work preserved.

Graphs as templates

A graph that worked once becomes a parameterized template — the unit of reuse behind workflows and automation.

[ 02 ][ graph — 4 nodes ]

{
  "nodes": [
    { "id": "a", "type": "fetch",     "source": "finance",
      "scope": "finance:read" },
    { "id": "b", "type": "transform", "op": "overdue>30d" },
    { "id": "c", "type": "decide",    "model": "y0-deep" },
    { "id": "d", "type": "act",       "tool": "email.send",
      "approval": true }
  ],
  "edges": [["a","b"],["b","c"],["c","d"]],
  "max_steps": 8
}