Every node execution produces an outcome containing a status that drives edge routing, retry logic, and goal gate checks. This page defines the five statuses and the attributes that influence them.
The five statuses
| Status | Meaning |
|---|
success | The handler completed normally |
fail | The handler encountered an unrecoverable error |
partial_success | The handler did not fully succeed but produced usable results — typically from retries exhausted with allow_partial=true |
retry | The handler wants to re-execute — consumed by the retry loop and never appears in edge conditions |
skipped | The node was not executed (e.g. a branch not taken in a parallel fan-out) |
retry is internal to the engine. It triggers re-execution inside the retry loop and is never visible in edge condition expressions. The four externally-visible statuses are success, fail, partial_success, and skipped.
How handlers produce statuses
Each node type has its own rules for which statuses it can return:
| Handler | Produces | Conditions |
|---|
| Command | success, fail | success when exit code is 0; fail otherwise |
| Agent / Prompt | success, fail, partial_success, retry, skipped | Defaults to success. The LLM can set any status via a routing directive JSON object in its response. Backend errors produce retry (if retryable) or fail. |
| Parallel | success, partial_success, fail | Depends on the join_policy. wait_all: success if no failures, partial_success if some branches failed. first_success / k_of_n / quorum: success if threshold met, else fail. |
| Human | success | Always succeeds — the user’s selection becomes a routing signal via preferred_label |
| Conditional | success | Always succeeds — routing is handled by the engine’s edge selection |
| Start / Exit / Wait | success | Always succeed |
Retry loop
When a handler returns retry status, the engine enters the retry loop. If retry attempts remain (per the node’s retry policy), the handler re-executes after a backoff delay. If attempts are exhausted, the final status depends on allow_partial:
┌─────────────┐
│ Run handler │
└──────┬──────┘
│
▼
┌──────────┐ success/fail/
│ Status? │───partial_success/───▶ Done (use as-is)
└────┬─────┘ skipped
│ retry
▼
┌──────────────┐ yes ┌──────────────┐
│ Attempts │─────────▶│ Backoff + │──┐
│ remain? │ │ re-execute │ │
└──────┬───────┘ └──────────────┘ │
│ no │
▼ ┌──────────┘
┌──────────────┐ │
│allow_partial?│ │ (loops back to
└──────┬───┬───┘ │ "Run handler")
yes │ │ no │
▼ ▼
partial_ fail
success
Handler errors follow the same loop: retryable errors (transient infrastructure) re-execute if attempts remain; non-retryable errors (authentication, bad config) fail immediately without consuming retry attempts.
allow_partial
When allow_partial=true and the retry loop exhausts all attempts on a retry status, the outcome is promoted to partial_success instead of fail. This lets the workflow continue past nodes that could not fully succeed.
| Attribute | Type | Default |
|---|
allow_partial | Boolean | false |
implement [
label="Implement",
retry_policy="standard",
allow_partial=true,
prompt="Implement the feature."
]
In this example, if the agent returns retry and all 5 standard-policy attempts are used, the node finishes with partial_success rather than failing the run.
See Retry policies for the available presets and backoff settings.
auto_status
When auto_status=true, any non-success and non-skipped status is silently overridden to success after the handler completes. This is applied after the retry loop, so retries still happen normally — only the final outcome is overridden.
| Attribute | Type | Default |
|---|
auto_status | Boolean | false |
scan [
label="Scan",
shape=parallelogram,
auto_status=true,
script="find . -name '*.log' | head -20"
]
Use auto_status for nodes whose failure should never block the workflow — optional scans, best-effort cleanup steps, or informational commands where the output matters more than the exit code.
Goal gate interaction
Nodes marked with goal_gate=true are checked when the workflow reaches the exit node. A goal gate is satisfied if its last outcome was success or partial_success. Any other status (fail, skipped) causes the workflow to fail, even though execution reached the exit.
This means allow_partial=true on a goal gate node lets the gate pass even if the node exhausted its retries — the promoted partial_success counts as passing.
See Goal gates for retry target resolution and failure behavior.
Outcome in edge conditions
The four externally-visible statuses can be used in edge condition expressions via the outcome key:
gate -> deploy [label="Pass", condition="outcome=success"]
gate -> fix [label="Fix", condition="outcome=fail"]
gate -> review [label="Partial", condition="outcome=partial_success"]
gate -> skip [label="Skipped", condition="outcome=skipped"]
// Common pattern: treat partial as passing
gate -> deploy [condition="outcome=success || outcome=partial_success"]
gate -> fix [condition="outcome=fail"]
See Transitions for the full edge selection logic and operator reference.