Skip to content
Orbital

Worktrees and delivery

Code workflows work in a worktree, open a pull request and see it merged

Give a workflow a worktree step when it must change files without touching your own checkout. A worktree is an isolated copy of a repository, on a branch of its own. This workflow makes one, changes it, and removes it only when nothing would be lost:

worktree.dot
digraph worktree {
graph [version="1", entry="checkout"]
checkout [shape="folder", action="create"]
implement [prompt="Make the change the goal describes and commit it."]
cleanup [shape="folder", action="remove"]
done [shape="Msquare"]
kept [shape="Msquare", outcome="failed"]
checkout -> implement
implement -> cleanup
cleanup -> done [condition="worktree.clean == true", weight="1"]
cleanup -> kept
}

A worktree is optional. A run gets one only when its workflow has a worktree step. explain-repo, the research, follow-up and triage guides, and most workflows that only read and write text have none.

The shipped code workflows create a worktree first. When the work passes review, they open a pull request and repair it until it merges or closes. Then they remove the worktree, unless that would lose work.

A worktree step with action="create" makes one worktree for each repository folder of the project. All of them share one branch name, orbital/<id>. They live under ~/.orbital/worktrees/. Plain folders, which are not Git repositories, are used where they are. See plain folders and Git.

From then on, each agent step starts in the primary folder’s worktree and reaches the other worktrees as additional folders. Before a worktree exists, a step works in your own folders. That is why explain-repo, which makes no worktree, only reads. Its prompt tells it not to change files.

The dock’s Changes tab shows what the run changed in its worktree, and Files shows the worktree’s files. Open in opens the worktree in your editor.

A worktree step with action="remove" removes the run’s worktrees only when nothing in them would be lost. It keeps a worktree that holds uncommitted changes or commits nobody has pushed, and records why in worktree.status. The shipped workflows then end on a terminal that says the worktree was kept, so you can look.

Never delete a kept worktree to make a run look finished. Commit and push what you need first.

Archiving a run also removes its worktrees.

The shipped delivery workflows share one delivery sub workflow, pr-delivery. It runs these stages:

Stage What happens
Publish An agent step pushes the branch and opens the pull request, following the repository’s conventions. When the step ends, Orbital asks GitHub to squash-merge the pull request once its checks and reviews allow it. A pull request that can merge already merges at once. If the repository does not allow auto-merge, a rule blocks it, or the token lacks permission, the run’s history records that and delivery carries on.
Watch A probe reads the pull request’s state from GitHub.
Wait at a gate While the pull request waits for review or merge, the run waits at a human gate, “The pull request is waiting for review or merge”. It shows a clock and “Waiting: The pull request is waiting for review or merge”, and takes no run slot. Orbital looks at the pull request once a minute and carries on by itself when something changes.
Repair Conflicts, failing CI and requested changes each have a repair step. A repair that changes the branch is reviewed against its reason alone, then published again.
End A merged pull request ends the run Succeeded. A pull request closed without merging ends it Failed.

Choose Skip at the gate, or Resume, to make the run look at the pull request at once. Add gates and waits explains gates.

A gate step reads The pull request is waiting for review or merge, with the waiting time, the next check and a Skip button.
Skip makes the run check the pull request now.

No setting turns auto-merge off. It comes from auto_merge="squash" on the publish step of pr-delivery. That is a sub workflow, not a workflow you can start or open by name. Each delivery workflow imports its own file, subgraphs/pr-delivery.dot, from beside it. A separate pr-delivery of your own is never used. Instead, take your own copy of each delivery workflow you start, and delete auto_merge="squash" from that copy’s pr-delivery.

Every shipped workflow except explain-repo delivers through pr-delivery. implement-ticket and implement-epic reach it through deliver-ticket.

To do it in the app:

  1. Open the workflow.

    Open Workflows and open the shipped workflow you use, for example pursue-goal.

  2. Find the delivery file.

    Open the Prompt docs tab and select subgraphs/pr-delivery.dot. It shows “Imported by delivery”, or “Imported by a nested workflow” for implement-ticket and implement-epic.

  3. Remove the attribute.

    Delete auto_merge="squash" from the publish line, then save.

Saving stores your own copy, with its imported files, under the same name. The list shows it as Custom with “Hides Shipped”. Revert brings the shipped one back.

To do it with files, copy the workflow’s .dot file, with its subgraphs/ and prompts/ folders, into ~/.orbital/workflows/ or the project’s .orbital/ folder. Delete auto_merge="squash" from the copy’s subgraphs/pr-delivery.dot. A workflow there wins over a shipped workflow of the same name. The Ticket to merge example holds the same delivery files.

Auto-merge describes the attribute.

Sometimes GitHub does not run a required check at all, for example because of billing or no runner. The run is then Paused on the probe step, with GitHub’s reason and the check names. See standings. Fix the cause on GitHub, then choose Resume.

A project with several repository folders gets one pull request per repository that changed. The run treats the set as one delivery. It merges only when every pull request merged, and it repairs the worst state first. The dock’s Pull requests section lists them all.

The dock's Pull requests list shows open and merged pull requests, each with its branch.
Every pull request of the run, with its state.

Delivery reads pull requests, checks and review threads through a GitHub token. Orbital tries these in order and uses the first it finds:

  1. the token saved in Settings > GitHub
  2. GH_TOKEN
  3. GITHUB_TOKEN
  4. an existing gh auth login

The page shows which one is in use. See Settings.

Settings, GitHub page shows a saved token and the token sources in order: saved token, GH_TOKEN, GITHUB_TOKEN and gh auth login.
The page names the token source in use.