Edges and conditions
How edge conditions control pipeline flow based on step results.
Edges connect steps in a pipeline and define the execution order. Each edge has a condition that determines whether it should be followed based on the result of the source step.
Edge conditions
There are five edge conditions, stored as a pipeline_edge_condition enum in the database:
| Condition | DB value | Follows when |
|---|---|---|
| Always | always | Always follows, regardless of pass/fail |
| On Pass | on_pass | Source step returned passed: true |
| On Fail | on_fail | Source step returned passed: false |
| On Review Pass | on_review_pass | Source step returned passed: true (review context) |
| On Review Fail | on_review_fail | Source step returned passed: false (review context) |
Condition evaluation
The executor evaluates conditions using a simple boolean check:
always-- always satisfiedon_passandon_review_pass-- satisfied whenpassed == trueon_failandon_review_fail-- satisfied whenpassed == false
When a step completes, the executor filters outgoing edges to those whose condition is satisfied and follows the first matching edge. If no edge matches, execution ends.
// Pseudocode
for edge in outgoing_edges(current_step):
if edge.condition.is_satisfied(result.passed):
next_step = edge.target_step
breakDefault condition
When creating an edge via the API, the condition field defaults to always if omitted.
Gate feedback flow
Gate steps play a special role in edge condition evaluation. When a gate step fails:
- The gate's evaluation output is stored as
gate_feedbackin the pipeline context. - The
ticket_sourceis updated to the gate's role name (e.g.,"reviewer"). - The
on_failedge is followed to the next step. - If the next step is an agent, it receives the gate feedback so it knows what to fix.
This pattern enables review-and-revise loops without creating actual graph cycles (which are forbidden). Instead of looping back, you chain multiple agent-gate pairs:
Developer --> Gate --> (on_fail) --> Developer2 --> Gate2 --> Terminal
(on_pass) --> TerminalThe same feedback mechanism applies to cron and lambda steps: when they fail, their output is stored as gate_feedback for the next step.
Common DAG patterns
Linear pipeline
The simplest pattern. Steps execute in sequence.
Agent A --always--> Agent B --always--> TerminalPass/fail branching
Route to different paths based on step results.
Developer --on_pass--> Reviewer --on_pass--> Terminal (Done)
--on_fail--> Terminal (Failed)
--on_fail--> Terminal (Failed)Diamond (fan-out / fan-in)
Split work across parallel paths that converge.
Entry --always--> Left Path --always--> Done
--always--> Right Path --always--> DoneNote: the executor follows edges sequentially (first match), so a "diamond" pattern means the executor will take one branch based on the first matching condition, not run both in parallel. True fan-out requires always conditions on multiple edges from the same step, but only the first match is followed.
Gate review pattern
Use gate steps to validate agent output before proceeding.
Developer --on_pass--> Quality Gate --on_pass--> Terminal (Done)
--on_fail--> TerminalFail (Rejected)Multi-stage review
Chain multiple agent-gate pairs for iterative refinement:
Implement --always--> Review Gate --on_pass--> Deploy --always--> Terminal
--on_fail--> Revise --always--> Final Gate --on_pass--> Terminal
--on_fail--> TerminalFailCreating edges via API
# Create an edge with on_pass condition
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source_step_id": "STEP_A_UUID",
"target_step_id": "STEP_B_UUID",
"condition": "on_pass"
}' \
https://your-instance.com/api/v1/pipelines/$PIPELINE_ID/edgesValidation
source_step_idandtarget_step_idmust refer to different steps (self-loops are rejected).- Both steps must belong to the specified pipeline.
Next steps
- DAG validation -- All validation rules your pipeline must satisfy
- Step types -- What each step type does