Skip to main content
A workflow is a directed graph that defines a repeatable process for AI agents, shell commands, and human decisions. Unlike a DAG (directed acyclic graph), an Fabro workflow can and often does include loops — for example, implement-test-fix cycles that repeat until tests pass. You write workflows in Graphviz DOT, check them into version control, and run them with fabro run.

Anatomy of a workflow

Every workflow is a digraph with a goal, a start node, an exit node, and one or more processing nodes connected by edges:
Simple workflow: Start → Scan Files → Analyze → Exit
my-workflow.fabro
digraph MyWorkflow {
    graph [goal="Describe the project"]
    rankdir=LR

    start [shape=Mdiamond, label="Start"]
    exit  [shape=Msquare, label="Exit"]

    scan    [label="Scan Files", shape=parallelogram, script="find . -maxdepth 2 -type f | head -30"]
    analyze [label="Analyze", prompt="Review the file listing. Summarize the project structure.", shape=tab]

    start -> scan -> analyze -> exit
}
The goal attribute describes what the workflow accomplishes. Fabro uses it to guide agent behavior and generate retrospectives.

Key node types

Each node’s Graphviz shape determines how it executes. The three most important types are: Agents (default box shape) run an LLM with access to tools — bash, file editing, sub-agents — looping autonomously until the task is complete:
implement [label="Implement", prompt="Read plan.md and implement every step."]
Commands (parallelogram) run shell scripts and capture output for downstream nodes:
validate [label="Run Tests", shape=parallelogram, script="cargo test 2>&1 || true"]
Human gates (hexagon) pause the workflow and wait for a person to choose a path. Edge labels define the options:
approve [shape=hexagon, label="Approve Plan"]

approve -> implement [label="[A] Approve"]
approve -> plan      [label="[R] Revise"]
Fabro supports additional node types for one-shot prompts, conditional branching, parallel fan-out/fan-in, and more. See Stages and Nodes for the full reference.

Branching and loops

Branching and loop workflow
Edges can have conditions that route execution based on outcomes:
gate [shape=diamond, label="Tests passing?"]

gate -> exit      [label="Pass", condition="outcome=success"]
gate -> implement [label="Fix"]
Loops are natural — just point an edge back to an earlier node. Use max_visits on a node to prevent infinite loops:
fix [label="Fix Failures", prompt="Fix the failing tests.", max_visits=3]

Parallel execution

Parallel fan-out and merge workflow
Fan out to run branches concurrently, then merge the results:
fork [label="Fan Out", shape=component]
merge [label="Merge", shape=tripleoctagon]

fork -> security
fork -> architecture
fork -> quality
security    -> merge
architecture -> merge
quality     -> merge
merge -> report -> exit

Goal gates

Mark critical nodes with goal_gate=true. The workflow fails if any goal gate doesn’t succeed — even if execution reaches the exit node:
validate [label="Validate", prompt="Run the test suite and verify all tests pass.", goal_gate=true]

Running a workflow

From the CLI:
fabro run workflow.fabro
Or from a run config TOML for repeatable, parameterized runs:
fabro run run.toml
In the web UI, the Workflows page lists all available workflows. Click into a workflow to view its DOT definition, rendered graph diagram, and run history.
Fabro web UI Workflows list showing Fix Build, Implement Feature, Sync Drift, and Expand Product workflows
Fabro web UI workflow detail showing the DOT source for Fix Build
Fabro web UI workflow diagram showing the Fix Build workflow graph
Fabro web UI workflow runs tab showing run history for Fix Build
See the Quick Start to try it out, or browse the example workflows for real-world patterns.