.toml file into version control and launch with a single command:
Minimal example
A run config needs at minimum a schema version and a goal:run.toml
| Field | Required | Description |
|---|---|---|
_version | No (defaults to 1) | Schema version. Must be 1 in the first pass. |
[workflow].graph | No | Path to the Graphviz workflow file, relative to the TOML file’s directory. Defaults to workflow.fabro. |
[run].goal | No | What the workflow should accomplish. Passed to agents and used in retrospectives. Can also be provided via --goal CLI flag or Graphviz graph goal attribute. |
--goal > [run].goal > Graphviz graph attribute.
Full example
run.toml
Sections
[run.model]
Override the default model and provider for all nodes that don’t have an explicit model assigned via a stylesheet.
run.toml
| Field | Description |
|---|---|
name | Model ID or alias (e.g. claude-sonnet-4-5, opus, gemini-pro). See Models. |
provider | Provider name (optional — auto-inferred from the model catalog). Only needed for models not in the catalog or to force a specific provider. |
fallbacks | Ordered list of model references to try when the primary is unavailable. Entries can be bare provider tokens ("openai"), bare model aliases, or qualified "provider/model" references. |
Fallbacks with splice
Use the reserved"..." marker in fallbacks to splice in the inherited list from lower-precedence layers:
run.toml
[run.prepare]
Ordered list of steps to run before the workflow starts. Use this to clone repositories, install dependencies, or prepare the environment.
run.toml
| Field | Description |
|---|---|
script | Shell-evaluated command (runs through sh -c). |
command | Argv-style command, mutually exclusive with script. |
env | Additional environment variables for this step. |
[run.sandbox]
Configure how agent tools (bash, file edits) are executed.
run.toml
| Field | Description |
|---|---|
provider | Sandbox mode: local (default), docker, or daytona. |
preserve | When true, keep the sandbox alive after the run finishes. Useful for debugging. |
devcontainer | When true, use the repo’s devcontainer.json to configure the sandbox. See Devcontainers. |
[run.sandbox.daytona]
Additional settings when using the Daytona cloud sandbox:
run.toml
| Field | Description |
|---|---|
auto_stop_interval | Minutes of inactivity before the sandbox auto-stops. |
labels | Key-value labels attached to the sandbox for filtering and identification. Labels merge across layers (sticky merge-by-key). |
snapshot.name | Snapshot name to create or use for the sandbox. |
snapshot.cpu | CPU cores for the snapshot (integer). |
snapshot.memory | Memory size using human-readable units: "8GB", "16GiB", or bare integers that default to GB. |
snapshot.disk | Disk size using the same units as memory. |
snapshot.dockerfile | Dockerfile content (inline string) or path ({ path = "..." }) for building the snapshot image. Paths are resolved relative to the TOML file’s directory. |
network | Network access mode: "allow_all" (default), "block", or { allow_list = ["..."] }. See Sandboxing. |
[run.sandbox.local]
Additional settings when using the local sandbox:
run.toml
| Field | Description |
|---|---|
worktree_mode | When to create a git worktree for the run: always, clean (default — only when the working tree is clean), dirty (also when dirty), or never. |
[run.sandbox.env]
Pass environment variables into sandbox command and agent execution. Values can be literal strings or host environment references using {{ env.VARNAME }} syntax:
run.toml
| Syntax | Description |
|---|---|
"literal" | Static value passed as-is |
"{{ env.VARNAME }}" | Whole-value reference resolved from the host environment at consumption time |
"prefix-{{ env.X }}-suffix" | Substring interpolation; multiple tokens per string are supported |
run.sandbox.env is a sticky merge-by-key map: entries from all layers combine, with higher-precedence layers overriding individual keys.
[run.checkpoint]
Configure how git checkpoint commits behave.
run.toml
| Field | Description |
|---|---|
exclude_globs | Glob patterns for files to exclude from checkpoint commits. Uses git pathspec :(glob,exclude) syntax. |
exclude_globs replaces across layers — the higher-precedence layer wins wholesale.
[run.inputs]
Define inputs that are expanded into the Graphviz source before the graph is parsed. See Variables for the full reference.
run.toml
{{ inputs.name }} syntax:
c-i.fabro
{{ inputs.langauge }}, Fabro raises an error immediately.
[run.inputs] replaces wholesale across layers. Unlike labels, inputs do not merge by key — the highest-precedence layer that sets inputs wins its entire map.
[run.artifacts]
Configure automatic collection of test artifacts (Playwright reports, JUnit XML, screenshots, etc.) from the execution environment after each stage.
run.toml
| Field | Description |
|---|---|
include | Glob patterns for files to collect as assets. Matched against the working directory after each stage completes. |
[run.artifacts] section is present, no file scanning occurs.
[run.agent.mcps]
Configure MCP servers available to agent stages during the workflow run. Each server is a named TOML table under [run.agent.mcps]. All three transport types are supported: stdio, http, and sandbox.
run.toml
| Field | Description | Default |
|---|---|---|
type | Transport type: "stdio", "http", or "sandbox". | — |
script | (stdio, sandbox) Shell-evaluated startup command, mutually exclusive with command. | — |
command | (stdio, sandbox) Argv array: executable + arguments. | — |
port | (sandbox) Port the server listens on inside the sandbox. | — |
url | (http) The MCP server endpoint URL. | — |
env | (stdio, sandbox) Additional environment variables. | {} |
headers | (http) Optional HTTP headers for authentication. | {} |
startup_timeout | Max duration for server startup + MCP handshake (e.g. "10s", "1m"). | "10s" |
tool_timeout | Max duration for a single tool call. | "60s" |
sandbox transport runs the MCP server inside the workflow’s sandbox. This is useful for tools that need access to the sandbox environment, such as browser automation with Playwright. See MCP for details.
[run.pull_request]
Automatically open a GitHub pull request when the workflow run completes successfully. Requires a GitHub App to be configured.
run.toml
| Field | Description |
|---|---|
enabled | When true, Fabro creates a PR from the agent’s working branch after a successful run. Default: false. |
draft | When true, the PR is created as a draft pull request. Default: true. |
auto_merge | When true, enables GitHub auto-merge on the created PR. Implies draft = false since GitHub doesn’t allow auto-merge on draft PRs. The repository must have auto-merge enabled in GitHub settings. Default: false. |
merge_strategy | Merge method when auto_merge is enabled: squash (default), merge, or rebase. |
[[run.hooks]]
Define hooks that run in response to lifecycle events. Each hook is a TOML array entry:
run.toml
| Field | Description |
|---|---|
id | Optional merge identity. Hooks with the same id replace each other across layers. |
name | Optional display name for the hook. |
event | Lifecycle event: run_start, run_complete, stage_start, stage_complete, etc. |
script | Shell-evaluated command (equivalent to the old type = "command" shorthand). |
command | Argv-style command (alternative to script). |
matcher | Regex matched against node ID or handler type. Limits which stages trigger this hook. |
blocking | Whether the hook must complete before execution continues. Defaults vary by event. |
timeout | Human-readable hook timeout (e.g. "30s", "1m"). Default: "60s". |
sandbox | Run inside the sandbox (true, default) or on the host (false). |
id values replace in place. Hooks without an id from a higher-precedence layer append after the fully merged inherited hook list.
See Hooks for hook types beyond scripts (HTTP, prompt, agent).
Graph path resolution
The[workflow].graph path is resolved relative to the TOML file’s parent directory, not the current working directory. This means a run config and its workflow can live side by side:
Precedence
Settings can come from multiple sources. Fabro resolves them in this order (first match wins):| Source | Priority |
|---|---|
| Node-level stylesheet | Highest |
CLI flags (--model, --provider, --sandbox) | |
Run config TOML (workflow.toml or equivalent) | |
Project defaults (.fabro/project.toml) | |
Machine defaults (~/.fabro/settings.toml) | |
Graphviz graph attributes (default_model, default_provider) | |
| Built-in defaults | Lowest |
Stylesheet rules on individual nodes always take priority over run config values.
Project defaults (.fabro/project.toml)
The .fabro/project.toml project config can set default values for any of the [run.*] sections described above. These defaults apply to all runs in the project unless the workflow config overrides them:
.fabro/project.toml
run.inputs replaces wholesale, run.sandbox.env sticky-merges by key, and run.prepare.steps replaces whole-list.
Machine defaults
When running locally, the machine defaults at~/.fabro/settings.toml can set run-scoped defaults too. Same merge rules apply.
Validation
Fabro validates the run config when it loads:_versioncheck — Only_version = 1(or missing, which defaults to1) is accepted. The legacy top-levelversionkey is rejected with a rename hint.- Unknown keys — Any top-level key not in
[project],[workflow],[run],[cli],[server],[features], or_versionis rejected with a targeted rename hint pointing at the v2 replacement path. - Variable check — Any undefined workflow template variable in the Graphviz file produces an error.
fabro preflight to validate a run config without executing it: