> For the index of every page in Orbital's docs, read https://docs.runorbital.dev/llms.txt.

# Workflows

> A workflow is one TOML file of steps that Orbital runs

You describe the work a run does as a workflow: one TOML file that Orbital loads, validates and runs. The smallest complete one has a version, an entry step, one agent step and one terminal:

```toml title="minimal.toml"
version = 3
entry = "steps.hello"

[steps.hello]
prompt = "Reply with one sentence explaining the goal: {{ inputs.goal }}."
next = "steps.done"

[steps.done]
kind = "terminal"
```

A workflow declares `version = 3`, the `entry` step the run starts at, and its [steps](/reference/step-kinds/) under `steps`. Each step says where the run goes next. [Write your first workflow](/workflows/write-a-workflow/) walks through this one.

Keep the file in your project's `.orbital/` folder as `<name>.toml`. The file name is the workflow's name. A step's ID is its path under `steps`, so `[steps.hello]` has the ID `hello`, and a reference to it is the quoted path `"steps.hello"`. Give every step a stable ID, because the run transcript, visit counts and manual jumps all address steps by ID. Write each prompt for someone arriving without prior conversation: state the expected result and the allowed actions.

## Why TOML?

TOML gives every setting its own key. Settings that nest, such as a step's outputs or a style's Codex options, are real tables rather than small languages packed into a quoted string. One key holds one fact, so a change to the file reads as a change to that fact when you review it in Git, and Orbital refuses a key it does not know, naming the key and where it is. Run [`orbital validate`](#validate-before-you-run) to check a file as you write it.

Workflows written in DOT, the format before version 3, no longer load, and a run of one is refused with a message saying how to convert it. Orbital converts the workflows it keeps itself, your saved custom workflows and your edits to built-in workflows, when it starts. A saved workflow it cannot convert stays as it was, and the Workflows page lists it with the problem, so you can rewrite it in the editor's Source view.

DOT files stay where you put them. When a project's `.orbital/` folder or your `~/.orbital/workflows/` folder still holds some, the Workflows page says how many and offers **Convert to TOML**. It writes each `.toml` file beside its `.dot` file, leaves the `.dot` file in place, and lists each file it wrote with what it dropped, such as tool limits, and each step it could not convert. [`orbital migrate`](/reference/command/#orbital-migrate) does the same from the command line.

## Group steps

A table under `steps` that has no `kind`, `prompt`, `prompt_file` or `import` is a group. It holds steps that belong together, takes no turn of its own, and is never a place a route can send the run. A group must hold at least one step, and groups nest to any depth.

```toml title="group.toml"
version = 3
entry = "steps.coder.plan"

[styles.careful]
effort = "high"

[steps.coder]
label = "The coder"
style = "careful"

[steps.coder.plan]
prompt = "Plan the change the goal describes. Do not change files."
outputs.plan = "text"
next = "steps.coder.implement"

[steps.coder.implement]
prompt = "Carry out this plan: {{ context.plan }}"
next = "steps.done"

[steps.done]
kind = "terminal"
```

The steps inside take the group's name into their IDs: `[steps.coder.plan]` has the ID `coder.plan`, and a route reaches it as `"steps.coder.plan"`. A group may set a `label`, and a `style` that applies to every step inside it. Here `plan` and `implement` both run with high effort from the `careful` style without naming it. A step's own keys and its own `style` still win, and an inner group's style wins over an outer one's. A `style` at the top of the file sets defaults for every step in the workflow in the same way. [Give steps a style](/styles/configure-steps/) gives the full order.

## Where Orbital looks for a workflow

Orbital searches these places in order and takes the first match:

| Order | Place |
| --- | --- |
| 1 | Custom workflows saved in the browser. |
| 2 | The `.orbital/` folder of the project's primary folder. |
| 3 | The `.orbital/` folder of each remaining folder. |
| 4 | Your library, `~/.orbital/workflows/`. |
| 5 | The workflows shipped with Orbital. |

Because the first match wins, a custom workflow named `hello` shadows a file named `hello.toml`. Use a distinct name while experimenting. Pass an explicit path to `orbital validate` when you diagnose a collision.

## Shipped workflows

Orbital ships eight workflows. They appear in the new-run menu of every project. A workflow of the same name in any other place takes a shipped one over.

| Workflow | What it does | What it needs |
| --- | --- | --- |
| `explain-repo` | Reads the project's primary folder in one step that only reads, and explains the repository. No worktree, no pull request. | An optional goal |
| `implement-ticket` | Plans, implements and reviews one ticket, then delivers it to merge. | A ticket URL, as `ticket_url` |
| `implement-epic` | Delivers an epic's leaf tickets one at a time, then closes the epic. | An epic URL, as `ticket_url` |
| `implement-epic-with-panel` | Delivers an epic the same way, with a panel of parallel reviewers. | An epic URL, as `ticket_url` |
| `improve-codebase` | Finds and delivers one worthwhile improvement, then stops. | An optional goal |
| `reduce-complexity` | Simplifies the function most worth simplifying. | An optional goal |
| `pursue-goal` | Implements and validates a goal in a loop, then delivers it. | A goal in plain words |
| `port-project` | Ports an application to a new stack, one proved slice per pull request. | A goal naming the source repository and the target stack |

[Shipped workflows](/reference/shipped-workflows/) describes each one, with its diagram.

## The Workflows page

Click **Workflows** in the sidebar to list every workflow the selected project offers. A badge says where each one comes from.

![The Workflows page lists four workflows, each with a source badge such as Project, Custom or Home, and Clone, Export or Revert to built-in buttons. Search, Import and New workflow sit at the top.](/screenshots/workflows-page.webp?v=991e5fde13)

*Each workflow's badge says where it lives and whether you can edit it here.*

| Badge | Where it lives | Can you edit it here? |
| --- | --- | --- |
| Custom | Saved in Orbital from this page. | Yes. |
| Project | The `.orbital/` folder of one of the project's folders. | Yes. Saving writes the file in place and leaves it uncommitted. |
| Home | Your library, `~/.orbital/workflows/`. | Yes. Saving writes the file in place. |
| Shipped | Comes with Orbital and is kept in Orbital's database. | Yes. Saving edits it in place. |

A shipped workflow you have saved stands as edited, and the editor offers **Reset to shipped** to bring the shipped version back. A later release updates every shipped workflow you have not edited and leaves your edits alone; for one you edited, the editor says when a newer shipped version exists. Deleting a shipped workflow hides it, and **Restore** on the Workflows page brings it back. A Custom workflow with a shipped name shows **Takes over built-in**; reverting it deletes it.

On this page you can create a workflow, import one, clone one, export one as a file, and open one in the editor. Export writes one self-contained file with the prompts inlined.

**Import** opens a box where you paste a workflow's TOML. Paste a DOT workflow and Orbital converts it to TOML, and lists what the conversion dropped as warnings. Nothing is stored until you save. Prompt files the workflow refers to become empty prompts for you to fill in.

![The Import a workflow page has one large text box with Import and Cancel buttons below it.](/screenshots/import-workflow.webp?v=b5c29c87bd)

*Paste the workflow's TOML; nothing is stored until you save.*

### The editor

The editor draws the workflow and validates it as you edit. The **Problems** bar at the bottom lists what validation found. The **Inspector** on the right holds the workflow's description, entry, inputs and turn budget.

Move around the canvas with a two-finger swipe, or drag an empty area. Pinch or hold ⌘ while scrolling to zoom.

Work in progress is kept as a Draft, even while it is not valid yet. A Draft cannot be run. It becomes a Custom workflow once you save it as a valid workflow. The browser workflow library also creates and edits custom workflows, and saving validates them. Inspect the selected workflow before you start a run.

![The workflow editor shows a project workflow as steps joined by arrows on a canvas, with the Inspector panel on the right and a Problems bar reading No problems at the bottom.](/screenshots/workflow-editor.webp?v=85a9c6275a)

*A project workflow saves to its file in place; commit it to share it. Use Duplicate to make a copy.*

## Declared inputs

Declare each value the workflow needs from the person who starts it as an `[inputs.<name>]` table. Its `kind` chooses the field on the new-run form and how Orbital checks the value. `label` and `hint` explain it on the form; without a label, the form shows the input's name.

```toml
[inputs.ticket]
kind = "ticket"
from = ["github", "linear"]
label = "Ticket"
hint = "The issue to deliver"

[inputs.notes]
label = "Notes"
required = false
```

An input is required unless it sets `required = false`, and a `default` fills it when nobody gives a value. `goal` is built in; an `[inputs.goal]` table may only change its `label`, `hint` and `default`. Starting a run requires the goal and every required input, so a workflow states what it needs and you do not have to remember it. From the command line, pass each input with `--input <name>=<value>`.

| Kind | What the input holds |
| --- | --- |
| `text` | Free text. The default when an input sets no `kind`. |
| `short_text` | One line of text. |
| `number` | A number, kept between `min` and `max` when you set them. |
| `yes_no` | Yes or no. |
| `url` | A link. |
| `choice` | One of its `options`, given as a list or as a table of values and their descriptions. |
| `ticket` | A GitHub issue or Linear issue. |
| `epic` | A GitHub issue or Linear issue that other tickets sit under. |
| `project` | The address of a GitHub or Linear project. |
| `pull_request` | The address of a pull request. |
| `repository` | The address of a repository. |

`from` limits a ticket, epic or project to `github` or `linear`; it accepts both by default. Orbital looks a ticket or epic up when the run is created, and refuses the run before any agent turn when it cannot read the ticket, naming the input and the tracker's reason. Prompts then read its fields, such as `{{ inputs.ticket.title }}`, and `{{ inputs.ticket }}` on its own renders the reference you gave. A project, pull request or repository is checked to be written as an address, and a prompt reads that address. [Input kinds](/reference/workflow-file/#input-kinds) lists every field, and [Pass context between steps](/workflows/pass-context/) covers what happens to the values once the run starts.

## Validate before you run

Validation reads the file, checks every key and its type, resolves imports and prompt files, and checks routing without calling an agent.

```sh
orbital validate .orbital/hello.toml
```

Fix errors before you add more steps. Warnings identify unreachable steps, unused inputs and other suspicious but loadable declarations.

Add one decision at a time. A choice output with two explicit routes is easier to inspect than a prompt that silently decides whether to publish. Validate again after you edit imports and prompt files, because those are separate files that the workflow only names.

## Choosing where to keep a workflow

| You want | Keep it |
| --- | --- |
| The workflow beside the code it works on, reviewed in Git | The `.orbital/` folder of the project's folder |
| The workflow in every project | Your library, `~/.orbital/workflows/` |
| To build it in the app, without files | A Custom workflow, from the Workflows page |
| A changed shipped workflow | The shipped workflow itself, edited in place. Reset to shipped to get the original back. |

## Related

- [Write your first workflow](/workflows/write-a-workflow/): copy the smallest complete workflow and change it.
- [Step kinds](/reference/step-kinds/): the kinds of step a workflow is made of.
- [Workflow file](/reference/workflow-file/): every key a workflow file takes.
- [How Orbital works](/concepts/how-orbital-works/): how a run carries out a workflow one step at a time.
- [Shipped workflows](/reference/shipped-workflows/): each shipped workflow with its diagram.
- [The orbital command](/command-line/): `orbital validate` and the other commands.
