Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Write a workflow

This page is the reference for workflow files. You rarely need to write one yourself: ask your coding agent, with the tome plugin installed, and it writes and validates the file for you. See Create workflows with an agent. Use this page to check what it wrote, or to make a small change by hand.

A workflow is a Markdown file with YAML frontmatter. Put it in .tome/workflows/ for one project or ~/.tome/workflows/ for all of them. tome workflow new <name> writes a starter file in the right place, and tome validate [name] checks it.

Every example on this page is a real file under docs/examples/ in the repo, and CI runs tome validate on each one.

The smallest workflow

Only name is required.

---
name: minimal
---
Say hello, then finish the run.

Everything after the closing --- is the body. You write it in plain English. The run’s agent reads it and decides what to do, in what order. tome never parses it, except to fill in placeholders and to check them.

Steps

Use ## Headings to name the steps. The run’s agent reports each one to tome as it starts and finishes, and you see them in tome runs show. Steps are not a rigid script: the text can tell the agent to retry, loop or skip, and it will.

Say what each step does, what counts as done, and what should happen if it fails. If nothing says otherwise, a failed step fails the run.

Custom statuses

To track where a run is in your own terms, tell the agent to set a status in the step’s text:

## Review
Set status to InReview.
Read the diff and leave comments.

The agent runs tome step status "InReview", which labels the running step. The run’s custom status follows its active step, separate from the run’s own status (queued, running, …). Both show in tome runs show: custom on the run and a CUSTOM column for each step, or custom_status in JSON.

  • Labels are free-form and kept exactly as written, including case. Several steps can share one.
  • Starting a step that has no status clears the run’s custom status.
  • When steps run in parallel, the run takes the status of the earliest-started step that is still running, which is the parent or group step.
  • When no step is running, tome step status --step "<name>" "<status>" sets the run’s custom status directly. After the run finishes or fails, the last one stays.

Frontmatter fields

tome validate rejects keys it doesn’t know, and points to the line.

name

Required. Letters, digits, _ and -. It’s what you pass to tome run.

description

One line, shown in listings.

mode

single (the default) or orchestrated.

  • single: tome starts one agent that does the whole workflow itself. It can report steps, use queues and publish events, but it can’t spawn workers, groups or worktrees; those commands are refused.
  • orchestrated: tome starts an orchestrator that hands the work to workers. Use it for any workflow that fans out.

tome validate warns when a single workflow’s body talks about workers, worktrees or fanning out, and when it sets keys only an orchestrator uses (orchestrator_harness, orchestrator_model, and the orchestrator and workers placement blocks). See Workflows, runs and steps.

params

Named inputs, filled in from --param key=value on tome run, from a trigger’s params:, or from the default. Each param has:

  • type: string (the default), int, float or bool
  • default: used when nothing sets it. A param without a default is required.
  • description
---
name: summarize
description: Summarize a file into a short note.
params:
  file: {type: string, description: "The file to summarize"}
  words: {type: int, default: 100, description: "Length limit"}
  bullets: {type: bool, default: false}
---
Summarize `{{params.file}}` in at most {{params.words}} words.
Use bullets: {{params.bullets}}. This is run {{run.id}}.

## Read
Read the file.

## Summarize
Write the summary to `summary.md` and finish the run.
tome run summarize --param file=notes.txt --param words=50

In the body, {{params.<name>}} inserts a value and {{run.id}} inserts the run’s id. A placeholder that names no param is an error at validation time. In a workflow started by a trigger, {{trigger.<field>}} inserts details of the event; see Triggers and the message bus.

defaults

Workflow-wide settings.

---
name: defaults-tour
description: Every key under `defaults`.
mode: orchestrated              # orchestrator_* keys apply to orchestrated runs
defaults:
  backend: tmux                 # tmux or cmux
  harness: claude               # agent CLI for workers
  orchestrator_harness: claude  # agent CLI for the orchestrator
  timeout: 30m
  on_failure: notify
  start_timeout: 2m             # or `off`
  layout: split                 # where sessions open; see the sessions guide
---
Do the work described in the steps below.

## Work
Do it.
KeyMeaning
backendtmux, cmux or herdr. Falls back to TOME_BACKEND, then config, then cmux inside cmux, herdr inside herdr, and tmux otherwise.
harnessThe agent CLI for a single run’s agent and for workers. Defaults to claude. Defined in config; see Sessions and backends.
orchestrator_harnessThe agent CLI for the orchestrator (mode: orchestrated only). Defaults to harness. Workers run it too unless harness is set.
modelThe model a single run’s agent and workers run, such as opus. Passed to the harness; unset uses the harness’s own default. Override for one worker with tome worker spawn --model.
orchestrator_modelThe model the orchestrator runs (mode: orchestrated only). Defaults to model.
layoutWhere sessions open. A name (tab, split, workspace) or a block of settings; see Sessions and backends.
start_timeoutHow long the run’s agent and each agent worker have to make their first tome call. A duration like 90s or 2m, or off. The default is 60s. If it passes, tome nudges the agent once and fails it after a second wait.
provider_optsOptions for a provider when the run uses --on <provider>, a map of names to values. --provider-opt overrides them, and they override defaults.provider_opts in config.
timeoutA duration, like 30m, or a number of seconds. tome accepts and records it, but doesn’t enforce a run timeout today.
on_failureA string, accepted and recorded. tome doesn’t act on it today; say in the body what should happen on failure.

tome run my-workflow --harness <name> --model <model> overrides the harness and model for that run, including orchestrator_harness and orchestrator_model. Workers inherit the run’s choices unless overridden with tome worker spawn --harness or --model. The workflow file stays unchanged. See Harnesses for setup.

concurrency and on_conflict

concurrency: N limits how many runs of this workflow go at once. Runs are unlimited by default. When the limit is reached, on_conflict: queue (the default) makes the new run wait, and on_conflict: reject refuses it.

orchestrator

Extra instructions for the orchestrator only, added to its prompt. Use it for how the orchestrator should behave, and keep the body for what the workflow does.

---
name: one-at-a-time
description: Never run twice at once; extra runs wait their turn.
concurrency: 1
on_conflict: queue     # or `reject` to refuse a run when one is going
orchestrator: |
  Keep your messages to the user short. Ask before deleting anything.
---
Do the work.

## Work
Do it.

triggers

A list of rules that start the workflow or signal its runs. This example has one of each kind:

---
name: triggers-tour
description: One of each kind of trigger.
params:
  reason: {type: string, default: manual}
triggers:
  - manual
  - file: "src/**/*.rs"
    on: [created, modified]
    debounce: 5s
    ignore: ["target/**"]
    while_running: queue
    params: {reason: files}
  - cron: "0 9 * * 1-5"
    params: {reason: schedule}
  - on: review.requested
    params: {reason: message}
---
Started because of: {{params.reason}}.

## Work
Do it.

Every field of a trigger is explained in Triggers and the message bus.

Check, then run

tome validate my-workflow
tome run my-workflow --param key=value

tome validate with no name checks every workflow it can see and shows which project workflows override global ones. It exits with code 2 if anything is wrong, and prints each problem with its line number.

For every command and flag, run tome --help.