Brennan Benson f71120551f Stop workers from taking over the Run they work for (#29008)
* fix(orchestration): refuse run-use by a worker on the Run it works for

A worker holding an active Dispatch in a Run could bind that Run as its coordinator.
That silently unbound the real coordinator, remembered the worker's address as a
coordinator address (so the worker's own mail in that Run routed to the Run mailbox
from then on), and when the worker later bound its own sub-Run, left the parent Run
with no coordinator at all.

bindRun now refuses a caller whose handle holds an active Dispatch in the Run, with
worker_cannot_coordinate_own_run, before any effect. Creating its own Run for
sub-workers is unchanged.

* fix(orchestration): tell a worker naming its own Run where its mail is

Workers that made a sub-Run ran `check --run <parent>`, were told "This
coordinator terminal is bound to X, not Y", and ran run-use on the parent
to "switch back", unbinding their coordinator. That refusal now says the
Run belongs to their coordinator, that their own mail arrives through
plain `check`, and that they report with `send`; it never mentions run-use.

The run-use refusal now matches the caller the way check and send do
(address, then pane, so a reminted terminal handle is still caught),
also covers Runs above the caller's own through recorded creator_dispatch_id
lineage, skips context-only self-dispatches so a coordinator can still
rebind its own Run, and passes its code through the RPC wire.

* feat(orchestration): refuse run-use over a live coordinator without --takeover

run-use silently took a Run from whoever coordinated it, even a chat or
agent that was still running. It now refuses with run_coordinator_live
when there is positive evidence the current coordinator is running (its
chat is still reachable, or the agent hooks prove its terminal agent
live) unless the caller passes --takeover. Anything unproven (closed chat,
exited or unhooked terminal, another host) rebinds as before, so restart
handoffs need no flag. The probe is async in the RPC handler; bindRun
enforces it only if the Run is still bound to the probed party.

A caller working a Dispatch can never take over, with or without the
flag (worker_cannot_take_over_run). The help text now says run-use is
for resuming a Run and that workers never use it.

* fix(orchestration): stop pointing workers at run-use

Workers learned run-use from error text: "No Run is bound. Use run-create
or run-use first", "Rebind with orchestration run-use", and "Rebind this
terminal with orchestration run-use". Each now says what the caller can
do instead. An unbound worker is told its mail arrives through plain
check and it reports with send; a displaced coordinator is told to stop
and take the Run back only if the user asks. The orchestration skill now
says run-use resumes your own Run, --takeover needs the user's word, and
workers never run it.

* fix(orchestration): stop routing mail to addresses that grabbed a Run's seat

Every address that ever bound a Run is remembered as one of its
coordinator addresses, so mail to it routes to the Run mailbox. When a
worker bound the Run it was working for, its own address joined that
list for good, and its direct mail in that Run kept landing in the
coordinator's inbox. The live database has 45 such rows since
2026-08-20.

All four readers of the remembered addresses now skip one that was first
bound while it worked an unsettled, delegated Dispatch in the same Run.
It is derived from existing rows, so no migration or delete is needed and
rows written by older builds stop mattering. The active-Dispatch check
also matches a worker's orca_session_id spelling, not only its handle.

* fix(cli): keep the orchestration spec file within its line limit

* fix(orchestration): read remembered coordinator Run ids without a type assertion

* fix(orchestration): compare seat-grab times at whole seconds

first_bound_at has no milliseconds, so a worker bound in the same second its
Dispatch settled was counted as grabbing the seat. Compare completed_at at
whole seconds with a strict >.

* fix(orchestration): a worker coordinates only Runs it created

The worker refusals depended on proving the target's coordinator alive, so
a worker could still take any Run whose coordinator was closed, unhooked,
remote or headless. Replace them with one rule derived from existing rows:
a caller working a Dispatch may bind only a Run it legitimately
coordinated before (a remembered, non-seat-grab address of that Run, or a
Run it dispatched work into), never the Run it works for, and never with
--takeover. A same-binding no-op is never refused, and workers are
classified before the legacy gate so they never see its
--takeover-legacy hint. The refusal names the Dispatch and how to end it
with worker-abandon if it is stale. The ancestor walk is gone.

run-use now records which coordinator it probed. If the binding moved
before the transaction, it probes again (three tries) and then refuses
with a retryable run_binding_changed instead of binding over a party
nobody probed. run_coordinator_live names the chat by its title and
worktree, or the terminal by its title and worktree, says it is still
open, and that closing it clears the refusal.

* fix(orchestration): say what happens to mail on takeover and stop naming run-use to readers

The help now says --takeover replaces the coordinator and replays its
unacknowledged mail to you. A replaced mailbox reader is told only that
another session coordinates the Run and to stop reading it.

* refactor(orchestration): throw one non-null refusal from the live gate

* refactor(runtime): host the coordinator presence probe beside the hook presence seam

Main moved the orphan-adoption runtime file; keeping the one-line probe next
to checkHookAgentPresenceFn leaves this PR off that file.

* fix(orchestration): use findLast for the worktree name

* refactor(runtime): move the coordinator presence probe beside the pty presence recheck

Main is moving the runtime construction files; the probe now sits with
recheckHookAgentPresenceForPty, which reads the same seam, so this PR stays
off the files being moved.

* fix(orchestration): keep workers out of their own Run seat

* fix(orchestration): clarify worker Run handoffs in skill

* test: align explicit Run gate refusal wording

* Move coordinator presence beside terminal presence checks

* Walk complete worker creator lineage when binding Runs

* Restore main documentation after merge hook formatting

* perf(orchestration): check run bindings without terminal snapshots

* test(orchestration): narrow SQLite instrumentation before access

* test(orchestration): import the explicit RPC methods module

* test: cover orchestration restart and continued Run handoff

* test: place orchestration CLI integration in CLI project

* test(cli): use explicit module extensions in restart handoff test

* test(orchestration): isolate source CLI integration in subprocesses

* refactor(orchestration): leave the live-coordinator takeover rule to #29292

#29008 is the worker fix: a worker cannot bind the Run it works for or an
ancestor, cannot abandon itself to get around that, and addresses it held while
grabbing a seat stop redirecting its mail. The separate rule that refuses any
second coordinator while the first is still open (the presence probe, the
--takeover flag and the run_coordinator_live / run_binding_changed refusals)
moves to #29292, which models Run ownership and hand-over and already builds on
it. run-use binds synchronously again, as on main.

* test(orchestration): cover delegated worker legacy takeover refusal

* test(orchestration): explain source CLI integration timeout
2026-10-26 00:46:27 -07:00
2026-03-16 22:27:51 -07:00
2026-03-28 10:19:14 -07:00

Orca Orca

GitHub stars Total downloads across all releases License: MIT Join the Orca Discord Follow Orca on X Supported platforms: macOS, Windows, and Linux

中文 · 日本語 · 한국어 · Español · Français · Português

The AI Orchestrator for 100x builders.
Run Codex, ClaudeCode, OpenCode or Pi side-by-side — each in its own worktree, tracked in one place.

Download Orca

Orca desktop app running agents in parallel worktrees, with the Orca mobile companion app in the corner

Features

Mobile Companion

Monitor and steer your agents from your phone — get notified when an agent finishes and send follow-ups from anywhere.

iOS App Store · Android APK · Docs →

Orca desktop with the mobile companion app

Parallel Worktrees

Fan one prompt across five agents, each in its own isolated git worktree — compare the results and merge the winner.

Docs →

Parallel worktree orchestration

Terminal Splits

Ghostty-class terminals with WebGL rendering, infinite splits, and scrollback that survives restarts.

Docs →

Terminal splits

Design Mode

Click any UI element in a real Chromium window to send its HTML, CSS, and a cropped screenshot straight into your agent's prompt.

Docs →

Embedded browser and Design Mode

GitHub & Linear, Native

Browse PRs, issues, and project boards in-app — open a worktree from any task and review without a context switch.

Docs →

GitHub and Linear task workflows in Orca

SSH Worktrees

Run agents on a beefy remote box with full file editing, git, and terminals — auto-reconnect and port forwarding included.

Docs →

Remote worktrees over SSH

Annotate AI Diffs

Drop comments on any diff line and ship them back to the agent — review, edit, and commit without leaving Orca.

Docs →

Annotate AI-generated diffs

Drag Files to Agents

VS Code's editor with autosave everywhere — drag files or images straight into an agent prompt.

Docs →

Drag files and images into an agent prompt

Orca CLI

Agents drive Orca too — script every workflow with orca worktree create, snapshot, click, and fill.

Docs →

Script Orca from the CLI

Also in the box:

  • Quick open — Search across worktrees, files, agents, commands, and repo context without leaving your flow.
  • Account switcher & usage tracking — See Claude and Codex usage and rate-limit resets, and hot-swap accounts without re-logging in.
  • Rich repo previews — Preview Markdown, images, PDFs, and repo docs in the workspace.
  • Computer Use — Let agents operate desktop apps and visible UI when a workflow needs real interaction.
  • Notifications and unread state — Know when an agent finishes or needs attention, then mark threads unread to come back later.
  • And many, many more — we ship daily, so this list is perpetually behind. The changelog is the real feature list.

Supported Agents

Works with any CLI agent — if it runs in a terminal, it runs in Orca.

Claude Code logo Claude Code   Codex logo Codex   Grok logo Grok   Cursor logo Cursor   GitHub Copilot logo GitHub Copilot   Muse logo Muse   DeepSeek Harness logo DeepSeek Harness   ZCode logo ZCode   OpenCode logo OpenCode   MiMo Code logo MiMo Code   Amp logo Amp   OpenClaude logo OpenClaude   Antigravity logo Antigravity   Pi logo Pi   oh-my-pi logo oh-my-pi   Hermes Agent logo Hermes Agent   Devin logo Devin   Goose logo Goose   Auggie logo Auggie   Autohand Code logo Autohand Code   Charm logo Charm   Cline logo Cline   CodeBuddy logo CodeBuddy   Codebuff logo Codebuff   Freebuff logo Freebuff   Command Code logo Command Code   Continue logo Continue   Droid logo Droid   Kilocode logo Kilocode   Kimi logo Kimi   Kiro logo Kiro   Mistral Vibe logo Mistral Vibe   Qwen Code logo Qwen Code   Rovo Dev logo Rovo Dev   + any CLI agent


Install

Desktop — macOS, Windows, Linux

Or via a package manager:

# macOS (Homebrew)
brew install --cask stablyai/orca/orca

# Arch Linux (AUR) — or stably-orca-git to build from source
yay -S stably-orca-bin

Mobile Companion — iOS, Android

Pair with your desktop app to monitor and steer your agents from your phone.


Community & Support

  • Discord: Join the community on Discord.

  • Twitter / X: Follow @orca_build for updates and announcements.

  • WeChat: Group 12 is full. Scan to join the Orca community WeChat group 13.

    WeChat group 13 QR code for the Orca community
  • Feedback & Ideas: We ship fast. Missing something? Request a new feature.

  • Privacy: See the privacy & telemetry docs for what anonymous usage data Orca collects and how to opt out.

  • Show Support: Star this repo to follow along with our daily ships.


Developing

Want to contribute or run locally? See our CONTRIBUTING.md guide.

The relay that pairs the mobile app with a desktop host is also in this repository under cloud/, with a separate pnpm workspace and setup guide.

Orca contributors

GitHub star history chart for stablyai/orca

Signed Builds

Windows code signing sponored/provided by SignPath.io, certificate by SignPath Foundation.

License

Orca is free and open source under the MIT License.

S
Description
Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.
Readme MIT
2.4 GiB
Languages
TypeScript 96.2%
JavaScript 3.2%
Swift 0.2%
CSS 0.1%