Run a delivery window
A delivery window drains your approved backlog for a set time. Orbit starts backlog tasks in parallel until the window closes; work already in flight finishes. Starting a window returns a run ID, not finished work, so check each task’s status before you treat it as delivered.
A second machine can drain the same workspace as a replica
(orbit ) while the owner keeps landing authority.
See Set Up a Distributed Drain.
Each step shows the dashboard or agent route first and the CLI as the fallback.
1. Prepare proposed work
Section titled “1. Prepare proposed work”The task pilot fills in each task’s context_files (the files and directories
it will work in) and assesses its complexity. It does not approve or dispatch
anything.
-
Agent: ask your agent to pilot the proposed tasks.
-
Dashboard: in Automation → Jobs, click Run ▸ on
task_pilot_pipeline. To pilot new and edited tasks automatically, turn on thetask_pilotroutine in Automation → Routines. It is off by default and runs on the host scheduler clock. -
CLI:
Terminal window # Tasks that need a pilot.orbit run task-pilot --waitorbit run task-pilot "$TASK_ID" "$OTHER_TASK_ID" --wait # exact tasks
Without task IDs, the pilot picks up proposed and backlog tasks whose
context_files is empty or whose complexity is unassessed. It skips a task it
already found to have no in-workspace targets while that assessment is fresh;
editing the task’s description, criteria, status, or source makes it eligible
again, and naming its ID always audits it again.
When preparation selects no tasks, the run skips agent dispatch and applies an empty result collection successfully, retaining any held-task skip details. For a nonempty selection, at least one pilot partition must succeed before apply runs; valid partitions can still apply when a sibling pilot fails.
Before you approve, check the pilot run (in Runs) and the selectors it applied (the task’s context files in Tasks). From the CLI:
orbit run history -j task_pilot_pipelineorbit run show "$PILOT_RUN_ID"orbit task show "$TASK_ID" --fields status,context_files2. Authorize the backlog
Section titled “2. Authorize the backlog”Approving a proposed task moves it to backlog, where a window can start
it. The task pilot alone does not approve work; approve tasks individually or
authorize a local drain to approve qualifying proposals.
-
Dashboard: in Tasks, click Approve on the task under Awaiting approval.
-
Agent: tell your agent which tasks to approve.
-
CLI:
Terminal window orbit task update "$TASK_ID" --approve --note "Pilot context reviewed."
Do not approve a task that is already in backlog. Once its pilot has
applied the context it needs, it is ready.
To authorize approval throughout a local window:
orbit run auto --for 4h --approve-proposedWhile the window is open, the drain pilots proposed tasks with the
no-diff-expected tag, or with context files and an assessed complexity. It
approves those with no duplicate, already-landed, conflict or warning
finding, including tasks filed while the window is open. Each pilot runs in
the background, so backlog work keeps starting meanwhile, and the drain
admits what a pilot approved as soon as it finishes. Tasks tagged no-auto-approve stay
proposed until a human approves them. Other held tasks also stay proposed;
orbit and orbit report approval counts and hold
reasons. A warnings hold also names each finding: under Approved: in
orbit , and as findings (kind and the finding’s first line) on
each held task in orbit . The dashboard shows that same
text on the live window’s approval hold. Each approval’s history note names the drain run.
--approve-proposed is off by default and conflicts with --pull, since
only the owner approves work. Approval still respects dependencies, file
locks, and crew restrictions when the drain admits a task. Add --complete
separately if the window should also finish delivery.
3. Check what will actually start
Section titled “3. Check what will actually start”Readiness is a read-only snapshot of what a window would start now and why the rest would wait. It reserves and submits nothing, so an eligible task is not guaranteed to start.
-
Dashboard: the Tasks dock’s Drain tab shows what a window started now would admit and how many tasks are eligible or waiting. The task list’s Backlog card sorts the backlog into Eligible now, Waiting on locks, Waiting on capacity, and Waiting, other, and each row’s tooltip names what it waits on. Locks held in the Tasks dock shows held locks (
orbit).task locks list -
CLI, for the reason behind each task:
Terminal window orbit run readinessorbit run readiness --concurrency 8orbit run readiness "$TASK_ID" --jsonWith no
--concurrency, the ceiling is the live local drain’s, including a laterorbit, otherwise a live pull drain’s, otherwise 5.run concurrency --set --jsonnames that choice ascapacity.(limit_source run_input,run_control,pull_run_input,pull_run_control, ordefault). Text adds aLeafline only when the pull drain supplies the ceiling.ceiling:
Common reasons a backlog task waits:
-
Unsatisfied dependencies.
-
An active file lock. Two tasks whose selectors overlap cannot run at once.
orbitshows which files the backlog collides on, which is what really limits your parallelism.task locks contention -
surface_reserved: a critical or high-priority task ahead of it in the queue is waiting on file locks, and this task overlaps the files it needs. It waits so the higher-priority task gets each lock as it frees, instead of losing it to smaller tasks one lock at a time. It starts once that task starts. Unrelated work is not held. -
awaiting_footprintorawaiting_exclusive_slot: the task has nocontext_files, so it holds no file lock and could collide with anything. A drain with more than one slot waits for the task pilot to fill them in, then starts the task only when nothing else is running. File such tasks asproposedand let the pilot prepare them before promoting them. -
crew_not_allowed, when you preview a crew restriction or a running window has one. -
pilot_duplicateorpilot_already_landed: the latest applied task-pilot assessment found duplicate work or work already landed. This also holds tasks filed directly into backlog. Read the finding in the task comments. Run task-pilot again to reassess it; a new assessment without either finding releases the hold. To approve the work anyway or clear a mistaken finding, append an explicit human decision from your CLI:Terminal window orbit task update "$TASK_ID" \--comment 'task-pilot-admission: approve-anyway'# Or clear a mistaken finding:orbit task update "$TASK_ID" \--comment 'task-pilot-admission: clear'The first line must match exactly; put any explanation on later lines. Both decisions release the current assessment’s admission hold while preserving its audit evidence. A later pilot assessment supersedes the decision. Ordinary edits, unrelated comments, and agent-authored decisions do not release it. All other admission checks still apply.
-
native_os_required: the pilot found native-host evidence requirements this host cannot satisfy. Route to a capable host, re-scope the criteria, or record an evidenced humantask-pilot-admission:orclear approve-anywaydecision. This decision stays valid across later pilot passes with the same criteria digest, OS requirement set and machine requirement; requirement order does not matter. Changed criteria or requirements supersede it. A new assessment still supersedes operator-validation and host-operational decisions. -
delivery_job_unavailable: the task’sdelivery:<job>tag selects a plugin delivery job whose plugin is disabled or uninstalled, or that does not declare the drain’s ship mode. The detail names the plugin. Enable it or remove the tag. -
pr_forge_remote_missing: the workspace ships through pull requests, but no Git remote of the checkout names a network host (only a local bare repository, say), sopr_opencould never succeed. The detail names the remotes. Runorbit, add a remote on the forge host, or tag the taskworkspace ship-mode local delivery:task_local_pipelineto deliver it locally.orbitreports the same verdict on itsdoctor forge-remoterow. -
local_route_before_pr:review.istiming before_prand this workspace ships locally, or the task’sdelivery:task_local_pipelinetag routes it locally. Before-PR review holds pull-request creation and does not run on the local-only route, so the task stays in the backlog instead of failing after dispatch. The detail names whether the global or workspace config set it. Setreview.totiming off, or ship through the PR route.orbitnames the same combination.doctor -
local_route_before_landing: the same hold forreview.attiming before_landing, which reviews an open pull request before it lands; a local delivery opens none. Setreview.totiming off, or ship through the PR route.
Neither approval nor the drain bypasses dependencies or locks, so a window may end with some tasks still in the backlog.
4. Start a bounded window
Section titled “4. Start a bounded window”-
Dashboard: on Drain → Start, pick a Window length (one pass, or
1hto24h), set Parallel tasks, and turn on Mark shipped tasks done to complete them (off stops at review). Optionally turn on Approve qualifying proposals (--approve-proposed) or Auto-fix PR blockers to repair the window’s blocked PRs. Click Start … window and confirm. See Auto-drain. -
Agent: ask for a window and say how long, how many tasks at once, and whether to complete them.
-
CLI:
Terminal window orbit run auto --for 3horbit run auto --for 3h --concurrency 8orbit run auto --for 3h --complete
The window length bounds only when new work may start; a task in flight when
it expires still finishes. Parallel tasks (--concurrency, default 5) is
not a batch size: the drain refills each free slot from the whole backlog.
--auto-concurrency selects forecast-based admission for this
window: shadow records what the forecast would admit, while enforce uses
measured CPU and memory profiles to fit new work within host capacity. The
concurrency ceiling still applies. Omit the flag to use the host’s configured
mode.
Mark shipped tasks done (--complete) authorizes this window to move every task it
ships from review to done, including tasks admitted later in the window. It
never approves proposed tasks. In the dashboard it needs an operator
session. See Completing work with
--complete.
Repair blocked pull requests
Section titled “Repair blocked pull requests”--auto-fix lets the window repair the pull requests it opened when a required
check fails or the branch conflicts with its base. It is off by default. In the
dashboard, check Auto-fix PR blockers when starting a window; this requires
an operator session on the owner machine and is disabled on pull replicas.
Completion and proposed-task approval remain separate choices. The receipt
reports whether repair was enabled. From the CLI:
orbit run auto --for 4h --auto-fixorbit run auto --for 4h --auto-fix --completeThe drain keeps watching each PR. Pending checks wait. A failed required check
or a conflict goes to the existing repair step, which runs as a crew from
workflow., else workflow.
(narrowed by --allow-crew). The repair then
passes your required validation and is pushed, and the drain checks the new
head. Approvals, permissions, admin rules, unknown status and optional-check
failures launch no agent. Each PR gets at most one repair per head and blocker,
and three in total; the attempts are recorded in the task’s history.
--auto-fix never merges. Add --complete to also merge and finish tasks.
See System work.
To follow the window, open its run from the Drain card header; the run
detail lists the child runs it started. A task in progress has View run on
its row. From the CLI, record the returned ID as $AUTO_RUN_ID:
orbit run show "$AUTO_RUN_ID"orbit run trace "$AUTO_RUN_ID" # run tree with child run IDsorbit run logs "$CHILD_RUN_ID"orbit task show "$TASK_ID" --fields status,job_run_id,commentsA task’s submitted run is not its status; check the task itself.
Restrict a window to some crews
Section titled “Restrict a window to some crews”--allow-crew limits one drain to the crews you name, for example when a
provider is down, rate-limited, or out of budget. Ask your agent or use the
CLI, or toggle Allowed crews on Drain → Start.
orbit run auto --for 4h --allow-crew opus,sonnet# Preview what readiness would skip.orbit run readiness --allow-crew opus,sonnet- For this run only. Without it, the drain runs every crew. No configuration is changed. An unknown or empty crew name fails before anything is dispatched.
- Enforced throughout. Every activity in the run is checked against the
crew that actually resolved, including a recovery crew drawn from a
complexity pool. The check
permits the named crews and aliases with the same effective provider,
model, and provider account. A crew with its own
envhas a separate account and must be explicitly allowed even when its provider and model match. The allowlist gates the crew that normal precedence picks; it never picks one. - Skips, never remaps. A task whose crew is excluded stays in
backlog, and readiness reports it ascrew_not_allowed, also without--allow-crewwhile the window runs. The dashboard’s Drain card lists the window’s allowed crews and the tasks they leave out. There is no automatic fallback to another provider. To move the task, change its crew in Tasks or withorbit.task update <id> --crew <name> - Leaves other work alone. Work another invocation already started keeps running.
5. Retune a running drain
Section titled “5. Retune a running drain”To change how many tasks a live drain keeps in flight, retune it rather than cancel it. Ask your agent or use the CLI; the dashboard has no retune control.
# Show the current ceiling and who last set it.orbit run show "$AUTO_RUN_ID"orbit run concurrency "$AUTO_RUN_ID" --set 7# Reduce the ceiling after a provider rate limit.orbit run concurrency "$AUTO_RUN_ID" --set 3 --reason 'provider rate limited'Retuning keeps the run ID, deadline, completion authorization, and every child
already dispatched. Cancelling and starting again mints a new run ID, restarts
the window, and makes you restate --complete and --allow-crew.
- Raising the ceiling fills the extra slots on the next admission pass, usually within a poll interval.
- Lowering it pauses admissions until enough children finish. Tasks in flight are never cancelled or cut short.
- The ceiling cannot exceed the leaf pipeline’s own active-run limit. A run that is not a drain, has not started, or has finished is refused.
--if-revisionapplies the change only while the ceiling is still the one you read, so two operators cannot silently overwrite each other.N
6. Stop admissions, or cancel work
Section titled “6. Stop admissions, or cancel work”These are different actions.
Stop new admissions. Click Stop on the Drain card (it needs an
operator session), or run orbit (no run ID needed). Children already started keep
running under the completion authority they were admitted with, and the
coordinator is not cancelled. Stopping again, or with no active window, does
nothing. Other workspaces and jobs are untouched. orbit then reports who stopped admissions. --stop cannot be
combined with flags that start a drain, including --for, --concurrency,
--complete, --approve-proposed, or --allow-crew.
Cancel work in flight. Cancel each child you want to abandon: open it in Runs and click cancel, or:
orbit run trace "$AUTO_RUN_ID" # find the child run IDsorbit run cancel "$CHILD_RUN_ID" --confirmCancelling a task leaf returns its task to backlog with the reason and keeps
its candidate available to resume. Add --block to keep the task blocked for
manual recovery instead.
A plain cancel of a local drain leaves its children running. Stop admissions
first, then cancel only the children you want to abandon, or use
orbit to stop the drain and all
the task runs it started. A child whose stop cannot be confirmed is reported
and makes the command exit 1.
Cancelling a pull drain is
graceful: unlaunched claims return to the owner’s backlog while launched
leaves finish and settle. --force stops those leaves too and returns their
claims to the owner’s backlog once their stop is confirmed.
7. Recover from a failed delivery
Section titled “7. Recover from a failed delivery”Ask your agent first. The orbit-orchestrate skill reads the run evidence,
matches it to a known failure, and files a repair task when the code needs
fixing.
By hand, find out why the run failed before you retry. Fix a real code, review, or dependency problem first; do not rerun blindly.
-
Find the failure. In Runs, filter to Failed and open the run; it opens on the failed step and its error. From the CLI,
orbitgroups failures by task and root cause;run history --failures orbitlists the window’s failed children, andrun show "$AUTO_RUN_ID" orbitorrun show orbiton a child gives the detail.run logs -
Check recovery steps. A failure the agent declares itself goes through step recovery before the task is sent to
blocked, so check those steps before deciding what a blocked task needs. -
Retry deliberately. A task blocked by its own failure stays blocked. Missing-launcher and transient-infrastructure blocks can instead be rechecked with
orbitafter their cause clears; transient recovery requires an authenticated published candidate and is bounded. Otherwise, once the cause is fixed, either:task recheck-blocked --confirm - click Resume on the failed run in Runs (
orbit) to continue from its first unsuccessful step; orjob resume <run-id> - move the task back to
backlogwith its status dropdown in Tasks (orbit) so a later window runs it again, resuming any saved candidate.task update "$TASK_ID" --status backlog
orbitprints the exact command on itstask show "$TASK_ID" Next:line. A show routed to another host prints the same line, and the dashboard task detail carries the samenext_step. - click Resume on the failed run in Runs (
A cancelled task leaf is already back in backlog by default, with its
candidate resumable on the next delivery. If you cancelled with --block,
return it to backlog when it is ready to run again.
Repair a cancelled owner-local published PR
Section titled “Repair a cancelled owner-local published PR”Generic resume still refuses cancelled runs. When an owner-local task PR run was deliberately cancelled after publication and its task remains in review, an operator on the owning host can explicitly authorize remaining source work on that same task, branch and PR. This does not admit claimed leaves or foreign runs, and does not release a draft/evidence hold.
First make the canonical task description, criteria, plan and complete context selectors describe the work you now authorize. Restore any temporarily released selectors before inspection. The cancelled worker must have conclusively stopped; its successful host commit, prepare, sync, push and PR checkpoints, retained Git objects and exact local and remote branch must still be available. The PR must be open, unmerged and have automatic merge disabled. Unreadable or uncertain merge intent refuses admission.
Run these public tool requests as the operator (a model session cannot confer
this authority). Use a deployment whose orbit schema advertises source_repair; the owner, worker
and any long-lived client must be on the compatible executable generation and
store schema before use. Existing resume callers need no new argument. This
feature adds a version-1 binding and append-only repair ledger, with no store
schema migration. Installation and client restart remain operator actions.
orbit tool run orbit.workflow.run.resume --input \ '{"id":"<cancelled-run-id>","source_repair":{"action":"inspect","task_id":"<task-id>"}}'If the workspace has an exclusive claim, include its authorized claim_token
as a top-level field in both requests; operator authority does not bypass it.
Inspection returns binding, current review, and prior reservations.
Copy the entire returned binding object verbatim into a local request file;
do not construct a head or digest yourself:
{ "id": "<cancelled-run-id>", "source_repair": { "action": "submit", "task_id": "<task-id>", "request_key": "published-source-repair-1", "binding": { "<replace with the entire inspected binding>": "" }, "diagnosis": "Name the failing CI run/job or observed source defect, its published head, and the remaining source edits explicitly authorized." }}orbit tool run orbit.workflow.run.resume --input-file source-repair-request.jsonThe binding pins the workspace, owner machine, source run and checkpoints, repository and origin URL, task meaning/tools/crew and footprint, PR, branch, published head and recorded base. A successful host rebase is authenticated by the complete prepare/sync/push/PR chain; the pre-rebase commit need not be an ancestor of the published head. Changed evidence or scope requires a fresh inspection; a changed payload under an existing request key is refused.
A request key contains 1–128 ASCII letters, digits, -, _, ., or :.
Submission durably reserves the bounded per-PR repair budget before admitting
one linked run. Repeat the identical request after a lost reply: it returns the
same run without spawning another worker, even after that run stops. A new key
cannot recharge the same head, and cancellation does not refund a reservation.
The new attempt continues the saved candidate with today’s authorized task
specification under normal footprint locks, crew/OS/capacity and build budget.
It inherits no validation or review checkpoint and reruns required commands on
the repaired source. It captures the current host’s review schedule: none for
an after-landing coverage setup, or before-landing review on the published head
when configured (before-PR configuration also retains its normal meaning).
No configuration change or additional review gate is needed. Independent review
uses that captured schedule; after-landing coverage remains the configured
delivery-code-review automation.
The attempt always requests completion: and auto_fix: .
Inspect its resulting PR and validation/review evidence before separately
requesting completion or automatic repair authority. This operator diagnosis
path does not depend on automatic CI annotation classification.
A host-specific or environmental failure that keeps recurring needs the host fixed, not another attempt.
A run stuck pending with no live worker holds its task reservations; cancel
it in Runs or with orbit . The
stuck job runs runbook
explains how to tell a stuck run from a slow one.
Then check the workspace and reclaim worktrees left by settled tasks:
orbit doctor# Report what it would reap.orbit gc worktrees# Remove the settled worktrees.orbit gc worktrees --confirm# Free build output while keeping checkouts.orbit gc worktrees --reclaim --confirmorbit collects only worktrees whose task is done, rejected,
or archived, and removes nothing without --confirm. On a replica it reads
task status from the owner machine. --reclaim deletes declared
worktree. paths (default ["target"]) only after terminal-run, worker,
registration, confinement, symlink and Git content checks. The failed run’s
checkout and unmatched evidence stay available for rescue. The scheduled sweep
also reclaims declared output in every kept terminal worktree. To limit it by age or to one run, see
the CLI reference.
The scheduled worktree_gc_pipeline run also prunes the checkout’s
. scratch directory: a top-level entry goes once nothing inside it
has changed for 24 hours. Pass --input to
orbit to change the window for a run. Entries a
live process holds open or an active run names are skipped and reported.
8. Keep the task record durable
Section titled “8. Keep the task record durable”A delivery window changes a lot of task state. To snapshot it somewhere you can restore from, see Publish and Restore Tasks. To operate across hosts, federated MCP setup explains how to select the owning workspace, without implying automatic failover.