diff --git a/agents/how-agents-work.mdx b/agents/how-agents-work.mdx
index 078a4d6..ab5283c 100644
--- a/agents/how-agents-work.mdx
+++ b/agents/how-agents-work.mdx
@@ -15,8 +15,8 @@ attacker actually get there?
## How a run proceeds
-1. **The agent receives a task.** In chat that's your message; in a workflow it's a briefing composed by the
- orchestrator.
+1. **The agent receives a task.** In chat that's your message; in a workflow it's the task Console composes
+ for that step.
2. **It reasons and calls tools.** Each call returns a result it reads before deciding the next step.
3. **It may load a skill** with `activate_skill` when it hits a task a documented procedure covers.
4. **It may delegate** with `spawn_agent`, handing focused work to a child and waiting for the summary.
@@ -50,12 +50,6 @@ between agents.
You can watch the tree live — as a nested view in the CLI, and in the web console's chat while a turn runs.
-### Forcing sequential delegation
-
-Set [`sequential-spawns: true`](/agents/writing-an-agent#sequential-spawns) when steps depend on each other
-and the agent must see one result before starting the next. Console's `workflow-runner` uses exactly this to
-guarantee workflow steps run in order.
-
## Where agents come from
| Source | Description |
@@ -63,7 +57,7 @@ guarantee workflow steps run in order.
| **Platform agents** | The library Console ships. See [the agent library](/agents/library). |
| **Organization agents** | Agents your team writes, in the web console or the CLI. |
-Both appear together wherever agents are listed, and the workflow orchestrator treats them identically. An
+Both appear together wherever agents are listed, and a workflow treats them identically. An
organization agent whose `name` matches a platform agent **shadows** it — the supported way to customize
built-in behavior.
diff --git a/agents/library.mdx b/agents/library.mdx
index f4b440d..a2edbcc 100644
--- a/agents/library.mdx
+++ b/agents/library.mdx
@@ -37,12 +37,20 @@ defined budget so the results stay reviewable.
These two are the ends of a loop worth understanding: `detection-author` turns a one-time discovery into a
permanent rule, and `detections-runner` is what applies every rule you've accumulated from then on.
-## Review
+## Patching
| Agent | What it does |
| --- | --- |
-| `code-reviewer` | Reviews code for security vulnerabilities, performance issues, and best practices. |
-| `security-analyzer` | Deep security analysis with taint tracking and vulnerability assessment. |
+| `patch-generator` | Generates a verified patch for one detection's findings in one file: edits the file, re-runs the detection to confirm the fix, captures the diff, and records it. |
+
+Add it as its own step after any agent that produces findings — `detections-runner`, a vulnerability
+scanner, or one of your own. It [consumes findings grouped by detection and file](/agents/writing-an-agent#group-by)
+by default, so it runs once per (detection, file) pair rather than once per individual match.
+
+
+ Patch generation used to be a setting on `detections-runner` itself. It's its own step now — if your
+ workflow used the old setting, Console already added `patch-generator` as a step for you.
+
## Agents spawned by other agents
@@ -51,28 +59,22 @@ steps:
| Agent | Spawned by | Role |
| --- | --- | --- |
-| `patch-generator` | `detections-runner`, when patch generation is enabled | Generates a verified patch for one detection's findings in one file: edits the file, re-runs the detection to confirm the fix, captures the diff, and records it. |
| `policy-evaluator` | `detections-runner` | Evaluates one policy detection against the repository, bound to that detection so every finding links back to it. |
| `policy-fix-verifier` | `patch-generator` | Independently judges whether a patched file still violates a policy. Deliberately read-only — it returns a verdict and cannot report findings or edit code. |
You *can* name one as a workflow step, but they expect a briefing their usual parent provides, so they work
best left to it.
-## The orchestrator
-
-`workflow-runner` is the agent that executes workflows: it reads a workflow's description and steps, spawns
-each step's agent in order, and composes each briefing. You don't add it to a chain — it *is* the chain. See
-[the agent chain](/workflows/agent-chain) for how it composes briefings.
-
## Common chains
| Goal | Chain |
| --- | --- |
-| Fast pull request check | `vulnerability-scanner-basic` |
-| Standard pull request review | `vulnerability-scanner-standard` |
+| Fastest signal | `vulnerability-scanner-basic` |
+| Balanced scan | `vulnerability-scanner-standard` |
+| Deepest audit | `vulnerability-scanner-comprehensive` |
| Turn findings into permanent rules | `vulnerability-scanner-standard` → `detection-author` |
| Apply everything you've already vetted | `detections-runner` |
-| Deep audit | `vulnerability-scanner-comprehensive` → `security-analyzer` |
+| Apply everything you've already vetted, and patch it | `detections-runner` → `patch-generator` |
## Next steps
diff --git a/agents/overview.mdx b/agents/overview.mdx
index 95f94b0..de0f3b2 100644
--- a/agents/overview.mdx
+++ b/agents/overview.mdx
@@ -29,8 +29,9 @@ Telling them apart is the most common early stumble:
## Yours are first-class
Console ships a library of agents and skills to start from. Detections are yours to build up — nothing is
-prebuilt there. Anything you write sits alongside the built-ins with no second-class status — the orchestrator that runs workflows treats platform and organization agents
-identically, briefing both from their stated `description`.
+prebuilt there. Anything you write sits alongside the built-ins with no second-class status — a workflow
+runs platform and organization agents identically, and both are picked from the same list by their stated
+`description`.
An agent you write with the same name as a built-in one **shadows** it. That's the supported way to
customize built-in behavior without breaking workflows that already reference that name.
diff --git a/agents/tool-reference.mdx b/agents/tool-reference.mdx
index 1db8e6f..91fd111 100644
--- a/agents/tool-reference.mdx
+++ b/agents/tool-reference.mdx
@@ -100,6 +100,9 @@ See [what agents can read](/data/what-agents-can-read) for what that covers and
| `report_finding` | Records a confirmed vulnerability, with evidence. This is what makes a result durable rather than conversational. |
| `list_findings` | Lists findings already recorded. |
| `report_patch` | Attaches a verified remediation patch (a unified diff) to the finding(s) it fixes. Call it only after editing the file **and** confirming the fix. It stores the patch; it does not verify. |
+| `emit_artifact` | Records a result of a kind your agent declares in [`produces:`](/agents/writing-an-agent#contracts-what-a-step-produces-and-consumes) — Console's own kinds or one you've defined yourself. Rejects `amplify:finding`: findings always go through `report_finding` instead. |
+| `list_artifacts` | Lists recorded artifacts, optionally filtered by kind. |
+| `get_artifact` | Fetches one artifact's full content by id. |
## Detections
diff --git a/agents/writing-an-agent.mdx b/agents/writing-an-agent.mdx
index eb7dce4..993d52d 100644
--- a/agents/writing-an-agent.mdx
+++ b/agents/writing-an-agent.mdx
@@ -49,22 +49,26 @@ That's the entire contract. No build step, no registration.
| `allowed-tools` | No | string[] | Restricts the agent to these tools. Omit to inherit. |
| `maxIterations` | No | positive int | Budget of reasoning↔tool cycles before the agent is stopped. |
| `timeout` | No | positive int (ms) | Wall-clock limit for one execution. |
-| `sequential-spawns` | No | boolean | Rejects concurrent `spawn_agent` calls, forcing one child at a time. |
+| `produces` | No | list | The kinds of result this agent's step may record. See [contracts](#contracts-what-a-step-produces-and-consumes) below. |
+| `consumes` | No | list | The kinds this agent's step reads, and how. See [contracts](#contracts-what-a-step-produces-and-consumes) below. |
+| `mutates-worktree` | No | boolean | Declares that this agent edits files in the repository. See below. |
-### The description is read at runtime
+### Why the description matters
-The description does real work. When a workflow runs your agent, the orchestrator reads the description to
-compose that step's briefing and reflects the agent's stated role back at it. Other agents deciding whether
-to delegate see only the name and description, so those two lines are the whole interface.
+Two audiences read `description`, and neither is your agent itself:
-A vague description produces a vague briefing. Write it as a precise statement of what the agent does and
-what it produces:
+- **You, choosing agents for a workflow** — the [workflow editor](/workflows/create-a-workflow#agents) and
+ the [agent library](/agents/library) show it as the one-line summary of what an agent does.
+- **Other agents, deciding whether to delegate to it** — an agent choosing a sub-agent to spawn sees only its
+ name and description, so those two lines are the entire interface it has to go on.
+
+Write it as an external, precise statement of the job and its output — not a note to yourself:
```yaml
# Good — states the job and the output
description: Audits third-party dependencies for known-vulnerable versions and unmaintained packages, and reports each one as a finding.
-# Too vague to brief against
+# Too vague to be useful to anyone deciding whether to use this agent
description: Dependency helper.
```
@@ -87,14 +91,132 @@ Both are ceilings, not targets. Leave them unset unless the agent is an outlier.
- Raise `timeout` for **orchestrators**, whose wall clock includes every child they spawn. Set it above the
worst-case sum of the children's durations.
-### `sequential-spawns`
+## Contracts: what a step produces and consumes
+
+When you chain agents into a [workflow](/workflows/create-a-workflow), Console needs to know which step's
+output feeds which step's input, so it can run steps that don't depend on each other together, wait for the
+ones that do, and skip a step that has nothing to work on. You declare that with `produces` and `consumes`.
+
+### `produces`
+
+The kinds of result this agent's step may record:
+
+```yaml
+produces:
+ - kind: amplify:finding
+```
+
+`produces` is a *may*, never a promise — an agent that looked thoroughly and found nothing has still done
+its job, and nothing checks that a declared kind was actually emitted.
+
+A kind is either one of Console's own (prefixed `amplify:`, like `amplify:finding` or `amplify:patch`) or one
+you define yourself. See [defining your own kind](#defining-your-own-kind) below.
+
+### `consumes`
+
+The kinds this agent's step reads, and how it wants them delivered:
+
+```yaml
+consumes:
+ - kind: amplify:finding
+ mode: each
+```
+
+| Field | Required | What it does |
+| --- | --- | --- |
+| `kind` | Yes | The kind this step reads. |
+| `mode` | No | `each` or `all`. Defaults to `all`. |
+| `group-by` | No | Only with `mode: each`. See below. |
+
+**`mode: all`** (the default) runs your agent once, with everything matching that kind from earlier in the
+chain — including an empty set. Use this for a step whose job is to summarize or report on the whole run:
+"no issues found" is itself a result worth producing, so it needs to run even when there's nothing to say.
+
+**`mode: each`** runs a separate copy of your agent per item (or per group, if you set `group-by`). Zero
+items means the step doesn't run at all — it's recorded as [skipped](/workflows/running#run-statuses), not
+as having run and found nothing. Use this when your agent's job only makes sense one item at a time, like
+generating a fix for a single bug.
+
+
+ A step can only consume a kind that an earlier step in the same workflow actually produces. Console checks
+ this when you save the workflow, not when it runs.
+
+
+### `group-by`
+
+For a `mode: each` step, `group-by` controls what counts as "one item." By default every result is its own
+item; naming fields under `group-by` batches results that share the same values into a single item instead.
+
+`patch-generator`, Console's built-in patching agent, is the canonical example — one patch should fix every
+match of the same underlying issue in the same file, not one patch per individual match:
+
+```yaml
+consumes:
+ - kind: amplify:finding
+ mode: each
+ group-by: [detection_id, properties.filePath]
+```
+
+Names in `group-by` come from the kind you're consuming — never from anything about how Console stores it:
+
+- **A field the kind itself declares**, including one nested inside another declared field, like
+ `properties.filePath` above.
+- **A documented attribute of that kind.** `amplify:finding` additionally exposes `detection_id` and
+ `severity` this way.
+- **`id`** — every item is its own group, overriding any default grouping. `amplify:finding` already groups
+ by detection and file when you set no `group-by` of your own, so write `group-by: [id]` explicitly if you
+ want one child per finding instead.
+
+An empty `group-by: []` isn't allowed: grouping by nothing means everything is one group, which is what
+`mode: all` already means. Console rejects it and suggests `[id]` if that's what you meant.
+
+
+ A result your grouping can't place — a finding with no detection behind it, say — is left out of that
+ step, with the reason recorded on the step. It still reaches any other step consuming the same kind with
+ `mode: all`.
+
+
+### `mutates-worktree`
+
+Set this to `true` if your agent edits files in the repository:
+
+```yaml
+mutates-worktree: true
+```
+
+This states a fact, not a scheduling request. Console uses it to make sure two steps that both edit the
+checkout never run at the same time and clobber each other's changes. Leave it unset (the default) for an
+agent that only reads.
+
+### Defining your own kind
+
+If `produces` names a kind that doesn't already exist in your organization, attach a `schema:` block and
+Console registers it the moment you save the agent — no separate setup step:
+
+```yaml
+produces:
+ - kind: scan-report
+ schema:
+ fields:
+ verdict:
+ type: string
+ enum: [clean, issues-found]
+ total_findings:
+ type: integer
+```
+
+Each field has a `type` (`string`, `number`, `integer`, `boolean`, `object`, or `array`) and can be marked
+`required`. A `string` field can restrict its values with `enum`; an `object` field declares its own nested
+`fields`; an `array` field declares the shape of its `items`.
-By default an agent may spawn several sub-agents at once. Setting `sequential-spawns: true` makes a second
-concurrent spawn return an error instead of queuing, which forces the agent to observe each child's result
-before starting the next.
+Saving the identical schema again is a no-op. Changing an already-registered kind's shape is not allowed —
+Console rejects the save rather than reinterpreting artifacts you've already recorded under the old shape.
+If a kind's shape needs to change, give it a new name.
-Use it for orchestrators whose steps depend on each other. It applies only to the agent that declares it —
-children are free to fan out.
+
+ Names starting with `amplify:` are reserved for Console's own kinds. You can *consume* `amplify:finding`
+ or `amplify:patch` in your own agents, but you can't register a `schema:` under that prefix.
+
## Writing one in the web console
diff --git a/quickstart.mdx b/quickstart.mdx
index e4b2cb2..13413d0 100644
--- a/quickstart.mdx
+++ b/quickstart.mdx
@@ -77,8 +77,9 @@ Open **Workflows** and click **New workflow**.
Click **Save**.
-Console's orchestrator reads the description as the goal and briefs your agent against it, so write it as an
-instruction. See [create a workflow](/workflows/create-a-workflow#description).
+The description is just a summary for your own reference — the agent you wrote in step 3 already carries
+its own instructions, and those are what actually run. See
+[create a workflow](/workflows/create-a-workflow#description).
## 5. Run it
diff --git a/workflows/agent-chain.mdx b/workflows/agent-chain.mdx
index 25ccda7..a263b13 100644
--- a/workflows/agent-chain.mdx
+++ b/workflows/agent-chain.mdx
@@ -1,56 +1,46 @@
---
title: The agent chain
-description: 'How workflow steps run in sequence, pass results forward, and how to order them.'
+description: 'How workflow steps depend on each other, pass results forward, and how to order them.'
---
## How the chain runs
-The agents you add to a workflow form an ordered chain. When a run starts, an orchestrating agent takes your
-workflow definition and drives it:
-
-1. It reads your **description** as the goal of the whole workflow.
-2. It walks the chain **in declared order**, spawning one agent at a time.
-3. For each step it composes a briefing from the workflow's intent, that agent's role, what triggered the run
- (for a pull-request run: the PR number, head and base commits, the diff), and the relevant parts of earlier
- steps' results.
-4. It **waits** for each step to finish before starting the next.
-5. When every step succeeds, it writes a short summary of what each step did and how the results chained
- together.
-
-Steps run strictly in sequence, so each one can see what the previous step produced.
+The agents you add to a workflow form a chain, and what each one **[produces and consumes](/agents/writing-an-agent#contracts-what-a-step-produces-and-consumes)**
+decides how it actually runs:
+
+1. A step becomes eligible to run once every step it depends on has **settled** — either finished normally or
+ been legitimately [skipped](/workflows/running#run-statuses). A step with nothing it depends on is eligible
+ immediately.
+2. **Steps with no dependency between them may run at the same time.** The order you drag them into sets which
+ *earlier* steps a later one is allowed to draw on — a step can only consume a kind an earlier step in the
+ list produces — but it doesn't by itself force one step to wait for another that it doesn't actually need.
+3. **Two steps that both edit the repository never run at the same time**, whether or not they depend on each
+ other — they'd be racing on the same checkout. This is `mutates-worktree` on the agent, not something you
+ configure per workflow.
+4. Each step is told what triggered the run (for a pull-request run: the PR number, head and base commits,
+ the diff) and reads the actual results earlier steps recorded of the kinds it consumes — not a text summary
+ of what an earlier step said it did.
+5. **If a step fails, nothing that depends on it runs, and the run ends in error.** Workflow steps do not
+ retry by default.
- If a step fails, the run **stops immediately** and later steps do not run. Workflow steps do not retry by
- default. Design chains so the expensive, broad step comes first and the steps that depend on it come after.
+ A step whose input turns out to be empty runs **zero times** and is recorded as **skipped** — a distinct
+ outcome from *failed* and from *ran and found nothing*. See [run statuses](/workflows/running#run-statuses).
## Passing results between steps
-You don't wire inputs and outputs together by hand. Each agent returns a summary of what it did, and the
-orchestrator quotes the relevant parts of that summary into later steps' briefings verbatim.
-
-In practice this means a two-step chain works because the second agent is *told* what the first one found —
-for example, a scanner reports findings to a manifest, and the next agent is briefed on where that manifest is
-and what's in it.
+You don't wire inputs and outputs together by hand. What flows from one step to the next is exactly what the
+consuming agent's `consumes` names — the actual results (findings, patches, or a kind of your own) that an
+earlier step's `produces` recorded, not a prose account of what happened.
What this does **not** do is let you transform or filter results between steps. If you need different
handling, that belongs inside an agent, not between them.
-## The briefing is why descriptions matter
-
-Two descriptions shape every step's briefing:
-
-- **The workflow's description** — quoted as the overall intent.
-- **Each agent's `description`** — reflected back at the agent to confirm its role.
-
-A vague description on either produces a vague briefing. This is the most common reason a chain
-underperforms, and it's usually fixed by editing prose rather than by changing agents. See
-[writing an agent](/agents/writing-an-agent#the-description-is-read-at-runtime).
-
## Choosing agents
Any agent can be a step — Console's or your own. Your organization's agents appear in the picker alongside the
-built-in ones, and the orchestrator treats them identically.
+built-in ones, and Console treats them identically.
- For what ships with Console and what each is for, see [the agent library](/agents/library).
- To write your own, see [writing an agent](/agents/writing-an-agent).
@@ -63,8 +53,10 @@ A few agents in the library are designed to be spawned *by* other agents rather
The rules of thumb:
- **Broad before narrow.** Discover first, then act on what was discovered.
-- **Expensive before dependent.** If a step fails, everything after it is skipped — so put the step most
- likely to fail where it costs least.
+- **Declare what a step actually needs.** Two steps that don't consume each other's output can run
+ concurrently; a step only waits on the steps its `consumes` names.
+- **Expensive before dependent.** If a step fails, nothing depending on it runs — so put the step most likely
+ to fail where it costs least.
- **One step is a valid chain.** A single scanner plus an [output](/workflows/outputs) is a complete, useful
workflow. Don't add steps for symmetry.
@@ -72,11 +64,12 @@ The rules of thumb:
| Goal | Chain |
| --- | --- |
-| Fast pull request check | `vulnerability-scanner-basic` |
-| Standard pull request review | `vulnerability-scanner-standard` |
+| Fastest signal | `vulnerability-scanner-basic` |
+| Balanced scan | `vulnerability-scanner-standard` |
+| Deepest audit | `vulnerability-scanner-comprehensive` |
| Turn findings into permanent rules | `vulnerability-scanner-standard` → `detection-author` |
| Apply everything you've already vetted | `detections-runner` |
-| Deep audit | `vulnerability-scanner-comprehensive` → `security-analyzer` |
+| Apply everything you've already vetted, and patch it | `detections-runner` → `patch-generator` |
## Editing a chain
diff --git a/workflows/artifacts.mdx b/workflows/artifacts.mdx
index 15b293a..c58222b 100644
--- a/workflows/artifacts.mdx
+++ b/workflows/artifacts.mdx
@@ -47,10 +47,14 @@ This model is deliberately open-ended: an artifact is *a set of files an agent p
optional linkage to the findings it relates to*. Nothing about it is specific to security. A risk assessment,
a compliance report, a threat model, a generated test suite are all describable in the same shape.
+Console ships several kinds of its own — findings and patches among them — but your own agents can define
+and record their own, with no setup outside the agent's own definition. See
+[defining your own kind](/agents/writing-an-agent#defining-your-own-kind) for how to declare one.
+
- Today the only artifact kind produced in practice is the **patch**. The model is general, but patch
- generation is the one producer that's wired up. Treat the broader shape as where this is heading, not as a
- set of features to build against right now.
+ A kind's shape is fixed once it's registered. Saving the identical shape again is a no-op; changing it is
+ rejected outright, so a kind never silently reinterprets artifacts you've already recorded under the old
+ shape. If a kind's shape needs to change, give it a new name.
## Getting results out
diff --git a/workflows/create-a-workflow.mdx b/workflows/create-a-workflow.mdx
index fb13041..c6509df 100644
--- a/workflows/create-a-workflow.mdx
+++ b/workflows/create-a-workflow.mdx
@@ -35,29 +35,26 @@ pull requests.
## Description
-A short statement of what the whole workflow is for.
+A short statement of what the whole workflow is for — shown in the workflow list and in run history so
+your team can tell workflows apart at a glance.
-This is the most important field in the editor, and the easiest to underestimate. Console runs your
-chain through an orchestrating agent, and that orchestrator:
-
-1. Reads the description as the **intent** of the entire workflow.
-2. Composes a briefing for each step, quoting the description so the agent knows the larger goal.
-3. Passes the relevant parts of earlier steps' results into later steps.
-
-The description is the instruction that shapes every step's task, so write it as a goal, in plain language.
+It doesn't shape what any step does. Each agent in the chain already carries its own instructions, and runs
+the same way whether it's the only step or one of many — write the description for the humans who'll read
+the workflow list, not as an instruction to the chain:
**Good:**
-> Scan the pull request for injection and access-control vulnerabilities, then generate a patch for
-> anything confirmed exploitable and post it as a review comment.
+> Scans pull requests for injection and access-control vulnerabilities, patches anything confirmed
+> exploitable, and posts the result as a review comment.
-**Too vague:**
+**Too vague to tell apart from your other workflows:**
> Security workflow.
- If your description and your agent chain disagree, the chain wins — the orchestrator runs the steps
- as declared and notes the disagreement in its summary. Keep the two aligned.
+ If you want a step to behave differently, change that agent or its own `description` — see
+ [writing an agent](/agents/writing-an-agent). The workflow description is documentation, not an
+ instruction.
## Triggers
@@ -79,16 +76,17 @@ See [Triggers](/workflows/triggers) for the full details.
*Required.* The ordered chain of agents that does the actual work.
Click the **+** button to search the agent library and add an agent. Each one becomes a step, drawn as
-a pill with an arrow to the next — the chain reads left to right, and that's the order it runs in.
+a pill with an arrow to the next — the chain reads left to right.
- **At least one** agent, **at most twenty**.
- **Reorder** by dragging a pill.
- **Remove** a step by clicking the grip icon on its pill and choosing *Remove from chain*.
-Steps run strictly one at a time. Each waits for the previous one to finish, and if any step fails the
-run stops there — later steps don't run.
+The order you drag steps into sets which *earlier* steps a later one can draw on — see
+[the agent chain](/workflows/agent-chain) for how that actually determines when each step runs. If any
+step fails, nothing depending on it runs and the run ends in error.
-See [The agent chain](/workflows/agent-chain) for how sequencing works, and [the agent library](/agents/library) for which agents to use.
+See [the agent library](/agents/library) for which agents to use.
## Output
diff --git a/workflows/overview.mdx b/workflows/overview.mdx
index 9b8264b..9a23f29 100644
--- a/workflows/overview.mdx
+++ b/workflows/overview.mdx
@@ -25,15 +25,15 @@ Every workflow is made of four parts. Only the first two are required.
| Part | Required | What it does |
| --- | --- | --- |
| **Name** | Yes | Identifies the workflow. Must be unique in your organization. |
-| **Description** | Yes | States the workflow's *intent*. The orchestrating agent reads it and briefs every step against it. |
+| **Description** | Yes | A short summary of the workflow's purpose, shown in the workflow list and run history. |
| **Agents** | Yes | The ordered chain of agents to run. At least one, at most twenty. |
| **Triggers** | No | When the workflow fires automatically. Manual runs are always available without a trigger. |
| **Outputs** | No | Where the results go when the run finishes. Attach as many destinations as you need. |
- Console's orchestrator reads the description as the goal of the whole workflow and quotes it into each
- agent's briefing, so a vague description produces vague step instructions. See
- [Create a workflow](/workflows/create-a-workflow#description) for how to write one.
+ The description documents the workflow for your team — it doesn't shape what any step does. Each agent
+ already carries its own instructions, which is what actually runs. See
+ [Create a workflow](/workflows/create-a-workflow#description).
## What happens during a run
@@ -45,9 +45,10 @@ When a workflow fires, Console does the following for **each** repository you ta
are at that moment. Editing the workflow later never changes a run that is already in flight.
3. **Provisions an isolated sandbox** and clones the repository into it. For pull-request runs, it
clones the pull request's head — not the default branch.
-4. **Runs the chain in order.** An orchestrating agent spawns each step's agent one at a time, waits
- for it to finish, and passes the relevant parts of earlier steps' results into the next briefing.
-5. **Stops on failure.** If a step fails, the run stops there and later steps do not run.
+4. **Runs the chain.** Each step runs once the steps it actually depends on have finished (or been
+ legitimately skipped) — independent steps can run at the same time; see
+ [the agent chain](/workflows/agent-chain) for exactly how steps depend on each other.
+5. **Stops on failure.** If a step fails, nothing depending on it runs, and the run ends in error.
6. **Records findings** from the run, and **dispatches your outputs** once the run completes.
Targeting three repositories produces three independent runs — one per repository — not one run that
@@ -68,7 +69,7 @@ loops. Each gets its own sandbox, and one failing does not stop the others.
- How steps run in sequence and how to order them.
+ How steps depend on each other and how to order them.
diff --git a/workflows/running.mdx b/workflows/running.mdx
index fc2db8e..fb5ecf9 100644
--- a/workflows/running.mdx
+++ b/workflows/running.mdx
@@ -37,7 +37,9 @@ organization; filter it by **status** or by **workflow name**.
Open a run to see:
- **The chain** — each step drawn in order with its agent name, how long it took, and its status icon.
- Steps light up as they complete, so you can watch progress on a running workflow.
+ Steps light up as they complete, so you can watch progress on a running workflow. A step that fanned out
+ into more than one agent run shows the count (`×3`); hover a **Skipped** step to see why, in the run's own
+ words — for example, no findings had been produced yet, or none matched what that step groups by.
- **Findings** — what the run confirmed, linked through to the full finding.
- **Outputs** — each configured destination and whether it was delivered. See
[checking delivery](/workflows/outputs#checking-delivery).
@@ -51,10 +53,17 @@ A run page refreshes itself while the run is active, so you can leave it open.
| --- | --- |
| **Pending** | Queued. Console is provisioning a sandbox and cloning the repository. |
| **Running** | The agent chain is executing. |
-| **Completed** | Every step finished successfully and outputs were dispatched. |
-| **Error** | A step failed. The run stopped there and later steps did not run. |
+| **Completed** | Every step finished — or was legitimately skipped — and outputs were dispatched. |
+| **Error** | A step failed. Nothing depending on it ran. |
| **Cancelled** | Cancelled by you, or superseded by a newer run from the same trigger. |
+
+ An individual step can also show **Skipped** — its input was empty, or nothing in it matched what the
+ step [groups by](/agents/writing-an-agent#group-by). A skipped step is not a failure: the run around it
+ still completes normally. It's a separate, distinct outcome from a step that ran and simply found
+ nothing to report.
+
+
## Cancel a run
Open the run and click **Cancel**. Console stops the agent chain and tears down the sandbox.
@@ -66,8 +75,9 @@ rather than passing.
## Reading a failed run
-A run ending in **Error** stops at the failing step. Open it and look at the chain: the step with the
-error icon is where it stopped, and everything to its right never ran.
+A run ending in **Error** has a step with the error icon — that's where something failed. Any step that
+depended on it never ran at all; an independent step elsewhere in the chain may have already finished
+before the failure landed, and keeps its own result.
Common causes: