Orchestration
L4. Workflow, run, step, trigger and event. Five nouns that turn a decision into durable execution.
Orchestration
L4. The layer that executes.
A decision that is not durable is a guess. This layer takes a plan and runs it, survives a crash, retries a failure, waits for a person, and records everything it did.
Components
| Component | Job |
|---|---|
| Workflow | The definition. An ordered set of steps, versioned. |
| Run | One execution of a workflow or of an agent. |
| Step | One durable unit inside a run. It is retried on failure, and it is not repeated on resume. |
| Trigger | The condition that starts a run. |
| Event | One append-only fact a run emitted. |
| Scheduler | Start a run at a time, or on a repeat. |
| Reaper | Close a run that stopped reporting. One reaper, for every run. |
The five nouns
Workflow what should happen
│
├── Run #001 what did happen, on Monday
├── Run #002 what did happen, on Tuesday
└── Run #003 what is happening now
A workflow is a definition. A run is an instance. Confusing the two produces a system where you cannot answer "what did it do last week".
What a run holds
run
workflow or agent, and the version pinned at start
trigger what started it, and who the principal is
input the brief
state one of the states below
steps child runs, each with its own state
output the result
error the failure, if any
retries the count, per step
cost tokens and money
artifacts what it produced
events the append-only log
The run row is the single source of truth for execution. There is one run table for agent runs and for workflow runs. A workflow run is the parent of its step runs.
Run states
queued → admitted → running ──→ succeeded
│ │ │
│ │ └──→ awaiting_approval ──→ running
│ │
│ ├──→ failed (retries exhausted)
│ └──→ cancelled (a person intervened)
│
└──→ denied (policy refused at admission; nothing ran)
denied and cancelled are separate states on purpose. One means the system refused. The other means a person stopped it. A single "stopped" state loses the difference, and that difference is the first question anyone asks.
Triggers
Five kinds start a run. The run does not know which one it was, beyond one field.
| Trigger | Starts a run when | Principal |
|---|---|---|
| Manual | A person asks in Mission Control | That person |
| Schedule | A time or a repeat is reached | A service principal |
| Event | A company state change matches a pattern | A service principal |
| Webhook | An external system posts, and the signature verifies | A service principal |
| Agent | An agent delegates a plan | The agent's own principal, itself derived from a person |
Policy admits every run, whatever the trigger. A scheduled run for an account over budget is stopped before it dispatches.
A webhook trigger always has a schedule beside it. External delivery is at-least-once and a message can be missed, so a slower schedule re-reads the same window. The steps must be idempotent, which makes the repeat harmless. A webhook on its own is data that is quietly incomplete.
The ingest workflow
Any pull from an external system uses one shape, and no model runs inside it.
fetch → normalize → upsert → emit
fetch calls a vendor tool. normalize discards the payload and keeps only what we model. upsert writes through an internal tool, keyed so a re-run overwrites rather than duplicates. emit writes the run event that a downstream trigger may match. The worked example is Metrics and connectors.
Rules
- A step is the unit of durability. A crash resumes at the last completed step. It does not restart the run.
- A step is idempotent, or it carries an idempotency key. A retry must not send a second email.
- A run pins its definition version at start. An edit to a workflow never changes a run in flight.
- A wait is a state, not a loop. A run that waits for an approval or for an external event consumes nothing.
- Every run has a deadline. The reaper closes a run that stopped reporting, and it records the reason.
- Events are append-only. A correction is a new event. Nothing in the log is edited.
- The engine sequences. It does not reason. A branch in a workflow is a condition over data, never a model call. A decision that needs a model is a step that runs an agent.
Events
One stream leaves this layer, and three consumers read it.
run event
├── Mission Control activity feed L6
├── trigger matcher L4, an event can start another run
└── the accrual checkpoint policy plane, cost adds up here
An event carries the run, the step, the kind, the severity and the payload. It never carries a secret.
Data model
| Table | Holds |
|---|---|
workflows | The versioned ordered steps, and the trigger bindings. |
runs | One execution. A workflow run is the parent of its step runs. |
run_events | One append-only fact from a run. |
triggers | The start condition: kind, pattern, filter, target, input template, enabled flag. |
artifacts | One file or record a run produced, and the step that produced it. |
Risks
| Risk | Mitigation |
|---|---|
| A trigger loop starts runs without end, and it costs money | A budget per domain, a concurrency cap, a debounce, and an enabled flag on every trigger row |
| A retry repeats a side effect | Every side-effecting step carries an idempotency key, enforced at the tool layer |
| Run history grows until the table is slow | A retention window, and a rollup of old runs to a summary row |
| A run waits for an approval that never comes | Every approval carries a TTL, and expiry fails the run with a clear reason |
| Two engines appear, one for agents and one for workflows | One run table and one status model. This is checked in review |
Open questions
- Does a workflow support a parallel branch in version 1, or only a sequence? Parallel is where most of the complexity lives.
- How long is the default run retention, and what is kept after it?
- Can a person edit the input of a waiting run and resume it, or must they cancel and restart?
- Does a step failure fail the whole run by default, or does the workflow declare the policy per step?
Diagram source. ac-docs/diagrams/mission-control-layers.drawio, page mission-control-orchestration.
Edit that page, then run ./scripts/export-diagrams.sh mission-control-layers.
Update this page and the diagram together.