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: