The workflow
parallel.fabro
Fan-out with the fork node
Thefork node has shape=component, making it a parallel fan-out node. Every outgoing edge becomes a concurrent branch:
Fan-in with the merge node
Themerge node has shape=tripleoctagon, making it a merge (fan-in) node. It receives every branch’s status and context updates in parallel.results and synthesizes them with its prompt:
parallel.results is runtime context, not a parallel_results.json file in the checkout. Fan-in never selects a branch’s files or changes workspace state; every branch has already worked in the same checkout. The downstream report node writes the synthesis produced by fan-in as the final report.
Concurrency control
By default, Fabro runs up to 4 parallel branches simultaneously. Control this withmax_parallel:
Review a runtime candidate list
Static branches work when the review perspectives are known while writing the graph. A security scan often discovers its review candidates at runtime. Write that array to a flat context key, then usefor_each to run one reviewer per
candidate:
routing output schema merges context_updates.candidates into the flat
candidates context key. review_batch accepts that inline array or its
automatically offloaded managed artifact reference. It clones reviewer for
each item, appends the item as pretty JSON inside a fresh
<untrusted-{16 lowercase hex}> fence with a matching closing tag, and keeps
parallel.results in candidate order.
Each result has id="reviewer", a zero-based index, and an item_label
chosen from the item’s name, then label, then index. An empty candidate
array succeeds and proceeds directly to aggregate. Mixed success and failure
also proceeds; only an all-failed batch fails the parallel stage.
Retries and executor-enforced timeouts apply independently to each candidate.
A retry keeps the same result index and branch identity, and releases its
max_parallel slot while waiting for backoff. If a run stops partway through
the batch, resuming it reruns every item because per-item checkpoints are not
created.
What you’ve learned
- Fan-out nodes (
shape=component) spawn concurrent branches and wait for all of them for_eachruns one agent or prompt template for every item in a runtime array- Parallel branches share one checkout, so workflows must prevent or tolerate file races
- Fan-in nodes (
shape=tripleoctagon) can synthesizeparallel.resultswith a prompt - Fan-in never selects or restores workspace state, and no results file is created
Next
Multi-Model Routing
Assign different models to different workflow nodes using stylesheets.