One-off workflows
Let an agent propose a workflow for one piece of work, and approve it before it runs
Some work needs a process no saved workflow has, and is not worth saving. A One-off Workflow is written for one run. An agent proposes its TOML text, Orbital checks it, and the run waits for you as a held Run until you approve it. It is an experimental feature: turn on One-off workflows in Settings > Experimental.
The text
Section titled “The text”A One-off Workflow is the same version = 3 TOML as any workflow file, with a few extra rules so one run cannot grow without bounds:
- it is at most 64 KiB and has at most 40 steps;
- it is self-contained: no
import, noprompt_fileand no[repeat]; - it sets a workflow-level
max_visitsof at most 50, and no failure route loops back without a bound.
Text from a source Orbital does not trust also may not use auto_merge or permissions = "full". An agent checks text with validate_workflow and its source argument before proposing it. Text that breaks a rule is refused with each problem named, and no run is created.
A One-off Workflow never appears in a workflow list, the start composer, the trigger picker or list_workflows. Its run keeps its own snapshot, so Resume, Retry, Jump, Restart and Run Export never look its name up, even if a saved workflow has the same name.
Approve a held Run
Section titled “Approve a held Run”A held Run is listed as One-off and Needs approval, and raises a desktop notification when notifications are on. Its page shows what you need to decide:
- where the text came from, with a link, and whether Orbital trusts that source;
- the canvas, the harnesses and styles its steps use, and its warnings;
- the keys with effects outside the worktree, such as
commandscripts,git.push,github.pr.open,worktree.remove,auto_mergeandpermissions = "full". Every agent step has every tool, so read the prompts too; - a cost caution, the TOML and when the approval expires.
Start the run to approve it: it runs exactly the text you read. Abort it to decline it. A held Run nobody decides on within 24 hours ends Aborted with “Approval expired”. A project holds at most 10 runs waiting for approval.
Where proposals come from
Section titled “Where proposals come from”| Source | Trusted | What happens |
|---|---|---|
| The delivery lead’s chat | Yes | Always held, whatever Start runs says, unless it says Never, which refuses it. A new proposal under the same name replaces the earlier one. |
| A trigger rule | Yes, once you approve the rule | The rule pins the text, and each firing runs it without asking. |
| A watcher wake-up | No | Always held, with the wake-up’s reason. The delivery lead is woken with your decision. |
| A step of a run | No | Always held as a child run of the run that proposed it. |
| An agent outside Orbital | No | Settings > MCP decides. |
From the delivery lead’s chat
Section titled “From the delivery lead’s chat”Ask the delivery lead for work no saved workflow fits. It writes a One-off Workflow, checks it and proposes it with start_run and source. The held Run appears in the chat’s Run tab. If you ask for changes, its next proposal under the same name replaces the earlier one, which ends Aborted with “Replaced by a newer version”.
From a trigger rule
Section titled “From a trigger rule”A trigger rule’s Start action can pin a One-off Workflow’s text and name. Every firing runs exactly that text, so the rule itself is what you approve. A rule an agent creates or changes with pinned text is saved switched off and marked Needs approval, and only you can switch it on, in the app. A rule never takes a definition from the event that fired it: event fields reach the run only through the goal, as for any rule.
From a watcher wake-up
Section titled “From a watcher wake-up”When the watcher wakes the delivery lead about a run, such as one that failed, and it proposes a One-off Workflow before you have written anything, the proposal is untrusted. It is held with the reason it woke and the run it was about, and a newer proposal about the same run replaces it. The delivery lead is woken again with what you decided.
From a step of a run
Section titled “From a step of a run”A step can propose a child run with the run.propose action. A planner step writes the TOML into the run’s context, and the action proposes it:
[steps.propose]kind = "action"do = "run.propose"source = "{{ context.plan }}"name = "triage"goal = "Triage the failing tests"wait = trueroutes = [ { if = "run.child.outcome == 'succeeded'", to = "steps.done" },]next = "steps.failed"The child is held in the same project and links back to the step that proposed it. The step writes run.child.id. With wait = true, the run gives back its Run Slot and parks until the child ends, then writes run.child.outcome: succeeded, failed, aborted, declined or expired. A proposed run cannot propose another, and one run proposes at most 3 children. Invalid text fails the step and creates no child.
From an agent outside Orbital
Section titled “From an agent outside Orbital”An agent connected over MCP proposes with start_run and source. One-off workflows from agents outside Orbital in Settings > MCP decides what happens: Ask me first, the default, holds the run; Do it starts it at once; Never refuses it. The run shows the client name the agent reported, marked as unverified. Restarting such a run holds it for approval again.
Save a One-off Workflow
Section titled “Save a One-off Workflow”A One-off Workflow that worked can become a saved workflow. Open the run, then choose Save as workflow from its Actions menu. The text opens in the editor as an Import, and you save it as any workflow.