← Back to Flow
AgentFlow
Workflow branches and joins
Defines how conditional and parallel workflow paths start, finish and combine without waiting forever or overwriting each other’s outputs.
branching-parallelism-joins
See how it helpsWhen is it useful?
Use it when a workflow has optional branches, simultaneous steps or a join whose completion rules are unclear.
What does it help you do?
- Distinguishes exclusive, inclusive and parallel branching.
- Waits only for branches actually activated by the split.
- Namespaces outputs and defines merge and failure policies.
Try asking this
Build an approval fork that skips legal review without blocking its join. Run one low-value and one high-value request. The first joins after finance alone; the second waits for every branch its rules actually activated.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Branching, Parallelism & Joins
Use this skill when designing or implementing decision nodes, multi-branch conditions, parallel fan-out/fan-in (AND/OR), dead-path elimination, and branch data merging in workflows.
Explicit Split Semantics (Van der Aalst Control-Flow Patterns)
Never leave branching behavior implicit. Every split node must declare its exact evaluation mode:
- Exclusive Choice (
XOR-Split/Switch/If-Else):- Evaluates ordered conditions deterministically (e.g., top-to-bottom priority) and activates exactly one outgoing branch.
- Always require or explicitly define a
default/elsebranch so an unmatched condition never leaves a run silently stuck with zero active tokens.
- Parallel Split (
AND-Split/Fork):- Activates all outgoing branches concurrently, giving each branch an isolated execution context.
- Multi-Choice (
OR-Split/ Inclusive Split):- Evaluates predicates for each outgoing port and activates the non-empty subset of branches whose predicates evaluate to
true(falling back to a declared default branch if none match).
- Evaluates predicates for each outgoing port and activates the non-empty subset of branches whose predicates evaluate to
Explicit Join Synchronization & Dead-Path Elimination (DPE)
A downstream join node must never guess how many incoming branches it should wait for:
- Simple Merge (
XOR-Join): Expects exactly one incoming branch from a mutually exclusive split; mark unchosen sibling branches asskipped. - Synchronizing
AND-Join(Wait All): Waits until every incoming branch reachessucceeded(or aborts/fails according to the declared failure policy:fail_fastvs.wait_all_then_report). - Synchronizing
OR-Join+ Dead-Path Elimination:- When an upstream
XOR-SplitorOR-Splitdoes not choose branch $B$, propagate askipped(dead-path) status down $B$ so downstreamOR-Joinnodes wait only for the branches that were actually activated, preventing permanent deadlocks.
- When an upstream
- First-Completed / Discriminator (
Wait Any / N-of-M):- Advances as soon as $K$ branches succeed, and explicitly cancels or marks the remaining in-flight sibling branches according to configuration.
Branch Output Scoping & Conflict-Free Merging
- Namespace step outputs by
nodeId(steps[nodeId].output) or require an explicit merge mapping at the join node so parallel branches never overwrite shared mutable variables through race conditions.
Checklist
- Does every conditional split define deterministic evaluation order and an explicit
default/elsepath? - Does every join node explicitly specify
XOR(one),AND(all active), orN-of-Msynchronization plus failure behavior? - Does Dead-Path Elimination mark unchosen branches
skippedso downstream joins never deadlock waiting for them? - Are parallel branch outputs isolated by
nodeIdor merged deterministically without shared-variable races?
Included files 1
SKILL.md
