fabro/docs/execution/run-configuration.mdx
Bryan Helmkamp 36ad1606ee Update docs for tool-level hooks, server mode, and auto-PR
- hooks.mdx: add pre_tool_use/post_tool_use/post_tool_use_failure events,
  tool-specific context fields, matcher support for tool names
- cli.mdx: add --mode and --server-url flags to arc exec
- run-configuration.mdx: add [pull_request] section
- github.mdx: add auto-PR to features table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:49:28 -04:00

351 lines
10 KiB
Text

---
title: "Run Configuration"
description: "Configure workflow runs with TOML files"
---
A run config is a TOML file that bundles a workflow graph with all the settings needed to execute it — the goal, model, sandbox, setup commands, variables, and hooks. Instead of passing a dozen CLI flags, you check a `.toml` file into version control and launch with a single command:
```bash
arc run run.toml
```
## Minimal example
A run config requires two fields:
```toml title="run.toml"
version = 1
graph = "workflow.dot"
goal = "Implement the login feature"
```
| Field | Required | Description |
|---|---|---|
| `version` | Yes | Config format version. Must be `1`. |
| `graph` | Yes | Path to the DOT workflow file, resolved relative to the TOML file's directory. |
| `goal` | No | What the workflow should accomplish. Passed to agents and used in retrospectives. Can also be provided via `--goal` CLI flag or DOT graph `goal` attribute. |
Goal precedence: CLI `--goal` > TOML `goal` > DOT graph attribute.
## Full example
```toml title="run.toml"
version = 1
goal = "Run the CI pipeline for $repo_name"
graph = "pipelines/ci.dot"
directory = "/tmp/workdir"
[llm]
model = "claude-sonnet-4-5"
provider = "anthropic"
[llm.fallbacks]
anthropic = ["gemini", "openai"]
gemini = ["anthropic", "openai"]
[setup]
commands = ["git clone $repo_url repo", "cd repo && npm install"]
timeout_ms = 120000
[sandbox]
provider = "daytona"
preserve = false
[sandbox.daytona]
auto_stop_interval = 60
[sandbox.daytona.labels]
project = "arc"
env = "ci"
[sandbox.daytona.snapshot]
name = "node-20"
cpu = 4
memory = 8
disk = 20
dockerfile = "FROM node:20-slim\nRUN apt-get update && apt-get install -y git"
[sandbox.env]
API_KEY = "${env.MY_API_KEY}"
NODE_ENV = "production"
[checkpoint]
exclude_globs = ["**/node_modules/**", "**/.cache/**"]
[vars]
repo_name = "arc"
repo_url = "https://github.com/qltysh/arc"
[pull_request]
enabled = true
[[hooks]]
event = "stage_start"
command = "./scripts/pre-check.sh"
blocking = true
sandbox = false
[[hooks]]
event = "run_complete"
command = "echo done"
```
## Sections
### `[llm]`
Override the default model and provider for all nodes that don't have an explicit model assigned via a [stylesheet](/workflows/stylesheets).
```toml title="run.toml"
[llm]
model = "claude-sonnet-4-5"
provider = "anthropic"
```
| Field | Description |
|---|---|
| `model` | Model ID or alias (e.g. `claude-sonnet-4-5`, `opus`, `gemini-pro`). See [Models](/core-concepts/models). |
| `provider` | Provider name: `anthropic`, `openai`, `gemini`, `kimi`, `zai`, `minimax`, `inception`. |
#### `[llm.fallbacks]`
Map each provider to an ordered list of fallback providers. When the primary provider is unavailable, Arc tries the fallbacks in order:
```toml title="run.toml"
[llm.fallbacks]
anthropic = ["gemini", "openai"]
gemini = ["anthropic", "openai"]
```
### `[setup]`
Shell commands to run before the workflow starts. Use this to clone repositories, install dependencies, or prepare the environment.
```toml title="run.toml"
[setup]
commands = ["pip install -r requirements.txt", "npm install"]
timeout_ms = 60000
```
| Field | Description |
|---|---|
| `commands` | List of shell commands, executed sequentially via `sh -c`. |
| `timeout_ms` | Per-command timeout in milliseconds. Default: `300000` (5 minutes). |
Each command must exit with status 0. If any command fails or times out, the run aborts before the workflow starts.
### `[sandbox]`
Configure how agent tools (bash, file edits) are executed.
```toml title="run.toml"
[sandbox]
provider = "docker"
preserve = true
```
| Field | Description |
|---|---|
| `provider` | Sandbox mode: `local` (default), `docker`, or `daytona`. |
| `preserve` | When `true`, keep the sandbox alive after the run finishes. Useful for debugging. |
#### `[sandbox.daytona]`
Additional settings when using the Daytona cloud sandbox:
```toml title="run.toml"
[sandbox.daytona]
auto_stop_interval = 60
[sandbox.daytona.labels]
project = "arc"
env = "staging"
[sandbox.daytona.snapshot]
name = "my-snapshot"
cpu = 4
memory = 8
disk = 20
dockerfile = "FROM rust:1.85-slim-bookworm\nRUN apt-get update"
# Or reference an external Dockerfile:
# dockerfile = { path = "./Dockerfile" }
```
| 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. |
| `snapshot.name` | Snapshot name to create or use for the sandbox. |
| `snapshot.cpu` | CPU cores for the snapshot. |
| `snapshot.memory` | Memory in GB for the snapshot. |
| `snapshot.disk` | Disk in GB for the snapshot. |
| `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](/administration/sandboxing#network-access-control). |
#### `[sandbox.env]`
Pass environment variables into sandbox command and agent execution. Values can be literal strings or host environment passthrough using `${env.VARNAME}` syntax:
```toml title="run.toml"
[sandbox.env]
API_KEY = "${env.MY_API_KEY}"
NODE_ENV = "production"
```
| Syntax | Description |
|---|---|
| `"literal"` | Static value passed as-is |
| `"${env.VARNAME}"` | Resolved from the host environment at load time. Missing vars produce a hard error. |
Host env references must be whole-value only — partial interpolation like `"prefix-${env.X}"` is not supported. Sandbox env vars from `server.toml` defaults and the run config are merged, with the run config winning on key collisions.
### `[checkpoint]`
Configure how git checkpoint commits behave.
```toml title="run.toml"
[checkpoint]
exclude_globs = ["**/node_modules/**", "**/.cache/**", "**/dist/**"]
```
| Field | Description |
|---|---|
| `exclude_globs` | Glob patterns for files to exclude from checkpoint commits. Uses git pathspec `:(glob,exclude)` syntax. |
Exclude globs from `server.toml` defaults and the run config are merged (union, deduplicated).
### `[vars]`
Define variables that are expanded into the DOT source before the graph is parsed. See [Variables](/workflows/variables) for the full reference.
```toml title="run.toml"
[vars]
repo_name = "arc"
repo_url = "https://github.com/qltysh/arc"
language = "rust"
```
Variables can be used anywhere in the DOT file with `$name` syntax:
```dot title="c-i.dot"
digraph CI {
graph [goal="Run tests for $repo_name"]
clone [shape=parallelogram, script="git clone $repo_url repo"]
test [label="Test", prompt="Run the $language test suite."]
}
```
If a `$variable` in the DOT file has no matching entry in `[vars]`, Arc raises an error immediately. A bare `$` not followed by an identifier (e.g. `costs $5`) is left as-is.
### `[pull_request]`
Automatically open a GitHub pull request when the workflow run completes successfully. Requires a [GitHub App](/integrations/github) to be configured.
```toml title="run.toml"
[pull_request]
enabled = true
```
| Field | Description |
|---|---|
| `enabled` | When `true`, Arc creates a PR from the agent's working branch after a successful run. Default: `false`. |
### `[[hooks]]`
Define hooks that run in response to lifecycle events. Each hook is a TOML array entry:
```toml title="run.toml"
[[hooks]]
name = "pre-check"
event = "stage_start"
command = "./scripts/pre-check.sh"
matcher = "agent_loop"
blocking = true
timeout_ms = 30000
sandbox = false
```
| Field | Description |
|---|---|
| `name` | Optional display name for the hook. |
| `event` | Lifecycle event: `run_start`, `run_complete`, `stage_start`, `stage_complete`. |
| `command` | Shell command to execute (shorthand for `type = "command"`). |
| `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_ms` | Hook timeout in milliseconds. Default: `60000` (60s). |
| `sandbox` | Run inside the sandbox (`true`, default) or on the host (`false`). |
See [Hooks](/agents/hooks) for hook types beyond simple commands (HTTP, prompt, agent).
## Top-level fields
In addition to the sections above, two optional top-level fields are available:
| Field | Description |
|---|---|
| `directory` | Working directory for the run. Defaults to the current directory. |
## Graph path resolution
The `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:
```
project/
runs/
ci.toml # graph = "ci.dot"
ci.dot
```
Absolute paths are used as-is.
## Precedence
Settings can come from multiple sources. Arc resolves them in this order (first match wins):
| Source | Priority |
|---|---|
| Node-level [stylesheet](/workflows/stylesheets) | Highest |
| Run config TOML | |
| CLI flags (`--model`, `--provider`, `--sandbox`) | |
| Server defaults (`~/.arc/server.toml`) | |
| DOT graph attributes (`default_model`, `default_provider`) | |
| Built-in defaults | Lowest |
<Note>
For model and provider specifically, the precedence is: CLI flags > TOML config > server defaults > DOT graph attributes > built-in defaults. Stylesheet rules on individual nodes always take priority over all of these.
</Note>
### Server defaults
When running via `arc serve`, the server config at `~/.arc/server.toml` can set default values for `[llm]`, `[setup]`, `[sandbox]`, and `[vars]`. These defaults are applied to every run unless the run config overrides them.
For variables, defaults and run config are **merged** — the run config wins on key collisions:
```toml
# ~/.arc/server.toml
[vars]
default_key = "from_server"
shared = "from_server"
# run.toml
[vars]
shared = "from_run" # wins
task_key = "from_run"
```
The same merge behavior applies to Daytona labels. All other fields use simple "first non-empty wins" precedence.
## Validation
Arc validates the run config when it loads:
- **Version check** — Only `version = 1` is accepted. Other versions are rejected immediately.
- **Required fields** — `version` and `graph` are required. `goal` is optional (can be provided via `--goal` or DOT graph attribute).
- **Unknown fields** — Extra fields not listed above are rejected (`deny_unknown_fields`).
- **Variable check** — Any `$variable` in the DOT file without a matching `[vars]` entry produces an error.
Use `--preflight` to validate a run config without executing it:
```bash
arc run run.toml --preflight
```