A first workflow
A workflow is a named recipe — an ordered list of steps, each one a capability invocation or a control-flow node, addressed by a single id when something fires it. The shape:workflow.json
$.input.* references read from the arguments passed when the workflow is fired. Step two’s runQuery can also reference outputs from step one — the runtime threads results between steps so each one can build on the previous one’s output without you wiring it up by hand.
The mental model: a directed action graph
Think of a workflow as a directed graph of actions with the runtime as the executor. You declare what should happen; the runtime decides when each step runs, what it inherits from earlier steps, and what to do if a step fails. The graph is usually a straight line, but branching is supported — a step can declare awhen predicate that gates whether it runs based on an earlier step’s output.
Two properties matter:
- Steps share a result envelope. Each step writes to the run’s result map under its action name. Later steps reference earlier outputs by path — no glue code, no manual passing of return values.
- The runtime owns retry and audit. A failed step retries on the platform’s schedule, not yours. Every step appends to the run’s audit chain.
Workflow vs capability vs agent
These three are the platform’s three units of work and it is easy to confuse them. The simplest mental rule: a capability is “do this one thing”; a workflow is “do these things together”; an agent is “do this work without a request behind it.”What triggers a workflow
Workflows are fired, not “called.” Three things fire them.Runs
Every fire is a run. A run has a stable id, a status that walks the same lifecycle as agent runs (pending, running, completed, failed), and an inputs/outputs envelope you can fetch after the fact. Failed runs are not silently dropped — the run record persists with the failing step, its error, and any retries the runtime attempted.
Runs that originate from an agent are linked back to the agent run. The audit chain records the parent, so an operator inspecting an agent’s run can drill into each workflow it triggered.
Idempotency at the workflow level
A workflow that fires twice with the same input — a network retry on the trigger side, a double-submit from a page — must not charge the card twice. The runtime tracks workflow runs by(workflow_id, input_hash) for a 24-hour window: the second fire returns the result of the first run, marked replayed, and does not re-execute any steps. The mechanism mirrors the API idempotency model but is keyed on the workflow’s input rather than an Idempotency-Key header.
For runs where the input legitimately should re-execute — same input but a deliberate retry — pass an explicit dedupe_key field on the trigger to scope the dedupe window to that key.