# Fabro Create Workflow

> Create Fabro workflow DOT graphs and TOML run configurations from natural language requirements. Use when the user wants to create a new workflow, build a pipeline, design a multi-step agent process, or write a .fabro or .toml file for Fabro. Covers topology selection, node types, model assignment, edge routing, and run configuration.

- Skill: `natea/fabro-create-workflow` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add natea/fabro-create-workflow`
- Raw SKILL.md: https://api.skillmd.com/api/skills/natea/fabro-create-workflow/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: natea (https://skillmd.com/u/natea)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/natea/fabro-create-workflow

---


# Fabro Create Workflow

Turn requirements into a runnable Fabro workflow: a `.fabro` graph file defining the pipeline structure and an optional `.toml` run configuration.

## Workflow

### Step 1: Fetch Current Model Catalog

Run `fabro model list` to get available models and providers. Never guess model IDs or provider names -- they change frequently.

### Step 2: Understand Requirements

Clarify what the workflow should accomplish:
- What is the end goal?
- What tools or languages are involved?
- Does it need human approval gates?
- Should multiple models or providers be used?
- Is parallelism needed (e.g., multi-perspective review, ensemble)?
- Does it need a verify/fix loop?
- What sandbox environment is appropriate (local, docker, daytona)?

### Step 3: Choose Topology

Pick the simplest topology that satisfies the requirements. See `references/example-workflows.md` for complete examples of each pattern.

| Pattern | When to use |
|---|---|
| **Linear** | Simple sequential steps, no branching |
| **Command-then-analyze** | Shell output feeds into LLM analysis |
| **Implement-test-fix loop** | Code generation with validation cycle |
| **Human approval gate** | Needs human review before proceeding |
| **Plan-approve-implement** | Complex changes needing upfront planning |
| **Parallel fan-out** | Independent analyses merged into synthesis |
| **Multi-model ensemble** | Multiple providers give independent opinions |
| **Production pipeline** | Toolchain checks + implement + verify + fixup loops |
| **Browser UI testing** | Validate web app screens and interactions with Vibium |

Combine patterns as needed. For example, a production pipeline might include a human gate after planning and a parallel fan-out for review.

### Step 4: Write the DOT Graph

See `references/dot-language.md` for the full language reference.

**Required elements:**
1. `digraph Name { ... }` wrapper
2. `graph [goal="..."]` attribute
3. `rankdir=LR` (preferred for readability)
4. Exactly one `start [shape=Mdiamond, label="Start"]`
5. Exactly one `exit [shape=Msquare, label="Exit"]`

**Choose node shapes by purpose:**
- `box` (default) -- agent with tools (implement, fix, write code)
- `tab` -- single LLM call without tools (analyze, plan, review, synthesize)
- `parallelogram` -- shell command (build, test, lint)
- `diamond` -- conditional routing (no prompt, only conditions on edges)
- `hexagon` -- human decision gate
- `component` -- parallel fan-out
- `tripleoctagon` -- merge parallel results

**Prompt guidelines:**
- Be specific and actionable in prompts
- Tell the agent exactly what to do, what files to create/modify, what output to produce
- Use `shape=tab` for nodes that only need to think, not act
- Use `prompt="@path/to/file.md"` for long prompts (path relative to DOT file)
- Set `reasoning_effort="low"` on simple analysis or summary nodes

**Edge routing:**
- Use `condition="outcome=success"` and unconditional fallback for check gates
- Diamond nodes must have multiple outgoing edges with conditions
- Use `max_visits` on fix/retry nodes to prevent infinite loops (typically 3)
- Use `goal_gate=true` on verification nodes that must pass for the workflow to succeed
- Set `retry_target` on goal gates to specify where to jump on failure

### Step 5: Assign Models via Stylesheet

Use `model_stylesheet` for model assignment rather than per-node attributes:

```dot
graph [model_stylesheet="
    *        { model: claude-sonnet-4-6;}
    .coding  { model: claude-opus-4-6;}
    .review  { model: gemini-3.1-pro-preview;}
"]
```

- Use `*` for the default model (usually a fast/cheap model)
- Use `.class` selectors for role-based assignment (`.coding`, `.review`, `.verify`)
- Use `#nodeid` selectors for specific node overrides
- Assign `class="coding"` etc. on nodes to match stylesheet rules
- **Critical:** Use semicolons between properties in stylesheet rules

**Model selection heuristics:**
- Fast/cheap models for simple analysis, summaries, routing: `claude-haiku-4-5`, `gemini-3-flash-preview`, `gpt-5-mini`
- Strong models for coding, complex reasoning: `claude-opus-4-6`, `claude-sonnet-4-6`, `gpt-5.4`
- Use `reasoning_effort="high"` for complex coding tasks
- For ensembles, pick models from different providers for diversity

### Step 5b: Browser Testing with Vibium

When the workflow involves validating a web app's UI, use [Vibium](https://github.com/VibiumDev/vibium) instead of Playwright MCP or custom test scripts. Vibium is a browser automation CLI built for AI agents — tests are written in plain English with embedded commands.

**Setup:** Add `vibium install` to the TOML `[setup]` commands. No MCP server config needed.

**Key commands:**
```bash
vibium go <url>                       # Navigate to URL
vibium map                            # Map interactive elements with @refs
vibium a11y-tree                      # Full accessibility tree
vibium screenshot -o <path>           # Capture screenshot
vibium screenshot -o <path> --annotate # Screenshot with numbered element labels
vibium keys <key>                     # Press key (ArrowLeft, Space, Enter, p, etc.)
vibium click @e1                      # Click element by ref from map
vibium type @e1 <text>                # Type into element
vibium fill @e1 <text>                # Clear and fill element
vibium eval "<js>"                    # Run JavaScript in page
vibium find text "Sign In"            # Find element by visible text
vibium find role button               # Find element by ARIA role
vibium is visible "<selector>"        # Check if element is visible (true/false)
vibium diff map                       # Compare current vs last map (what changed)
vibium record start                   # Start recording (screenshots + snapshots)
vibium record stop -o <path>          # Stop recording, save to ZIP
vibium stop                           # Stop browser
```

**Design rules:**
- Use `backend: cli` on test agent nodes so they get shell access to run vibium
- Write test prompts in plain English with embedded vibium commands
- Use `vibium map` to discover interactive elements, then `vibium click @ref`
- Use `vibium find text/role/label` for semantic element discovery in DOM-based apps
- Use `vibium screenshot -o <path> --annotate` for annotated screenshots that label interactive elements
- Use `vibium diff map` after interactions to verify what changed
- Use `vibium is visible/enabled/checked` for state assertions
- Use `vibium record start/stop` to capture session recordings (ZIP of screenshots + snapshots)
- Each parallel test agent gets its own browser session — safe to fan out
- Always include `vibium record stop` and `vibium stop` in cleanup
- Create a timestamped output directory (`YYYY-MM-DD_HH-MM-SS`) so test runs don't overwrite each other
- Store screenshots in a `screenshots/` subdir and recordings in `recordings/` within the run directory
- **Critical `$` escaping:** Fabro expands `$var` in `@prompt` files before the LLM sees them — use `$$RUN_ID` there so it becomes `$RUN_ID`. But `script=` attributes go directly to the shell with NO expansion — use plain `$RUN_ID` in scripts.

See `references/example-workflows.md` example 10 for a complete browser testing workflow.

### Step 6: Write the TOML Run Configuration (if needed)

See `references/run-configuration.md` for the full reference.

A TOML file is optional for simple workflows (you can run `fabro run workflow.fabro` directly). Create one when you need:
- Sandbox configuration (provider, environment variables)
- Setup commands (install dependencies)
- Variable definitions
- LLM fallbacks
- Hooks
- Asset collection

Minimal TOML:

```toml
version = 1
graph = "workflow.fabro"
```

Common additions:

```toml
[sandbox]
provider = "local"

[sandbox.local]
worktree_mode = "always"

[sandbox.env]
NODE_ENV = "test"
```

### Step 7: Validate

Run `fabro run --preflight workflow.toml` (or `fabro run --preflight workflow.fabro`) to validate without executing.

If validation fails, fix the reported errors and re-validate.

## Guardrails

- **Diamond nodes route only.** Never put a `prompt` on a `diamond` node -- it only evaluates edge conditions.
- **All nodes reachable from start.** No orphan nodes.
- **No edges into start or out of exit.**
- **LLM nodes need prompts.** Every `box` and `tab` node must have a `prompt` attribute.
- **Conditional nodes need multiple outgoing edges** with `condition` attributes.
- **Prevent infinite loops.** Use `max_visits` on retry/fix nodes. Typical value: 3.
- **Use `goal_gate=true`** on critical verification steps that must succeed.
- **Use `outcome=success` conditions** on edges leaving command/conditional nodes.
- **Model IDs must match the catalog.** Always run `fabro model list` first.
- **Semicolons in stylesheets.** Properties must be separated by semicolons.

## File Organization

Place workflow files together in a directory:

```
my-workflow/
  workflow.fabro        # the graph
  workflow.toml         # run configuration (optional)
  prompts/              # external prompt files (optional)
    implement.md
    review.md
```

## Running Workflows

```bash
fabro run workflow.fabro                  # run graph directly
fabro run workflow.toml                   # run with TOML config
fabro run workflow.toml --dry-run         # simulated LLM backend
fabro run workflow.toml --no-retro        # skip retro (faster for testing)
fabro run workflow.toml --auto-approve    # auto-approve human gates
fabro run workflow.toml --model claude-opus-4-6  # override model
fabro run workflow.toml --sandbox local   # override sandbox
fabro validate workflow.fabro            # validate only
```

## References

- `references/dot-language.md` -- Complete DOT language reference (node types, attributes, edges, conditions, stylesheets, fidelity, variables)
- `references/run-configuration.md` -- Complete TOML run configuration reference (sandbox, setup, hooks, LLM, vars, assets)
- `references/example-workflows.md` -- 9 complete example workflows from simple to production-grade

{{user_input}}

