From 5c736da025b10aa21b62a4a22e1d98da1fea6b94 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 01:57:03 -0700 Subject: [PATCH 01/18] feat(orchestration): report the caller's host-resolved orchestration address in orca status orca status --json gains a caller block: the calling agent's address as the host resolved it from the identity its environment carries. A structured session is session:; a terminal agent is its handle, with whether the host still knows it. A session the host refuses reports that refusal instead. The host answers through a new read-only orchestration.callerShow, so the session claim runs through the same dispatch-entry resolver every verb uses. An older host leaves caller unresolved. The help footer and the run/check specs stop describing identity only in terminal terms. --- src/cli/format.ts | 14 +- src/cli/handlers/core.ts | 10 +- src/cli/root-help-text-primary.ts | 4 +- src/cli/root-help-text-secondary.ts | 3 + src/cli/runtime/status-caller.test.ts | 178 ++++++++++++++++++ src/cli/runtime/status-caller.ts | 46 +++++ src/cli/specs/core.ts | 3 + src/cli/specs/orchestration.ts | 8 +- src/main/runtime/rpc/methods/orchestration.ts | 4 +- .../rpc/methods/orchestration/caller-show.ts | 33 ++++ .../methods/orchestration/runs/runs.test.ts | 3 +- .../rpc/orchestration-caller-show.test.ts | 124 ++++++++++++ .../rpc/orchestration-session-caller.test.ts | 4 +- src/shared/orchestration-caller-status.ts | 36 ++++ .../rpc-params-catalog.generated.ts | 1 + src/shared/runtime-session-contracts.ts | 3 + 16 files changed, 463 insertions(+), 11 deletions(-) create mode 100644 src/cli/runtime/status-caller.test.ts create mode 100644 src/cli/runtime/status-caller.ts create mode 100644 src/main/runtime/rpc/methods/orchestration/caller-show.ts create mode 100644 src/main/runtime/rpc/orchestration-caller-show.test.ts create mode 100644 src/shared/orchestration-caller-status.ts diff --git a/src/cli/format.ts b/src/cli/format.ts index 3893eaea7e5..41d10b5b6c5 100644 --- a/src/cli/format.ts +++ b/src/cli/format.ts @@ -1,3 +1,4 @@ +import type { CliStatusCaller } from '../shared/orchestration-caller-status' import type { CliStatusResult } from '../shared/runtime-types' import { prepareComputerCliJsonResult } from './computer-format' import type { RuntimeRpcSuccess } from './runtime-client' @@ -136,10 +137,21 @@ export function formatCliStatus(status: CliStatusResult): string { `runtimeReachable: ${status.runtime.reachable}`, `runtimeConnectionState: ${status.runtime.connectionState ?? 'unknown'}`, `runtimeId: ${status.runtime.runtimeId ?? 'none'}`, - `graphState: ${status.graph.state}` + `graphState: ${status.graph.state}`, + ...(status.caller === undefined ? [] : [`caller: ${formatStatusCaller(status.caller)}`]) ].join('\n') } +function formatStatusCaller(caller: CliStatusCaller): string { + if (caller === null) { + return 'none' + } + if ('refusal' in caller) { + return `session:${caller.sessionId} (refused: ${caller.refusal.code})` + } + return `${caller.address}${caller.live ? '' : ' (not live)'}` +} + export function formatStatus(status: CliStatusResult): string { return formatCliStatus(status) } diff --git a/src/cli/handlers/core.ts b/src/cli/handlers/core.ts index 6a1b7ab3918..49450d7c19b 100644 --- a/src/cli/handlers/core.ts +++ b/src/cli/handlers/core.ts @@ -3,6 +3,7 @@ import type { CommandHandler } from '../dispatch' import { formatCliStatus, formatStatus, printResult } from '../format' import { RuntimeClientError, serveOrcaApp } from '../runtime-client' import { stripElectronRunAsNode } from '../runtime/launch' +import { resolveCliStatusCaller } from '../runtime/status-caller' import { getServeOptionValidationError } from '../../shared/serve-option-validation' function envRecord(): Record { @@ -129,6 +130,13 @@ export const CORE_HANDLERS: Record = { if (!json && !result.result.runtime.reachable) { process.exitCode = 1 } - printResult(result, json, formatStatus) + const caller = result.result.runtime.reachable + ? await resolveCliStatusCaller(client) + : undefined + printResult( + caller === undefined ? result : { ...result, result: { ...result.result, caller } }, + json, + formatStatus + ) } } diff --git a/src/cli/root-help-text-primary.ts b/src/cli/root-help-text-primary.ts index 2d4561f3098..8f58b54f1e7 100644 --- a/src/cli/root-help-text-primary.ts +++ b/src/cli/root-help-text-primary.ts @@ -95,8 +95,8 @@ export const ROOT_HELP_TEXT_PRIMARY = [ '', 'Orchestration:', ' orchestration run-create Create and bind a lightweight orchestration Run', - ' orchestration run-use Bind this coordinator terminal to an existing Run', - " orchestration run-current Show this terminal's bound Run", + ' orchestration run-use Bind this coordinator to an existing Run', + " orchestration run-current Show this coordinator's bound Run", ' orchestration run-list List lightweight orchestration Runs', ' orchestration run-show Show one lightweight orchestration Run', ' orchestration send Send an inter-agent message', diff --git a/src/cli/root-help-text-secondary.ts b/src/cli/root-help-text-secondary.ts index 8602e35c49e..8a1ff895b25 100644 --- a/src/cli/root-help-text-secondary.ts +++ b/src/cli/root-help-text-secondary.ts @@ -112,6 +112,9 @@ export const ROOT_HELP_TEXT_SECONDARY = [ ' Most commands require a running Orca runtime. If Orca is not open yet, run `orca open` first.', ' Remote runtime access can also be supplied with ORCA_PAIRING_CODE or ORCA_ENVIRONMENT.', ' Use selectors for discovery and handles for repeated live terminal operations.', + ' Inside an Orca agent, `orca status --json` reports its orchestration address as caller.address:', + ' session: for a chat session, its terminal handle for a terminal agent.', + ' When ORCA_CLI_COMMAND is set, run that executable; bare `orca` in a login shell can reach another Orca.', '', 'Agent Sessions And Worktrees:', ' `worktree create --agent` creates a new checkout with an agent.', diff --git a/src/cli/runtime/status-caller.test.ts b/src/cli/runtime/status-caller.test.ts new file mode 100644 index 00000000000..75924e303a6 --- /dev/null +++ b/src/cli/runtime/status-caller.test.ts @@ -0,0 +1,178 @@ +import { mkdtempSync, writeFileSync } from 'node:fs' +import { createServer, type Server, type Socket } from 'node:net' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { getRuntimeMetadataPath } from '../../shared/runtime-bootstrap' +import type { RuntimeOrchestrationEnvelope } from '../../shared/runtime-rpc-envelope' +import { CORE_HANDLERS } from '../handlers/core' +import { RuntimeClient } from './client' + +const SESSION = '4a1f6c2e-8b3d-4e7a-9c15-0d2b6e8f1a37' +const RUNTIME_ID = 'runtime-caller' +const IDENTITY_ENV = ['ORCA_AGENT_SESSION_ID', 'ORCA_TERMINAL_HANDLE', 'ORCA_PANE_KEY'] as const + +type ReceivedRequest = RuntimeOrchestrationEnvelope & { + id: string + method: string + params?: unknown +} + +type HostReply = { result: unknown } | { error: { code: string; message: string } } + +/** + * The real `orca status` handler and CLI client over a real Unix socket. The host's side of + * `orchestration.callerShow` is covered against the real dispatcher in orchestration-caller-show. + */ +describe.skipIf(process.platform === 'win32')('orca status reports its caller address', () => { + let server: Server + const sockets = new Set() + const received: ReceivedRequest[] = [] + const savedEnv = new Map() + let userDataPath: string + let callerShowReply: HostReply + + beforeEach(async () => { + for (const key of IDENTITY_ENV) { + savedEnv.set(key, process.env[key]) + delete process.env[key] + } + received.length = 0 + userDataPath = mkdtempSync(join(tmpdir(), 'orca-status-caller-')) + const endpoint = join(userDataPath, 'runtime.sock') + server = createServer((socket) => { + sockets.add(socket) + socket.once('close', () => sockets.delete(socket)) + socket.once('data', (data) => answer(socket, String(data).trim())) + }) + await new Promise((resolve) => server.listen(endpoint, resolve)) + writeFileSync( + getRuntimeMetadataPath(userDataPath), + JSON.stringify({ + runtimeId: RUNTIME_ID, + pid: process.pid, + transport: { kind: 'unix', endpoint }, + authToken: 'token', + startedAt: Date.now() + }) + ) + }) + + afterEach(async () => { + for (const socket of sockets) { + socket.destroy() + } + await new Promise((resolve) => server.close(() => resolve())) + vi.restoreAllMocks() + for (const [key, value] of savedEnv) { + if (value === undefined) { + delete process.env[key] + } else { + process.env[key] = value + } + } + }) + + function answer(socket: Socket, line: string): void { + const request: ReceivedRequest = JSON.parse(line) + received.push(request) + const reply: HostReply = + request.method === 'status.get' + ? { + result: { + runtimeId: RUNTIME_ID, + rendererGraphEpoch: 1, + graphStatus: 'ready', + authoritativeWindowId: null, + liveTabCount: 0 + } + } + : callerShowReply + const ok = 'result' in reply + socket.write( + `${JSON.stringify({ id: request.id, ok, ...reply, _meta: { runtimeId: RUNTIME_ID } })}\n` + ) + } + + async function status(json: boolean): Promise { + const log = vi.spyOn(console, 'log').mockImplementation(() => {}) + await CORE_HANDLERS.status({ + client: new RuntimeClient(userDataPath), + flags: new Map(), + cwd: userDataPath, + json + }) + return String(log.mock.calls.at(-1)?.[0]) + } + + async function statusCaller(): Promise { + const printed: { result: Record } = JSON.parse(await status(true)) + return printed.result.caller + } + + function callerShowRequests(): ReceivedRequest[] { + return received.filter((request) => request.method === 'orchestration.callerShow') + } + + it('asks the host as the session its environment names, and prints what the host resolved', async () => { + process.env.ORCA_AGENT_SESSION_ID = SESSION + process.env.ORCA_TERMINAL_HANDLE = 'term_tui' + const address = { + kind: 'session', + address: `session:${SESSION}`, + sessionId: SESSION, + live: true + } + callerShowReply = { result: { caller: address } } + + expect(await statusCaller()).toEqual(address) + const [request] = callerShowRequests() + // Nothing names the caller in params: the host reads the envelope, as every verb's entry does. + expect(request?.params).toBeUndefined() + expect(request?.orchestrationCompatibilityEvidence).toMatchObject({ + agentSessionId: SESSION, + terminalHandle: 'term_tui' + }) + expect(await status(false)).toContain(`caller: session:${SESSION}`) + }) + + it('asks the host about the terminal handle a PTY agent carries', async () => { + process.env.ORCA_TERMINAL_HANDLE = 'term_mine' + callerShowReply = { + result: { caller: { kind: 'terminal', address: 'term_mine', live: false } } + } + + expect(await statusCaller()).toEqual({ kind: 'terminal', address: 'term_mine', live: false }) + expect(callerShowRequests()[0]?.orchestrationCompatibilityEvidence).toEqual({ + terminalHandle: 'term_mine' + }) + expect(await status(false)).toContain('caller: term_mine (not live)') + }) + + it("reports the host's refusal of the session instead of an address", async () => { + process.env.ORCA_AGENT_SESSION_ID = SESSION + callerShowReply = { + error: { code: 'session_caller_not_live', message: `Agent session ${SESSION} has ended.` } + } + + expect(await statusCaller()).toEqual({ + kind: 'session', + sessionId: SESSION, + live: false, + refusal: { code: 'session_caller_not_live', message: `Agent session ${SESSION} has ended.` } + }) + }) + + it('leaves the caller out when the host predates the method', async () => { + process.env.ORCA_AGENT_SESSION_ID = SESSION + callerShowReply = { error: { code: 'method_not_found', message: 'Unknown method' } } + + expect(JSON.parse(await status(true)).result).not.toHaveProperty('caller') + }) + + it('reports no caller, without asking the host, for a process with no identity', async () => { + expect(await statusCaller()).toBeNull() + expect(received.map((request) => request.method)).toEqual(['status.get']) + expect(await status(false)).toContain('caller: none') + }) +}) diff --git a/src/cli/runtime/status-caller.ts b/src/cli/runtime/status-caller.ts new file mode 100644 index 00000000000..f77e09495e9 --- /dev/null +++ b/src/cli/runtime/status-caller.ts @@ -0,0 +1,46 @@ +import { readInjectedAgentSessionId } from '../../shared/agent-session-caller-env' +import type { + CliStatusCaller, + OrchestrationCallerShowResult +} from '../../shared/orchestration-caller-status' +import { ORCHESTRATION_SESSION_CALLER_ERROR_CODES } from '../../shared/orchestration-session-caller-codes' +import type { RuntimeClient } from './client' +import { RuntimeClientError } from './types' + +const SESSION_REFUSAL_CODES = new Set( + Object.values(ORCHESTRATION_SESSION_CALLER_ERROR_CODES) +) + +// Resolving a session may bring up the agent-session host, which the 1s status probe cannot cover. +const CALLER_SHOW_TIMEOUT_MS = 10_000 + +/** + * This process's orchestration address, resolved by the host from the identity the orchestration + * envelope carries. `undefined` when nothing could be resolved: an older host, or a failed call. + */ +export async function resolveCliStatusCaller( + client: Pick +): Promise { + const sessionId = readInjectedAgentSessionId() + if (!sessionId && !process.env.ORCA_TERMINAL_HANDLE?.trim()) { + return null + } + try { + const response = await client.call( + 'orchestration.callerShow', + undefined, + { timeoutMs: CALLER_SHOW_TIMEOUT_MS } + ) + return response.result.caller + } catch (error) { + if (sessionId && error instanceof RuntimeClientError && SESSION_REFUSAL_CODES.has(error.code)) { + return { + kind: 'session', + sessionId, + live: false, + refusal: { code: error.code, message: error.message } + } + } + return undefined + } +} diff --git a/src/cli/specs/core.ts b/src/cli/specs/core.ts index 98301b36e53..71bffaf3733 100644 --- a/src/cli/specs/core.ts +++ b/src/cli/specs/core.ts @@ -19,6 +19,9 @@ export const CORE_COMMAND_SPECS: CommandSpec[] = [ summary: 'Show app/runtime/graph readiness', usage: 'orca status [--json]', allowedFlags: [...GLOBAL_FLAGS], + notes: [ + "caller is this agent's orchestration address as Orca resolved it from its environment: session: for a chat session, the terminal handle for a terminal agent, null outside an Orca agent." + ], examples: ['orca status', 'orca status --json'] }, { diff --git a/src/cli/specs/orchestration.ts b/src/cli/specs/orchestration.ts index 8c4418f38ba..4143fc7716f 100644 --- a/src/cli/specs/orchestration.ts +++ b/src/cli/specs/orchestration.ts @@ -17,7 +17,7 @@ export const ORCHESTRATION_COMMAND_SPECS: CommandSpec[] = [ }, { path: ['orchestration', 'run-use'], - summary: 'Bind this coordinator terminal to an existing Run', + summary: 'Bind this coordinator to an existing Run', usage: 'orca orchestration run-use --id [--from ] [--takeover-legacy] [--retry-request ] [--json]', allowedFlags: [...GLOBAL_FLAGS, 'id', 'from', 'takeover-legacy', 'retry-request'], @@ -28,7 +28,7 @@ export const ORCHESTRATION_COMMAND_SPECS: CommandSpec[] = [ }, { path: ['orchestration', 'run-current'], - summary: 'Show the Run bound to this coordinator terminal', + summary: 'Show the Run bound to this coordinator', usage: 'orca orchestration run-current [--from ] [--json]', allowedFlags: [...GLOBAL_FLAGS, 'from'], identityFlagRoles: { from: 'caller' } @@ -87,7 +87,7 @@ export const ORCHESTRATION_COMMAND_SPECS: CommandSpec[] = [ }, { path: ['orchestration', 'check'], - summary: 'Check messages for a terminal', + summary: "Check this agent's messages", usage: 'orca orchestration check [--terminal ] [--run ] [--ack ] [--unread | --peek | --all] [--types ] [--format] [--wait] [--timeout-ms ] [--retry-request ] [--json]\n' + " default: return the bound Run's oldest unacknowledged FIFO batch.\n" + @@ -115,6 +115,8 @@ export const ORCHESTRATION_COMMAND_SPECS: CommandSpec[] = [ ], identityFlagRoles: { terminal: 'caller' }, notes: [ + 'The caller is this agent: session: in a chat session, else the Orca terminal it runs in. Omit --terminal in both; pass only your own handle elsewhere.', + 'A chat coordinator never uses --wait: Orca starts a turn in the chat when mail arrives, and that turn runs check.', 'On Windows PowerShell, quote comma-separated type filters, e.g. --types "worker_done,escalation".', '--types is the wake condition for --wait; a returned Delivery is always the whole FIFO batch, so it is never filtered by type. Without --wait it has no effect on consuming checks. Only --peek and --all filter their rows.', '--format renders the returned rows as local text only; it never writes to another terminal.', diff --git a/src/main/runtime/rpc/methods/orchestration.ts b/src/main/runtime/rpc/methods/orchestration.ts index ab80b91e830..ce98a055326 100644 --- a/src/main/runtime/rpc/methods/orchestration.ts +++ b/src/main/runtime/rpc/methods/orchestration.ts @@ -9,6 +9,7 @@ import { ORCHESTRATION_DISPATCH_METHODS } from './orchestration/runs/dispatch-me import { ORCHESTRATION_ASK_METHODS } from './orchestration/messaging/ask-methods' import { ORCHESTRATION_GATE_METHODS } from './orchestration/gates/gates' import { ORCHESTRATION_RESET_METHODS } from './orchestration/runs/reset-methods' +import { ORCHESTRATION_CALLER_METHODS } from './orchestration/caller-show' export const ORCHESTRATION_METHODS = [ ...ORCHESTRATION_RUN_METHODS, @@ -21,5 +22,6 @@ export const ORCHESTRATION_METHODS = [ ...ORCHESTRATION_DISPATCH_METHODS, ...ORCHESTRATION_ASK_METHODS, ...ORCHESTRATION_GATE_METHODS, - ...ORCHESTRATION_RESET_METHODS + ...ORCHESTRATION_RESET_METHODS, + ...ORCHESTRATION_CALLER_METHODS ] diff --git a/src/main/runtime/rpc/methods/orchestration/caller-show.ts b/src/main/runtime/rpc/methods/orchestration/caller-show.ts new file mode 100644 index 00000000000..b2d38538ec1 --- /dev/null +++ b/src/main/runtime/rpc/methods/orchestration/caller-show.ts @@ -0,0 +1,33 @@ +import type { OrchestrationCallerShowResult } from '../../../../../shared/orchestration-caller-status' +import { defineMethod } from '../../core' + +export const ORCHESTRATION_CALLER_METHODS = [ + defineMethod({ + name: 'orchestration.callerShow', + params: null, + // Why no params: the answer comes from the identity the caller's environment carries, which the + // dispatch entry already resolved (a session) or the envelope evidence names (a terminal). + // A session the entry cannot admit never reaches here: its refusal is the answer. + handler: ( + _params, + { runtime, orchestrationCaller, orchestrationCompatibilityEvidence } + ): OrchestrationCallerShowResult => { + if (orchestrationCaller) { + return { + caller: { + kind: 'session', + address: orchestrationCaller.actor, + sessionId: orchestrationCaller.sessionId, + live: true + } + } + } + const handle = orchestrationCompatibilityEvidence?.terminalHandle + if (!handle) { + return { caller: null } + } + const identity = runtime.resolveTerminalIdentity(handle) + return { caller: { kind: 'terminal', address: identity.handle, live: identity.live } } + } + }) +] diff --git a/src/main/runtime/rpc/methods/orchestration/runs/runs.test.ts b/src/main/runtime/rpc/methods/orchestration/runs/runs.test.ts index a037a1d473d..f729db58b93 100644 --- a/src/main/runtime/rpc/methods/orchestration/runs/runs.test.ts +++ b/src/main/runtime/rpc/methods/orchestration/runs/runs.test.ts @@ -26,7 +26,8 @@ describe('orchestration RPC methods', () => { it('registers all expected methods', () => { const registry = buildRegistry(ORCHESTRATION_METHODS) - expect(registry.size).toBe(41) + expect(registry.size).toBe(42) + expect(registry.has('orchestration.callerShow')).toBe(true) expect(registry.has('orchestration.workerRelease')).toBe(true) expect(registry.has('orchestration.workerRetain')).toBe(true) expect(registry.has('orchestration.workerList')).toBe(true) diff --git a/src/main/runtime/rpc/orchestration-caller-show.test.ts b/src/main/runtime/rpc/orchestration-caller-show.test.ts new file mode 100644 index 00000000000..f246b0b9249 --- /dev/null +++ b/src/main/runtime/rpc/orchestration-caller-show.test.ts @@ -0,0 +1,124 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { ORCHESTRATION_SESSION_CALLER_ERROR_CODES as CODES } from '../../../shared/orchestration-session-caller-codes' +import { + mintStructuredWorkerHandle, + mintStructuredWorkerPaneKey, + structuredWorkerIdentities, + structuredWorkerProcessIncarnation +} from '../structured-worker-identity' +import { + ACTOR_X, + createSessionCallerHarness, + orchestrationRequest, + PROVIDER_ID_X, + resultOf, + SESSION_X, + SESSION_Y, + sessionRecord, + type SessionCallerHarness +} from './orchestration-session-caller-test-fixture' + +const hostRef = vi.hoisted((): { current: unknown } => ({ current: null })) +vi.mock('../../native-chat/agent-session-wire/structured-agent-session-registry', () => ({ + getStructuredAgentSessionHost: () => hostRef.current +})) + +describe('orchestration.callerShow: the caller learns its own address from the host', () => { + let h: SessionCallerHarness + + beforeEach(() => { + h = createSessionCallerHarness(hostRef) + }) + + afterEach(() => { + h.close() + vi.restoreAllMocks() + }) + + function callerShow(options: Parameters[2]) { + return orchestrationRequest('orchestration.callerShow', {}, options) + } + + it('answers a chat with session:, even in terminal view where it also carries a pane', async () => { + const response = await h.dispatch( + callerShow({ + sessionId: SESSION_X, + evidence: { terminalHandle: 'term_tui', paneKey: 'tab_tui:1:2' } + }) + ) + + expect(resultOf(response)).toEqual({ + caller: { kind: 'session', address: ACTOR_X, sessionId: SESSION_X, live: true } + }) + }) + + it('answers a structured worker with its session address, not the handle it was minted', async () => { + const handle = mintStructuredWorkerHandle() + structuredWorkerIdentities.register({ + handle, + sessionId: SESSION_Y, + agent: 'claude', + paneKey: mintStructuredWorkerPaneKey(SESSION_Y), + processIncarnation: structuredWorkerProcessIncarnation(SESSION_Y), + worktreeId: 'wt_1', + hostScope: { kind: 'local', hostId: 'local' } + }) + + const response = await h.dispatch( + callerShow({ sessionId: SESSION_Y, evidence: { terminalHandle: handle } }) + ) + + expect(resultOf(response)).toEqual({ + caller: { kind: 'session', address: `session:${SESSION_Y}`, sessionId: SESSION_Y, live: true } + }) + }) + + it('refuses a session that is not running, with the same code every orchestration verb gets', async () => { + h.records.set(SESSION_X, sessionRecord(SESSION_X, { lease: { claimStatus: 'released' } })) + + const response = await h.dispatch(callerShow({ sessionId: SESSION_X })) + + expect(response).toMatchObject({ + ok: false, + error: { code: CODES.notLive, message: expect.stringContaining(SESSION_X) } + }) + }) + + it("names the Orca id when handed the provider's id", async () => { + const response = await h.dispatch(callerShow({ sessionId: PROVIDER_ID_X })) + + expect(response).toMatchObject({ + ok: false, + error: { code: CODES.providerId, data: { orcaSessionId: SESSION_X } } + }) + }) + + it('refuses a session claim from a paired client, naming the host boundary', async () => { + const response = await h.dispatchStreaming(callerShow({ sessionId: SESSION_X }), 'paired-1') + + expect(response).toMatchObject({ ok: false, error: { code: CODES.hostBoundary } }) + }) + + it('answers a terminal agent with the handle its environment carries, and whether it is live', async () => { + const probe = vi + .spyOn(h.runtime, 'resolveTerminalIdentity') + .mockImplementation((handle) => ({ handle, live: handle === 'term_live' })) + + const live = await h.dispatch(callerShow({ evidence: { terminalHandle: 'term_live' } })) + const stale = await h.dispatch(callerShow({ evidence: { terminalHandle: 'term_stale' } })) + + expect(resultOf(live)).toEqual({ + caller: { kind: 'terminal', address: 'term_live', live: true } + }) + expect(resultOf(stale)).toEqual({ + caller: { kind: 'terminal', address: 'term_stale', live: false } + }) + expect(probe).toHaveBeenCalledTimes(2) + }) + + it('answers null for a caller whose environment carries no identity', async () => { + const response = await h.dispatch(callerShow({})) + + expect(resultOf(response)).toEqual({ caller: null }) + }) +}) diff --git a/src/main/runtime/rpc/orchestration-session-caller.test.ts b/src/main/runtime/rpc/orchestration-session-caller.test.ts index c23bd9087bc..310c8bf30a9 100644 --- a/src/main/runtime/rpc/orchestration-session-caller.test.ts +++ b/src/main/runtime/rpc/orchestration-session-caller.test.ts @@ -92,8 +92,8 @@ describe('orchestration session callers at the dispatch entry', () => { .map((method) => method.name) .sort() - // The population: 41 registered methods, 21 of which carry a party-naming field. - expect(registry.size).toBe(41) + // The population: 42 registered methods, 21 of which carry a party-naming field. + expect(registry.size).toBe(42) expect(partyNaming).toHaveLength(21) expect(partyNaming).toEqual( [ diff --git a/src/shared/orchestration-caller-status.ts b/src/shared/orchestration-caller-status.ts new file mode 100644 index 00000000000..38d28bcdb89 --- /dev/null +++ b/src/shared/orchestration-caller-status.ts @@ -0,0 +1,36 @@ +/** + * The calling agent's own orchestration address, as the host resolved it from the identity injected + * into the caller's environment: its Orca session id, else its terminal handle. Never from a flag. + * `orca status --json` reports it as `caller`, so any agent can learn the address others reach it by. + */ +export type OrchestrationCallerAddress = + | { + kind: 'session' + /** `session:`: one spelling for every session, a structured worker included. */ + address: string + sessionId: string + /** The host resolves a session only while its lease is live; otherwise it refuses. */ + live: true + } + | { + kind: 'terminal' + address: string + /** False for a handle this process kept across a remint or a window reload. */ + live: boolean + } + +/** The host refused the session this process names, so it cannot act as it right now. */ +export type OrchestrationCallerRefusal = { + kind: 'session' + sessionId: string + live: false + refusal: { code: string; message: string } +} + +/** + * `null`: this process carries no orchestration identity. Absent from a status result: nothing was + * resolved, because the runtime was unreachable or the host predates `orchestration.callerShow`. + */ +export type CliStatusCaller = OrchestrationCallerAddress | OrchestrationCallerRefusal | null + +export type OrchestrationCallerShowResult = { caller: OrchestrationCallerAddress | null } diff --git a/src/shared/rpc-contract/rpc-params-catalog.generated.ts b/src/shared/rpc-contract/rpc-params-catalog.generated.ts index 2cd61678c28..c07c68471e9 100644 --- a/src/shared/rpc-contract/rpc-params-catalog.generated.ts +++ b/src/shared/rpc-contract/rpc-params-catalog.generated.ts @@ -979,6 +979,7 @@ export const RPC_PARAMS_BY_METHOD = { 'notifications.unregisterPush': null, 'notifications.unsubscribe': NotificationUnsubscribeParams, 'orchestration.ask': AskParams, + 'orchestration.callerShow': null, 'orchestration.check': CheckParams, 'orchestration.dispatch': DispatchParams, 'orchestration.dispatchShow': DispatchShowParams, diff --git a/src/shared/runtime-session-contracts.ts b/src/shared/runtime-session-contracts.ts index 393c95fec87..e70ad711468 100644 --- a/src/shared/runtime-session-contracts.ts +++ b/src/shared/runtime-session-contracts.ts @@ -14,6 +14,7 @@ import type { RuntimeMobileSessionSnapshotTab, RuntimeMobileSessionTerminalClientTab } from './runtime-mobile-session-tab-contracts' +import type { CliStatusCaller } from './orchestration-caller-status' export type * from './runtime-mobile-session-tab-contracts' @@ -127,6 +128,8 @@ export type CliStatusResult = { graph: { state: RuntimeGraphStatus | 'not_running' | 'starting' } + /** This process's orchestration address, resolved by the host; see `CliStatusCaller`. */ + caller?: CliStatusCaller } export type RuntimeSyncedTab = { From 91acc1e062cd73e71e82c21a09a4b025c2141278 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 01:57:14 -0700 Subject: [PATCH 02/18] docs(orchestration): tell agents their address and give chat coordinators a non-waiting loop The orchestration guide now states that a chat session's address is session: (never the provider's id), that orca status --json reports it, and that no caller flag should name another agent. A consuming check no longer tells every caller to name itself with --terminal. A chat coordinator starts its wave, ends the turn, and on each turn Orca starts for new mail runs a non-waiting check and ack; it never blocks in check --wait. The guide also names ORCA_CLI_COMMAND as the executable in chat sessions. --- skill-guides/orchestration.md | 51 +++++++++++++++++-- .../references/messaging-and-gates.md | 12 +++-- src/cli/bundled-skill-guides.ts | 6 +-- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/skill-guides/orchestration.md b/skill-guides/orchestration.md index a7d63ff922c..7ea842f017b 100644 --- a/skill-guides/orchestration.md +++ b/skill-guides/orchestration.md @@ -65,9 +65,31 @@ non-Orca subagent tool when Orca orchestration provenance was requested. - Use the executable you used to run `skills get` for the entire run. In the examples below, replace `ORCA` with it; do not create a shell variable or run `ORCA` literally. If it fails, report that exact error instead of switching. + When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for + its chat sessions, where bare `orca` in a login shell can reach another Orca. - A successful `orchestration send` proves durable enqueue; its wake or nudge is best-effort attention only and does not prove the recipient read or accepted it. +## Your address + +Every agent Orca runs has one orchestration address, and other agents reach it +there: + +- A chat session is `session:`, with the Orca session id. Never use the + provider's session id: it changes on `/clear` and names no live agent. +- A terminal agent is its terminal handle. + +`ORCA status --json` reports yours as `caller.address`, resolved by Orca from +the identity in your environment. A `caller` with `live: false` and a `refusal` +says why you cannot act as that session right now; `null` means this shell has +no orchestration identity. Send to another session with +`ORCA orchestration send --to session:`; a user may copy a chat's address +with its Copy Orchestration Address menu action and give it to you. + +Your commands act as you without a caller flag. Never pass another agent's +address as `--from` or `--terminal`: in a chat session the CLI refuses it, and in +a terminal it acts as that agent and consumes its mail. + ## Worker obligations The injected preamble is authoritative. A dispatched worker must: @@ -78,8 +100,8 @@ The injected preamble is authoritative. A dispatched worker must: 2. Send heartbeats only at the cadence in the preamble. A heartbeat proves liveness, not completion. 3. Read coordinator follow-ups at each natural checkpoint — before starting a - new file, after a test run — and once more immediately before `worker_done`: - `ORCA orchestration check --terminal --json`. + new file, after a test run — and once more immediately before `worker_done`, + with the preamble's own `check` command. 4. Send `worker_done` exactly once, from the dispatched terminal, with a three-sentence executive summary, both lifecycle IDs, and explicit `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose. @@ -112,8 +134,10 @@ dependencies or a retry of a known Task. Use dependencies only for real ordering and prefer parallel waves over chains deeper than three or four steps; nested workers obey the depth limit, and a new Run does not reset the caller's depth. -A consuming `check` names its caller with `--terminal `, never `--from`; -omit it inside the coordinator's own Orca terminal. It returns the bound Run's +A consuming `check` reads its caller from your environment, like every other +verb: omit `--terminal` in a chat session and inside your own Orca terminal. +Elsewhere pass `--terminal` with your own handle, never `--from` and never +another agent's handle. It returns the bound Run's oldest FIFO Delivery and replays that batch until acknowledged. Process every message: reply to questions, validate each `worker_done` against the expected active Dispatch, and decide each settled terminal's next owner before the ack: @@ -142,6 +166,25 @@ sent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose including when `worker-show` reports `agentWait` null. Absence never authorizes stop, abandon, retry, or release; keep waiting or inspect. +### Chat coordinators: end the turn instead of waiting + +When `ORCA status --json` reports `caller.kind` `session`, you coordinate from a +chat. Never block in `check --wait`: your shell tool has its own timeout, and +Orca wakes you instead. When messages reach your Run, Orca starts a new turn in +this chat once you are idle, saying `You have orchestration message(s)`. + +1. Bind one Run and start the full independent wave, as above. +2. End your turn. +3. On each such turn run `ORCA orchestration check --json`, without `--wait`. + Process every message as above, then `ORCA orchestration check --ack + --json`, which also returns the next batch. Repeat until it + returns no Delivery. +4. End your turn again. When every expected Dispatch has settled, report. + +A turn with no new Delivery is a checkpoint, not a failure. The empty-wait +enumeration above applies when a turn arrives and a Dispatch you expected has +still not settled. + `worker-start` is the normal path, composing placement, terminal readiness, prompt injection, and supervised resource ownership. `dispatch --inject` leaves an operator-created process unsupervised and is only for an expressiveness gap. diff --git a/skill-guides/orchestration/references/messaging-and-gates.md b/skill-guides/orchestration/references/messaging-and-gates.md index 573ca90e5e7..bce8e585829 100644 --- a/skill-guides/orchestration/references/messaging-and-gates.md +++ b/skill-guides/orchestration/references/messaging-and-gates.md @@ -10,9 +10,11 @@ accepted steering. ## Coordinator delivery loop `check` names its caller with `--terminal ` and is the only verb that -rejects `--from`. Omit `--terminal` inside an Orca terminal, where Orca resolves -the caller; pass it explicitly from anywhere else, including a dispatched -worker reading coordinator follow-ups. +rejects `--from`. Omit `--terminal` in a chat session, whose caller is always +`session:`, and inside an Orca terminal, where Orca resolves the caller. +Pass your own handle explicitly from anywhere else, including a dispatched +worker reading coordinator follow-ups. A chat coordinator never waits: it +checks without `--wait` on each turn Orca starts for new mail. A consuming coordinator `check` returns the bound Run's oldest FIFO Delivery, up to 50 messages, and replays that exact batch until acknowledged. Process @@ -36,7 +38,9 @@ ORCA orchestration send --to dispatch: --subject "Follow-up" --body Do not substitute a remote terminal handle. Omit `--from` for ordinary coordinator calls; a dispatched worker instead copies the exact `--from` and -capability arguments in its preamble. `check` is the exception: it identifies +capability arguments in its preamble. Any live chat session on this host is +reachable at `session:`, its Orca session id; `ORCA status --json` reports +your own as `caller.address`. `check` is the exception: it identifies its caller with `--terminal`, never `--from`. Group addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`, diff --git a/src/cli/bundled-skill-guides.ts b/src/cli/bundled-skill-guides.ts index 0985a2239ab..ce8dbee5854 100644 --- a/src/cli/bundled-skill-guides.ts +++ b/src/cli/bundled-skill-guides.ts @@ -66,10 +66,10 @@ const ORCA_PER_WORKSPACE_ENV_SSH_HOST_REFERENCE_MARKDOWN = "# SSH connection mod const ORCA_PER_WORKSPACE_ENV_WINDOWS_SCRIPTS_REFERENCE_MARKDOWN = "# Windows local-side scripts\n\nLoad this when the user's desktop is Windows and you are scaffolding the local-side scripts. A bare\n`.sh` will not execute there. Either require WSL or Git Bash and point `orca.yaml` at a launcher such\nas `bash ./scripts/orca-vm/.sh` through a `.cmd` file, or scaffold PowerShell equivalents.\n\nThe remote-side commands you run inside the Linux environment stay bash regardless of the desktop OS.\n\n```powershell\n#requires -Version 5\n$ErrorActionPreference = 'Stop'\n# resolve env→state→fallback; run the provider CLI / ssh the same way;\n# capture provider output; build the result object for the chosen mode and write ONE line of JSON to stdout.\n# Orca-server mode: @{ schemaVersion=1; pairingCode=$pairingCode; projectRoot=$projectRoot; userData=@{...} }\n# SSH mode: @{ schemaVersion=1; connection=@{ type=\"ssh\"; projectRoot=$projectRoot;\n# target=@{ label=$label; host=$host; port=$port; username=$user } } }\n($result | ConvertTo-Json -Compress -Depth 6)\n# progress/errors → Write-Error / the error stream, never stdout.\n```\n\nThe doctor's executable-bit check is a POSIX concept and is skipped on Windows, so a script that is\nunusable on the user's machine for a different reason still has to be caught by the `--provision`\nself-test.\n" // oxfmt-ignore -const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`:\n `ORCA orchestration check --terminal --json`.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` names its caller with `--terminal `, never `--from`;\nomit it inside the coordinator's own Orca terminal. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" +const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run `ORCA orchestration check --json`, without `--wait`.\n Process every message as above, then `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until it\n returns no Delivery.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" // oxfmt-ignore -const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`:\n `ORCA orchestration check --terminal --json`.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` names its caller with `--terminal `, never `--from`;\nomit it inside the coordinator's own Orca terminal. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` inside an Orca terminal, where Orca resolves\nthe caller; pass it explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" +const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run `ORCA orchestration check --json`, without `--wait`.\n Process every message as above, then `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until it\n returns no Delivery.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id; `ORCA status --json` reports\nyour own as `caller.address`. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" // oxfmt-ignore const ORCHESTRATION_COORDINATOR_LOOP_REFERENCE_MARKDOWN = "# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n" @@ -81,7 +81,7 @@ const ORCHESTRATION_LEGACY_CONTRACT_MIGRATION_REFERENCE_MARKDOWN = "# Legacy con const ORCHESTRATION_LOW_LEVEL_TOPOLOGY_REFERENCE_MARKDOWN = "# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n" // oxfmt-ignore -const ORCHESTRATION_MESSAGING_AND_GATES_REFERENCE_MARKDOWN = "# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` inside an Orca terminal, where Orca resolves\nthe caller; pass it explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n" +const ORCHESTRATION_MESSAGING_AND_GATES_REFERENCE_MARKDOWN = "# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id; `ORCA status --json` reports\nyour own as `caller.address`. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n" // oxfmt-ignore const ORCHESTRATION_PLACEMENT_AND_REMOTE_REFERENCE_MARKDOWN = "# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n" From 38445fbd5eeadc72214263a0724d835a2a3bc942 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 01:57:15 -0700 Subject: [PATCH 03/18] feat(native-chat): add Copy Orchestration Address to a structured chat's context menu Copies session:, the Orca-minted address other agents message the chat by. The existing Copy Session ID still copies the provider's id and is left as is; the new action is labelled so the two cannot be confused. Strings are added to every locale catalog. --- .../NativeChatCopyAddressMenuItem.tsx | 39 +++++++++++ .../NativeChatStructuredSession.tsx | 11 ++- .../use-native-chat-context-menu.test.tsx | 70 ++++++++++++++++++- .../use-native-chat-context-menu.tsx | 14 +++- ...se-structured-native-chat-pane-commands.ts | 5 +- src/renderer/src/i18n/locales/en.json | 5 ++ src/renderer/src/i18n/locales/es.json | 7 +- src/renderer/src/i18n/locales/fr.json | 5 ++ src/renderer/src/i18n/locales/ja.json | 5 ++ src/renderer/src/i18n/locales/ko.json | 5 ++ src/renderer/src/i18n/locales/zh.json | 5 ++ 11 files changed, 166 insertions(+), 5 deletions(-) create mode 100644 src/renderer/src/components/native-chat/NativeChatCopyAddressMenuItem.tsx diff --git a/src/renderer/src/components/native-chat/NativeChatCopyAddressMenuItem.tsx b/src/renderer/src/components/native-chat/NativeChatCopyAddressMenuItem.tsx new file mode 100644 index 00000000000..ffbb2b0c86e --- /dev/null +++ b/src/renderer/src/components/native-chat/NativeChatCopyAddressMenuItem.tsx @@ -0,0 +1,39 @@ +import { Copy } from 'lucide-react' +import { toast } from 'sonner' +import { DropdownMenuItem } from '@/components/ui/dropdown-menu' +import { translate } from '@/i18n/i18n' + +/** + * Copies the session's orchestration address (`session:`), the Orca-minted id other agents + * message it by. Distinct from "Copy Session ID", which copies the provider's id and changes on + * `/clear`. + */ +export function NativeChatCopyAddressMenuItem({ address }: { address: string }): React.JSX.Element { + const copyAddress = async (): Promise => { + try { + await window.api.ui.writeClipboardText(address) + toast.success( + translate( + 'components.native-chat.contextMenu.orchestrationAddressCopied', + 'Orchestration address copied' + ) + ) + } catch { + toast.error( + translate( + 'components.native-chat.contextMenu.orchestrationAddressCopyFailed', + 'Unable to copy orchestration address' + ) + ) + } + } + return ( + void copyAddress()}> + + {translate( + 'components.native-chat.contextMenu.copyOrchestrationAddress', + 'Copy Orchestration Address' + )} + + ) +} diff --git a/src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx b/src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx index f967e57ea68..7f85fa0a318 100644 --- a/src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx +++ b/src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx @@ -2,6 +2,10 @@ import { useMemo, useRef, useState } from 'react' import { encodeAgentSessionQuestionAnswers } from '../../../../shared/agent-session-question-answer' import { dispatchStructuredAgentSessionComposerCommand } from '../../../../shared/structured-agent-session-composer' import { structuredAgentSessionPaneKey } from '../../../../shared/structured-agent-session-projection' +import { + formatOrchestrationActor, + sessionOrchestrationActor +} from '../../../../shared/orchestration-actor' import type { NativeChatLiveSession } from './use-native-chat-live-session' import { NativeChatApprovalCard } from './NativeChatApprovalCard' import { NativeChatComposer, type NativeChatComposerHandle } from './NativeChatComposer' @@ -60,13 +64,18 @@ export function NativeChatStructuredSession( ) const rootRef = useRef(null) const composerRef = useRef(null) + const orchestrationAddress = useMemo(() => { + const actor = sessionOrchestrationActor(props.sessionId) + return actor ? formatOrchestrationActor(actor) : undefined + }, [props.sessionId]) const paneCommands = useStructuredNativeChatPaneCommands({ tabId: props.tabId, groupId: props.groupId, isVisible: props.isVisible, rootRef, composerRef, - terminalPaneActions: props.contextMenuActions + terminalPaneActions: props.contextMenuActions, + orchestrationAddress }) const session = useMemo( () => ({ diff --git a/src/renderer/src/components/native-chat/use-native-chat-context-menu.test.tsx b/src/renderer/src/components/native-chat/use-native-chat-context-menu.test.tsx index 14841e6c56d..26ec5550c21 100644 --- a/src/renderer/src/components/native-chat/use-native-chat-context-menu.test.tsx +++ b/src/renderer/src/components/native-chat/use-native-chat-context-menu.test.tsx @@ -53,6 +53,9 @@ vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback })) +const toasts = vi.hoisted(() => ({ success: vi.fn(), error: vi.fn() })) +vi.mock('sonner', () => ({ toast: toasts })) + vi.mock('@/components/tab-bar/TabWorkspaceLayoutMenuSection', () => ({ TabWorkspaceLayoutMenuSection: () => 'Move Tab to Split' })) @@ -73,11 +76,15 @@ function childrenText(children: ReactNode): string { function Harness({ onSwitchToTerminal, structured = false, - enabled = true + enabled = true, + orchestrationAddress, + canCopyAgentSessionId = false }: { onSwitchToTerminal?: () => void structured?: boolean enabled?: boolean + orchestrationAddress?: string + canCopyAgentSessionId?: boolean }) { const rootRef = createRef() const { menu } = useNativeChatContextMenu({ @@ -86,8 +93,10 @@ function Harness({ onSwitchToTerminal, showTerminalPaneActions: !structured, workspaceLayout: structured ? { unifiedTabId: 'chat-tab', groupId: 'group-1' } : undefined, + orchestrationAddress, actions: { ...emptyNativeChatContextMenuActions, + canCopyAgentSessionId, onPaste: vi.fn() } satisfies NativeChatContextMenuActions }) @@ -155,4 +164,63 @@ describe('useNativeChatContextMenu', () => { document.dispatchEvent(new Event('selectionchange')) expect(getSelection).not.toHaveBeenCalled() }) + + describe('Copy Orchestration Address', () => { + const address = 'session:4a1f6c2e-8b3d-4e7a-9c15-0d2b6e8f1a37' + const writeClipboardText = vi.fn() + + beforeEach(() => { + writeClipboardText.mockReset().mockResolvedValue(undefined) + toasts.success.mockReset() + toasts.error.mockReset() + Object.assign(window, { api: { ui: { writeClipboardText } } }) + }) + + function labels(): string[] { + return items.list.map((candidate) => childrenText(candidate.children)) + } + + function addressItem(): ItemProps | undefined { + return items.list.find( + (candidate) => childrenText(candidate.children) === 'Copy Orchestration Address' + ) + } + + it.each([ + ['a chat tab', true], + ['a chat in a terminal pane', false] + ])('copies session: in %s', async (_where, structured) => { + renderToStaticMarkup() + + addressItem()?.onSelect?.() + + await vi.waitFor(() => expect(toasts.success).toHaveBeenCalledOnce()) + expect(writeClipboardText).toHaveBeenCalledWith(address) + }) + + it('keeps the provider-id action beside it, under its own label', () => { + renderToStaticMarkup() + + expect(labels()).toEqual( + expect.arrayContaining(['Copy Orchestration Address', 'Copy Session ID']) + ) + }) + + it('is absent for a chat with no orchestration address', () => { + renderToStaticMarkup() + renderToStaticMarkup() + + expect(labels()).not.toContain('Copy Orchestration Address') + }) + + it('reports a failed copy instead of claiming success', async () => { + writeClipboardText.mockRejectedValue(new Error('denied')) + renderToStaticMarkup() + + addressItem()?.onSelect?.() + + await vi.waitFor(() => expect(toasts.error).toHaveBeenCalledOnce()) + expect(toasts.success).not.toHaveBeenCalled() + }) + }) }) diff --git a/src/renderer/src/components/native-chat/use-native-chat-context-menu.tsx b/src/renderer/src/components/native-chat/use-native-chat-context-menu.tsx index 48d896d4aea..058a8ad010d 100644 --- a/src/renderer/src/components/native-chat/use-native-chat-context-menu.tsx +++ b/src/renderer/src/components/native-chat/use-native-chat-context-menu.tsx @@ -31,6 +31,7 @@ import { import { translate } from '@/i18n/i18n' import { isMacPlatform, nativeChatToggleShortcutLabel } from './native-chat-shortcut' import { TabWorkspaceLayoutMenuSection } from '@/components/tab-bar/TabWorkspaceLayoutMenuSection' +import { NativeChatCopyAddressMenuItem } from './NativeChatCopyAddressMenuItem' import type { TabSplitDirection } from '@/store/slices/tabs' type NativeChatContextMenuState = { @@ -52,6 +53,8 @@ type UseNativeChatContextMenuArgs = { groupId: string shortcutLabels?: Partial> } + /** A structured session's `session:`; terminal-backed chats are addressed by their handle. */ + orchestrationAddress?: string } export type NativeChatContextMenuActions = { @@ -103,7 +106,8 @@ export function useNativeChatContextMenu({ actions, showTerminalPaneActions = true, splitShortcutLabels, - workspaceLayout + workspaceLayout, + orchestrationAddress }: UseNativeChatContextMenuArgs): { onContextMenuCapture: MouseEventHandler onSelectionCapture: () => void @@ -284,6 +288,9 @@ export function useNativeChatContextMenu({ 'Set Title…' )} + {orchestrationAddress ? ( + + ) : null} {actions.canCopyAgentSessionId ? ( @@ -320,6 +327,11 @@ export function useNativeChatContextMenu({ ) : null} + ) : orchestrationAddress ? ( + <> + + + ) : null} diff --git a/src/renderer/src/components/native-chat/use-structured-native-chat-pane-commands.ts b/src/renderer/src/components/native-chat/use-structured-native-chat-pane-commands.ts index d479c6ac03a..0695f564861 100644 --- a/src/renderer/src/components/native-chat/use-structured-native-chat-pane-commands.ts +++ b/src/renderer/src/components/native-chat/use-structured-native-chat-pane-commands.ts @@ -18,7 +18,8 @@ export function useStructuredNativeChatPaneCommands({ isVisible, rootRef, composerRef, - terminalPaneActions + terminalPaneActions, + orchestrationAddress }: { tabId: string groupId?: string @@ -26,6 +27,7 @@ export function useStructuredNativeChatPaneCommands({ rootRef: RefObject composerRef: RefObject terminalPaneActions?: Omit + orchestrationAddress?: string }) { const keybindings = useAppStore((state) => state.keybindings) const pasteClipboardIntoComposer = useNativeChatPasteBridge({ rootRef, composerRef }) @@ -37,6 +39,7 @@ export function useStructuredNativeChatPaneCommands({ onPaste: pasteClipboardIntoComposer }, enabled: isVisible, + orchestrationAddress, showTerminalPaneActions: terminalPaneActions !== undefined, splitShortcutLabels: { right: formatShortcutLabel('terminal.splitRight', keybindings), diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index fbced091ce2..f177b27924a 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -17749,6 +17749,11 @@ "label": "Context {{used}} of {{window}} tokens, {{percent}}% used", "title": "Context", "estimated": "Estimated from the last response." + }, + "contextMenu": { + "orchestrationAddressCopied": "Orchestration address copied", + "orchestrationAddressCopyFailed": "Unable to copy orchestration address", + "copyOrchestrationAddress": "Copy Orchestration Address" } }, "tab": { diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 9a80be5b3da..cc9a6415f25 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -14834,7 +14834,12 @@ "allow": "Permitir", "deny": "Denegar" }, - "launchPromptNotDelivered": "No entregado — revisa la terminal" + "launchPromptNotDelivered": "No entregado — revisa la terminal", + "contextMenu": { + "orchestrationAddressCopied": "Dirección de orquestación copiada", + "orchestrationAddressCopyFailed": "No se pudo copiar la dirección de orquestación", + "copyOrchestrationAddress": "Copiar dirección de orquestación" + } }, "tab": { "bar": { diff --git a/src/renderer/src/i18n/locales/fr.json b/src/renderer/src/i18n/locales/fr.json index 6e3e7193afa..e24876f8f1a 100644 --- a/src/renderer/src/i18n/locales/fr.json +++ b/src/renderer/src/i18n/locales/fr.json @@ -17672,6 +17672,11 @@ "notFound": "Fichier introuvable : {{value0}}", "unverifiable": "Impossible de vérifier {{value0}} : {{value1}}", "unresolved": "Impossible de résoudre {{value0}} dans cet espace de travail" + }, + "contextMenu": { + "orchestrationAddressCopied": "Adresse d'orchestration copiée", + "orchestrationAddressCopyFailed": "Impossible de copier l'adresse d'orchestration", + "copyOrchestrationAddress": "Copier l'adresse d'orchestration" } }, "tab": { diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index 43c9c42072c..68a39e58ab3 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -17608,6 +17608,11 @@ "notFound": "ファイルが見つかりません: {{value0}}", "unverifiable": "{{value0}} をチェックできませんでした: {{value1}}", "unresolved": "このワークスペースで {{value0}} を解決できませんでした" + }, + "contextMenu": { + "orchestrationAddressCopied": "オーケストレーションアドレスをコピーしました", + "orchestrationAddressCopyFailed": "オーケストレーションアドレスのコピーに失敗しました", + "copyOrchestrationAddress": "オーケストレーションアドレスをコピー" } }, "tab": { diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index 7a22d44064c..1905aedff8e 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -17608,6 +17608,11 @@ "notFound": "파일을 찾을 수 없습니다: {{value0}}", "unverifiable": "{{value0}}을(를) 확인할 수 없습니다: {{value1}}", "unresolved": "이 워크스페이스에서 {{value0}}을(를) 해결할 수 없습니다." + }, + "contextMenu": { + "orchestrationAddressCopied": "오케스트레이션 주소를 복사했습니다", + "orchestrationAddressCopyFailed": "오케스트레이션 주소를 복사하지 못했습니다", + "copyOrchestrationAddress": "오케스트레이션 주소 복사" } }, "tab": { diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index 46205df0bcc..a94d75fd080 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -17573,6 +17573,11 @@ "notFound": "未找到文件:{{value0}}", "unverifiable": "无法检查 {{value0}}:{{value1}}", "unresolved": "无法解析此工作区中的 {{value0}}" + }, + "contextMenu": { + "orchestrationAddressCopied": "已复制编排地址", + "orchestrationAddressCopyFailed": "复制编排地址失败", + "copyOrchestrationAddress": "复制编排地址" } }, "tab": { From b704c5239a37ec282a4e94ac9cb96d55c967a580 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 02:00:07 -0700 Subject: [PATCH 04/18] feat(orchestration): tell every dispatched worker its own orchestration address The worker preamble names the coordinator's address rather than a terminal handle, and states the worker's own address. A structured worker is told it is session:, that its coordinator reaches it there or at its dispatch mailbox, and that mail arriving while it is idle starts a new turn. Its commands invoke the CLI through ORCA_CLI_COMMAND in its own shell's form, the same rendering the pointer turn uses, because a bare orca in a login shell can reach a different Orca. --- .../__snapshots__/preamble.test.ts.snap | 3 +- .../runtime/orchestration/preamble.test.ts | 51 +++++++++ src/main/runtime/orchestration/preamble.ts | 33 +++++- .../orchestration-worker-mode-opacity.test.ts | 30 ++++- .../deliver-worker-dispatch-preamble.test.ts | 107 ++++++++++++++++++ .../deliver-worker-dispatch-preamble.ts | 13 +++ 6 files changed, 229 insertions(+), 8 deletions(-) create mode 100644 src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.test.ts diff --git a/src/main/runtime/orchestration/__snapshots__/preamble.test.ts.snap b/src/main/runtime/orchestration/__snapshots__/preamble.test.ts.snap index dabbaf462ec..5313f6a5978 100644 --- a/src/main/runtime/orchestration/__snapshots__/preamble.test.ts.snap +++ b/src/main/runtime/orchestration/__snapshots__/preamble.test.ts.snap @@ -2,8 +2,9 @@ exports[`buildDispatchPreamble > renders a stable snapshot of the full preamble 1`] = ` "You are working inside Orca, a multi-agent IDE. You are a dispatched worker. -Your coordinator's terminal handle is: term_COORD +Your coordinator's address is: term_COORD Your task ID is: task_SNAP +Your orchestration address is: term_WORKER The coordinator cannot see this terminal, so reach it with the \`orca orchestration\` commands below; a question or result left only in this terminal never gets to it. diff --git a/src/main/runtime/orchestration/preamble.test.ts b/src/main/runtime/orchestration/preamble.test.ts index 03d9e4fc912..0734370f744 100644 --- a/src/main/runtime/orchestration/preamble.test.ts +++ b/src/main/runtime/orchestration/preamble.test.ts @@ -403,3 +403,54 @@ describe('sub-dispatch section', () => { expect(preamble.indexOf('=== SUB-DISPATCH ===')).toBeLessThan(preamble.indexOf('=== TASK ===')) }) }) + +describe('the worker is told its own orchestration address', () => { + const sessionId = '4a1f6c2e-8b3d-4e7a-9c15-0d2b6e8f1a37' + const posixSession = { sessionId, cliInvocation: '"$ORCA_CLI_COMMAND"' } as const + + it('names a terminal worker by its handle', () => { + const preamble = buildDispatchPreamble(baseParams()) + + expect(preamble).toContain('Your orchestration address is: term_worker\n') + expect(preamble).not.toContain('session:') + }) + + it('names a structured worker session: and says how its coordinator reaches it', () => { + const preamble = buildDispatchPreamble( + baseParams({ workerHandle: 'structworker_1', structuredSession: posixSession }) + ) + + expect(preamble).toContain(`Your orchestration address is: session:${sessionId}\n`) + expect(preamble).toContain('Your coordinator reaches you there or at dispatch:ctx_def456.') + expect(preamble).toContain("Your coordinator's address is: term_coord\n") + }) + + it.each([ + ['a POSIX shell', '"$ORCA_CLI_COMMAND"'], + ['PowerShell', '& $env:ORCA_CLI_COMMAND'] + ] as const)( + "runs a structured worker's commands through ORCA_CLI_COMMAND in %s, even in dev", + (_shell, cliInvocation) => { + const preamble = buildDispatchPreamble( + baseParams({ + workerHandle: 'structworker_1', + structuredSession: { sessionId, cliInvocation }, + devMode: true, + cliCommand: 'orca' + }) + ) + const commands = cliFence(preamble) + .split('\n') + .map((line) => line.trim()) + .filter((line) => line.length > 0 && !line.startsWith('#')) + + expect(commands.length).toBeGreaterThan(0) + for (const command of commands) { + expect(command.startsWith(`${cliInvocation} orchestration `)).toBe(true) + } + expect(preamble).not.toContain('orca-dev') + expect(preamble).toContain(`\`${cliInvocation}\` runs this Orca's CLI`) + expect(afterWorkerDoneSection(preamble)).toContain(`${cliInvocation} orchestration check`) + } + ) +}) diff --git a/src/main/runtime/orchestration/preamble.ts b/src/main/runtime/orchestration/preamble.ts index 208868ce45b..a606649f33c 100644 --- a/src/main/runtime/orchestration/preamble.ts +++ b/src/main/runtime/orchestration/preamble.ts @@ -1,4 +1,4 @@ -import type { OrchestrationCliCommand } from './cli-command' +import type { OrchestrationCliCommand, StructuredSessionCliInvocation } from './cli-command' import type { RuntimeAgentPromptWriteOptions } from '../runtime-terminal-contracts' import { ORCA_DISPATCH_PROMPT_LEAD_LINE } from '../../../shared/orca-dispatch-status-prompt' @@ -12,8 +12,14 @@ export type PreambleParams = { dispatchId: string dispatchCapability?: string taskSpec: string + /** The coordinator's orchestration address: a terminal handle, or `session:` for a chat. */ coordinatorHandle: string workerHandle: string + /** + * Set when the worker is a structured session. Its address is then `session:`, and it runs + * the CLI through `ORCA_CLI_COMMAND`, which names this app's CLI by absolute path. + */ + structuredSession?: { sessionId: string; cliInvocation: StructuredSessionCliInvocation } devMode?: boolean // Why: packaged WSL panes install the scoped launcher as `orca-ide`; // other execution hosts keep their existing bare `orca` bridge. @@ -52,7 +58,11 @@ export function buildDispatchPreamble(params: PreambleParams): string { // Why: in dev mode, agents must use orca-dev to connect to the dev runtime's // socket. Without this, agents inside the dev Electron app would call the // production CLI and talk to the wrong Orca instance (Section 6.4). - const cli = params.devMode ? 'orca-dev' : (params.cliCommand ?? 'orca') + const cli = params.structuredSession + ? params.structuredSession.cliInvocation + : params.devMode + ? 'orca-dev' + : (params.cliCommand ?? 'orca') const postDoneInstructions = buildPostWorkerDoneInstructions({ cli, workerKind: params.workerKind ?? 'prompt-returning-agent' @@ -66,9 +76,9 @@ export function buildDispatchPreamble(params: PreambleParams): string { // Why plain-reason wording: Claude Code tells the model pasted text may carry instructions // the user did not write, and shouted rules read as prompt injection (STA-8200). const header = `You are working inside Orca, a multi-agent IDE. You are a dispatched worker. -Your coordinator's terminal handle is: ${params.coordinatorHandle} +Your coordinator's address is: ${params.coordinatorHandle} Your task ID is: ${params.taskId} - +${buildWorkerAddressSection(params)} The coordinator cannot see this terminal, so reach it with the \`${cli} orchestration\` commands below; a question or result left only in this terminal never gets to it. Don't post to Slack, GitHub, or other channels during the run; report through these commands. @@ -160,6 +170,21 @@ export function dispatchPreambleSendOptions(requestId: string): DispatchPreamble } } +// Why: a structured worker is a chat, reached at `session:` and woken by Orca rather than a PTY. +function buildWorkerAddressSection(params: PreambleParams): string { + const session = params.structuredSession + if (!session) { + return `Your orchestration address is: ${params.workerHandle} +` + } + return `Your orchestration address is: session:${session.sessionId} +Your coordinator reaches you there or at dispatch:${params.dispatchId}. Mail that arrives while +you are idle starts a new turn in this chat; mid-task, read it with the check command below. +Run every command below exactly as written: \`${session.cliInvocation}\` runs this Orca's CLI +from ORCA_CLI_COMMAND, and a bare \`orca\` in a login shell can reach a different Orca. +` +} + function buildPostWorkerDoneInstructions({ cli, workerKind diff --git a/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts b/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts index aa8c7c58574..cb79ba36ccb 100644 --- a/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts +++ b/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts @@ -34,7 +34,10 @@ vi.mock('./orchestration/worker/worker-topology', async (importOriginal) => ({ ...(await importOriginal>()), createStructuredWorkerSessionForWorktree: async (args: { effects: unknown[] }) => { args.effects.push({ kind: 'terminal', role: 'agent', action: 'created' }) - return { identity: { handle: STRUCTURED_HANDLE, sessionId: 'sess_worker' }, host: {} } + return { + identity: { handle: STRUCTURED_HANDLE, sessionId: 'sess_worker', agent: 'claude' }, + host: {} + } }, createExistingWorktreeWorkerTerminal: async () => ({ handle: TERMINAL_HANDLE }) })) @@ -90,6 +93,17 @@ function installStructuredCoordinator(handle: string, sessionId: string): string } /** Strips the ids that legitimately differ per dispatch, leaving what the agent is taught. */ +/** + * The two facts that legitimately differ by mode, and nothing else: the worker's own address (its + * handle, or `session:` with how mail reaches a chat) and how its shell invokes the CLI. + */ +function normalizeWorkerIdentity(preamble: string, cli: string): string { + return preamble + .replace(/^Your orchestration address is: [^\n]*\n(?:[^\n]+\n)*/m, '\n') + .split(`${cli} orchestration`) + .join(' orchestration') +} + function normalizePreamble(preamble: string, handle: string, dispatchId: string): string { return preamble .split(handle) @@ -203,9 +217,19 @@ describe('a worker cannot tell which mode it is running in', () => { expect(terminal.mode.mode).toBe('terminal') const structuredPreamble = structuredPreambles[0] as string const terminalPreamble = vi.mocked(runtime.sendTerminalAgentPrompt).mock.calls[0]?.[1] as string - expect(normalizePreamble(structuredPreamble, STRUCTURED_HANDLE, structured.dispatchId)).toBe( - normalizePreamble(terminalPreamble, TERMINAL_HANDLE, terminal.dispatchId) + expect( + normalizeWorkerIdentity( + normalizePreamble(structuredPreamble, STRUCTURED_HANDLE, structured.dispatchId), + '"$ORCA_CLI_COMMAND"' + ) + ).toBe( + normalizeWorkerIdentity( + normalizePreamble(terminalPreamble, TERMINAL_HANDLE, terminal.dispatchId), + 'orca' + ) ) + expect(structuredPreamble).toContain('Your orchestration address is: session:sess_worker\n') + expect(terminalPreamble).toContain(`Your orchestration address is: ${TERMINAL_HANDLE}\n`) // The section the structured lane used to withhold, asserted by name so the equality above // cannot pass by both preambles losing it. expect(structuredPreamble).toContain('=== SUB-DISPATCH ===') diff --git a/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.test.ts b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.test.ts new file mode 100644 index 00000000000..f8d4c33da6e --- /dev/null +++ b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.test.ts @@ -0,0 +1,107 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import type { OrcaRuntimeService } from '../../../../orca-runtime' +import { deliverWorkerDispatchPreamble } from './deliver-worker-dispatch-preamble' + +const sent = vi.hoisted((): { preambles: string[] } => ({ preambles: [] })) +vi.mock('../../orchestration-structured-worker-session', () => ({ + sendStructuredWorkerPreamble: async (args: { preamble: string }) => { + sent.preambles.push(args.preamble) + } +})) + +const SESSION = '4a1f6c2e-8b3d-4e7a-9c15-0d2b6e8f1a37' + +function runtime(prompts: string[]): OrcaRuntimeService { + const fake: Pick< + OrcaRuntimeService, + 'getNestedWorkerMaxDepth' | 'getTerminalOrchestrationCliCommand' | 'sendTerminalAgentPrompt' + > = { + getNestedWorkerMaxDepth: () => 0, + getTerminalOrchestrationCliCommand: () => 'orca', + sendTerminalAgentPrompt: async (handle, text) => { + prompts.push(text) + return { handle, accepted: true, bytesWritten: text.length } + } + } + // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: deliverWorkerDispatchPreamble reads only the three members the fake implements. + return fake as OrcaRuntimeService +} + +type StructuredSession = Parameters[0]['structuredSession'] + +function structuredSession(agent: 'claude' | 'codex' = 'claude'): StructuredSession { + const session = { host: {}, identity: { sessionId: SESSION, agent } } + // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: delivery reads only identity.sessionId/agent, and the mocked send ignores host. + return session as unknown as StructuredSession +} + +const args = { + dispatchId: 'ctx_1', + dispatchDepth: 1, + taskId: 'task_1', + taskSpec: 'do it', + coordinatorHandle: 'session:7e3b9d15-2c4a-4f86-a0b1-5c9e2d7f3b64', + dispatchCapability: 'cap', + devMode: false, + requestId: 'req_1' +} + +describe('deliverWorkerDispatchPreamble tells each worker its own address', () => { + beforeEach(() => { + sent.preambles = [] + }) + + it('names a structured worker by the session it was started as', async () => { + const prompts: string[] = [] + await deliverWorkerDispatchPreamble({ + ...args, + runtime: runtime(prompts), + terminalHandle: 'structworker_1', + structuredSession: structuredSession() + }) + + expect(prompts).toEqual([]) + expect(sent.preambles).toHaveLength(1) + expect(sent.preambles[0]).toContain(`Your orchestration address is: session:${SESSION}\n`) + expect(sent.preambles[0]).toContain( + '"$ORCA_CLI_COMMAND" orchestration send --from structworker_1' + ) + }) + + it("renders the CLI in the worker's own shell: PowerShell for Codex on Windows", async () => { + const platform = Object.getOwnPropertyDescriptor(process, 'platform') + Object.defineProperty(process, 'platform', { value: 'win32' }) + try { + for (const agent of ['codex', 'claude'] as const) { + await deliverWorkerDispatchPreamble({ + ...args, + runtime: runtime([]), + terminalHandle: 'structworker_1', + structuredSession: structuredSession(agent) + }) + } + } finally { + if (platform) { + Object.defineProperty(process, 'platform', platform) + } + } + + expect(sent.preambles[0]).toContain('& $env:ORCA_CLI_COMMAND orchestration send') + expect(sent.preambles[1]).toContain('"$ORCA_CLI_COMMAND" orchestration send') + }) + + it('names a terminal worker by its handle and keeps its bare CLI', async () => { + const prompts: string[] = [] + await deliverWorkerDispatchPreamble({ + ...args, + runtime: runtime(prompts), + terminalHandle: 'term_worker', + structuredSession: null + }) + + expect(sent.preambles).toEqual([]) + expect(prompts[0]).toContain('Your orchestration address is: term_worker\n') + expect(prompts[0]).toContain('orca orchestration send --from term_worker') + expect(prompts[0]).not.toContain('ORCA_CLI_COMMAND') + }) +}) diff --git a/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts index ecb3270874e..415773f00c7 100644 --- a/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts +++ b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts @@ -4,6 +4,7 @@ import { buildDispatchPreamble, dispatchPreambleSendOptions } from '../../../../orchestration/preamble' +import { structuredSessionCliInvocation } from '../../../../orchestration/cli-command' import { sendStructuredWorkerPreamble } from '../../orchestration-structured-worker-session' import type { createStructuredWorkerSessionForWorktree } from './worker-topology' @@ -40,6 +41,18 @@ export async function deliverWorkerDispatchPreamble(args: { taskSpec: args.taskSpec, coordinatorHandle: args.coordinatorHandle, workerHandle: terminalHandle, + ...(structuredSession + ? { + structuredSession: { + sessionId: structuredSession.identity.sessionId, + cliInvocation: structuredSessionCliInvocation({ + platform: process.platform, + // Registered with its agent at start; null only for an entry rehydrated later. + provider: structuredSession.identity.agent ?? 'claude' + }) + } + } + : {}), dispatchCapability: args.dispatchCapability, devMode: args.devMode, cliCommand: runtime.getTerminalOrchestrationCliCommand(terminalHandle) From 7847a26ba91751104a2a903be769d87016eaa9bf Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 02:20:29 -0700 Subject: [PATCH 05/18] docs(orchestration): give the ORCA_CLI_COMMAND form for POSIX shells and PowerShell A chat session's shell reads the variable as "$ORCA_CLI_COMMAND" in a POSIX shell (Git Bash included) and as & $env:ORCA_CLI_COMMAND in PowerShell, the same two forms the pointer turn and worker preamble render. The chat coordinator loop now runs the check its pointer turn names. --- skill-guides/orchestration.md | 10 ++++++---- src/cli/bundled-skill-guides.ts | 4 ++-- src/cli/root-help-text-secondary.ts | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/skill-guides/orchestration.md b/skill-guides/orchestration.md index 7ea842f017b..01dded0a4d0 100644 --- a/skill-guides/orchestration.md +++ b/skill-guides/orchestration.md @@ -67,6 +67,8 @@ non-Orca subagent tool when Orca orchestration provenance was requested. `ORCA` literally. If it fails, report that exact error instead of switching. When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for its chat sessions, where bare `orca` in a login shell can reach another Orca. + Invoke it as `"$ORCA_CLI_COMMAND"` in a POSIX shell (including Git Bash) and + as `& $env:ORCA_CLI_COMMAND` in PowerShell. - A successful `orchestration send` proves durable enqueue; its wake or nudge is best-effort attention only and does not prove the recipient read or accepted it. @@ -175,10 +177,10 @@ this chat once you are idle, saying `You have orchestration message(s)`. 1. Bind one Run and start the full independent wave, as above. 2. End your turn. -3. On each such turn run `ORCA orchestration check --json`, without `--wait`. - Process every message as above, then `ORCA orchestration check --ack - --json`, which also returns the next batch. Repeat until it - returns no Delivery. +3. On each such turn run the `check` it names, without `--wait`. Process every + message as above, then acknowledge with `ORCA orchestration check --ack + --json`, which also returns the next batch. Repeat until no + Delivery is returned. 4. End your turn again. When every expected Dispatch has settled, report. A turn with no new Delivery is a checkpoint, not a failure. The empty-wait diff --git a/src/cli/bundled-skill-guides.ts b/src/cli/bundled-skill-guides.ts index ce8dbee5854..e8142cd518e 100644 --- a/src/cli/bundled-skill-guides.ts +++ b/src/cli/bundled-skill-guides.ts @@ -66,10 +66,10 @@ const ORCA_PER_WORKSPACE_ENV_SSH_HOST_REFERENCE_MARKDOWN = "# SSH connection mod const ORCA_PER_WORKSPACE_ENV_WINDOWS_SCRIPTS_REFERENCE_MARKDOWN = "# Windows local-side scripts\n\nLoad this when the user's desktop is Windows and you are scaffolding the local-side scripts. A bare\n`.sh` will not execute there. Either require WSL or Git Bash and point `orca.yaml` at a launcher such\nas `bash ./scripts/orca-vm/.sh` through a `.cmd` file, or scaffold PowerShell equivalents.\n\nThe remote-side commands you run inside the Linux environment stay bash regardless of the desktop OS.\n\n```powershell\n#requires -Version 5\n$ErrorActionPreference = 'Stop'\n# resolve env→state→fallback; run the provider CLI / ssh the same way;\n# capture provider output; build the result object for the chosen mode and write ONE line of JSON to stdout.\n# Orca-server mode: @{ schemaVersion=1; pairingCode=$pairingCode; projectRoot=$projectRoot; userData=@{...} }\n# SSH mode: @{ schemaVersion=1; connection=@{ type=\"ssh\"; projectRoot=$projectRoot;\n# target=@{ label=$label; host=$host; port=$port; username=$user } } }\n($result | ConvertTo-Json -Compress -Depth 6)\n# progress/errors → Write-Error / the error stream, never stdout.\n```\n\nThe doctor's executable-bit check is a POSIX concept and is skipped on Windows, so a script that is\nunusable on the user's machine for a different reason still has to be caught by the `--provision`\nself-test.\n" // oxfmt-ignore -const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run `ORCA orchestration check --json`, without `--wait`.\n Process every message as above, then `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until it\n returns no Delivery.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" +const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n Invoke it as `\"$ORCA_CLI_COMMAND\"` in a POSIX shell (including Git Bash) and\n as `& $env:ORCA_CLI_COMMAND` in PowerShell.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as above, then acknowledge with `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until no\n Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" // oxfmt-ignore -const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run `ORCA orchestration check --json`, without `--wait`.\n Process every message as above, then `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until it\n returns no Delivery.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id; `ORCA status --json` reports\nyour own as `caller.address`. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" +const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n Invoke it as `\"$ORCA_CLI_COMMAND\"` in a POSIX shell (including Git Bash) and\n as `& $env:ORCA_CLI_COMMAND` in PowerShell.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as above, then acknowledge with `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until no\n Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id; `ORCA status --json` reports\nyour own as `caller.address`. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" // oxfmt-ignore const ORCHESTRATION_COORDINATOR_LOOP_REFERENCE_MARKDOWN = "# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n" diff --git a/src/cli/root-help-text-secondary.ts b/src/cli/root-help-text-secondary.ts index 8a1ff895b25..1ffa40eb1bd 100644 --- a/src/cli/root-help-text-secondary.ts +++ b/src/cli/root-help-text-secondary.ts @@ -114,7 +114,8 @@ export const ROOT_HELP_TEXT_SECONDARY = [ ' Use selectors for discovery and handles for repeated live terminal operations.', ' Inside an Orca agent, `orca status --json` reports its orchestration address as caller.address:', ' session: for a chat session, its terminal handle for a terminal agent.', - ' When ORCA_CLI_COMMAND is set, run that executable; bare `orca` in a login shell can reach another Orca.', + ' When ORCA_CLI_COMMAND is set, run that executable: "$ORCA_CLI_COMMAND" in a POSIX shell,', + ' & $env:ORCA_CLI_COMMAND in PowerShell. Bare `orca` in a login shell can reach another Orca.', '', 'Agent Sessions And Worktrees:', ' `worktree create --agent` creates a new checkout with an agent.', From 4981a470435e82a52371133b53202e08172861f8 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 02:52:45 -0700 Subject: [PATCH 06/18] docs(orchestration): say that /clear gives a chat a new address and Orca moves its Runs --- skill-guides/orchestration.md | 4 +++- src/cli/bundled-skill-guides.ts | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/skill-guides/orchestration.md b/skill-guides/orchestration.md index 01dded0a4d0..eafca12e363 100644 --- a/skill-guides/orchestration.md +++ b/skill-guides/orchestration.md @@ -86,7 +86,9 @@ the identity in your environment. A `caller` with `live: false` and a `refusal` says why you cannot act as that session right now; `null` means this shell has no orchestration identity. Send to another session with `ORCA orchestration send --to session:`; a user may copy a chat's address -with its Copy Orchestration Address menu action and give it to you. +with its Copy Orchestration Address menu action and give it to you. `/clear` +starts a new session, so a new address: Orca moves your Runs and unread mail to +it, and a send to the old address is refused with the new one named. Your commands act as you without a caller flag. Never pass another agent's address as `--from` or `--terminal`: in a chat session the CLI refuses it, and in diff --git a/src/cli/bundled-skill-guides.ts b/src/cli/bundled-skill-guides.ts index e8142cd518e..9e878676b61 100644 --- a/src/cli/bundled-skill-guides.ts +++ b/src/cli/bundled-skill-guides.ts @@ -66,10 +66,10 @@ const ORCA_PER_WORKSPACE_ENV_SSH_HOST_REFERENCE_MARKDOWN = "# SSH connection mod const ORCA_PER_WORKSPACE_ENV_WINDOWS_SCRIPTS_REFERENCE_MARKDOWN = "# Windows local-side scripts\n\nLoad this when the user's desktop is Windows and you are scaffolding the local-side scripts. A bare\n`.sh` will not execute there. Either require WSL or Git Bash and point `orca.yaml` at a launcher such\nas `bash ./scripts/orca-vm/.sh` through a `.cmd` file, or scaffold PowerShell equivalents.\n\nThe remote-side commands you run inside the Linux environment stay bash regardless of the desktop OS.\n\n```powershell\n#requires -Version 5\n$ErrorActionPreference = 'Stop'\n# resolve env→state→fallback; run the provider CLI / ssh the same way;\n# capture provider output; build the result object for the chosen mode and write ONE line of JSON to stdout.\n# Orca-server mode: @{ schemaVersion=1; pairingCode=$pairingCode; projectRoot=$projectRoot; userData=@{...} }\n# SSH mode: @{ schemaVersion=1; connection=@{ type=\"ssh\"; projectRoot=$projectRoot;\n# target=@{ label=$label; host=$host; port=$port; username=$user } } }\n($result | ConvertTo-Json -Compress -Depth 6)\n# progress/errors → Write-Error / the error stream, never stdout.\n```\n\nThe doctor's executable-bit check is a POSIX concept and is skipped on Windows, so a script that is\nunusable on the user's machine for a different reason still has to be caught by the `--provision`\nself-test.\n" // oxfmt-ignore -const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n Invoke it as `\"$ORCA_CLI_COMMAND\"` in a POSIX shell (including Git Bash) and\n as `& $env:ORCA_CLI_COMMAND` in PowerShell.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as above, then acknowledge with `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until no\n Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" +const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n Invoke it as `\"$ORCA_CLI_COMMAND\"` in a POSIX shell (including Git Bash) and\n as `& $env:ORCA_CLI_COMMAND` in PowerShell.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you. `/clear`\nstarts a new session, so a new address: Orca moves your Runs and unread mail to\nit, and a send to the old address is refused with the new one named.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as above, then acknowledge with `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until no\n Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" // oxfmt-ignore -const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n Invoke it as `\"$ORCA_CLI_COMMAND\"` in a POSIX shell (including Git Bash) and\n as `& $env:ORCA_CLI_COMMAND` in PowerShell.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as above, then acknowledge with `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until no\n Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id; `ORCA status --json` reports\nyour own as `caller.address`. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" +const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n Invoke it as `\"$ORCA_CLI_COMMAND\"` in a POSIX shell (including Git Bash) and\n as `& $env:ORCA_CLI_COMMAND` in PowerShell.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you. `/clear`\nstarts a new session, so a new address: Orca moves your Runs and unread mail to\nit, and a send to the old address is refused with the new one named.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as above, then acknowledge with `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until no\n Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id; `ORCA status --json` reports\nyour own as `caller.address`. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" // oxfmt-ignore const ORCHESTRATION_COORDINATOR_LOOP_REFERENCE_MARKDOWN = "# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n" From f300c60ce61ed02a4fc3489d0c8e1e34a1f63da7 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 03:26:11 -0700 Subject: [PATCH 07/18] fix(orchestration): keep CLI resolution in the shared skill stub and the orchestration kernel in budget The guide-contract tests own two rules this PR broke: only the shared skill stub may describe how to resolve the CLI, and the always-loaded orchestration kernel stays within 202 lines. The ORCA_CLI_COMMAND text moves to the stub's resolver block, which now covers chat sessions and login shells beside WSL and gives the POSIX and PowerShell forms; every skill projection and the bundle manifest are regenerated. The kernel keeps one line each for the caller's address, the environment-resolved check caller and the chat coordinator's non-waiting loop; the loop steps and the address details move to the coordinator-loop and messaging references. The two kernel pins now assert the new check contract and refuse the old --terminal shape. --- .../orchestration-skill-guidance.test.mjs | 11 ++- resources/skills/current-manifest.json | 96 +++++++++---------- resources/skills/snapshot-registry.json | 96 +++++++++---------- skill-guides/orchestration.md | 65 +++---------- .../references/coordinator-loop.md | 25 ++++- .../references/messaging-and-gates.md | 9 +- skill-stubs/_shared/cli-resolution.md | 4 +- skills/computer-use/SKILL.md | 4 +- skills/linear-tickets/SKILL.md | 4 +- skills/orca-cli/SKILL.md | 4 +- skills/orca-emulator-android/SKILL.md | 4 +- skills/orca-emulator/SKILL.md | 4 +- skills/orca-linear/SKILL.md | 4 +- skills/orca-per-workspace-env/SKILL.md | 4 +- skills/orchestration/SKILL.md | 4 +- src/cli/bundled-skill-guides.ts | 8 +- 16 files changed, 176 insertions(+), 170 deletions(-) diff --git a/config/scripts/orchestration-skill-guidance.test.mjs b/config/scripts/orchestration-skill-guidance.test.mjs index 2ed4288e223..bb2b6c30027 100644 --- a/config/scripts/orchestration-skill-guidance.test.mjs +++ b/config/scripts/orchestration-skill-guidance.test.mjs @@ -184,11 +184,16 @@ describe('orchestration kernel', () => { ) }) - it('names --terminal, never --from, as the check caller flag', () => { + it('resolves the check caller from the environment and never teaches naming another', () => { const kernel = squash(readKernel()) - expect(kernel).toContain('`check` names its caller with `--terminal `, never `--from`') + expect(kernel).toContain( + '`check` takes its caller from the environment in a chat or Orca terminal; elsewhere pass your own `--terminal `, never `--from`' + ) + expect(kernel).toContain('Never name another agent with `--from`/`--terminal`') expect(kernel).not.toContain('check --from') + // The #21097 shape: an instruction to name the caller by handle on every check. + expect(kernel).not.toContain('check --terminal ') }) it('makes a dispatched worker read coordinator follow-ups on a cadence', () => { @@ -196,7 +201,7 @@ describe('orchestration kernel', () => { expect(kernel).toContain('Read coordinator follow-ups at each natural checkpoint') expect(kernel).toContain('once more immediately before `worker_done`') - expect(kernel).toContain('`ORCA orchestration check --terminal --json`') + expect(kernel).toContain("with the preamble's own `check` command") }) it('requires full Delivery processing and settled-terminal accounting before ack', () => { diff --git a/resources/skills/current-manifest.json b/resources/skills/current-manifest.json index c0c492a2736..acfa1ed768d 100644 --- a/resources/skills/current-manifest.json +++ b/resources/skills/current-manifest.json @@ -5,17 +5,17 @@ "name": "computer-use", "sourcePath": "skills/computer-use", "releaseRevision": 9, - "packageDigest": "425634e3ebf27690cc613eaf17b6337b36769153ec6bca85dc4ebf65d4d6b8b4", - "gitTreeSha": "b59f27370a41225c22127e91da0c91cd2519f217", + "packageDigest": "a87375ac9e9250161fd73465c82364a865607aa0f5d90dee0d206293a5f1be53", + "gitTreeSha": "c1c110c2f328e9d97dc949f84fb6b325b73899de", "files": [ { "path": "SKILL.md", - "size": 2211, + "size": 2443, "executable": false, "classification": "text", - "exactSha256": "2839933fd35216845461466403e6061488005f6df57126d0cd0f769ea45753f3", - "textNormalizedSha256": "2839933fd35216845461466403e6061488005f6df57126d0cd0f769ea45753f3", - "identitySha256": "2839933fd35216845461466403e6061488005f6df57126d0cd0f769ea45753f3" + "exactSha256": "f5b644888461f1589fd20b03b38f6f3aafcd12d1102c346a63cfb76fd193b486", + "textNormalizedSha256": "f5b644888461f1589fd20b03b38f6f3aafcd12d1102c346a63cfb76fd193b486", + "identitySha256": "f5b644888461f1589fd20b03b38f6f3aafcd12d1102c346a63cfb76fd193b486" } ] }, @@ -23,17 +23,17 @@ "name": "linear-tickets", "sourcePath": "skills/linear-tickets", "releaseRevision": 11, - "packageDigest": "1eab442d048b79ab0b836adf57663ac384988dd79172ec5f14193eb05e037715", - "gitTreeSha": "30d9b40144d4a9a07ce12f0d1a9261fd9cf9649b", + "packageDigest": "02af6f3804d3184c16c80bacbd7e241cf4df7ba2c9b6c4c9974e84cfaef37ddc", + "gitTreeSha": "754c4849a3ca79574dcb37aab4ca1836811bf8e9", "files": [ { "path": "SKILL.md", - "size": 2231, + "size": 2463, "executable": false, "classification": "text", - "exactSha256": "e181f86073da65c492361469d504fe15e7ae61bc99990bc41bea47aa13455619", - "textNormalizedSha256": "e181f86073da65c492361469d504fe15e7ae61bc99990bc41bea47aa13455619", - "identitySha256": "e181f86073da65c492361469d504fe15e7ae61bc99990bc41bea47aa13455619" + "exactSha256": "cbf6afd89607bf8c5af9dd3dd20363e65108291d0d5a43e5b1d0fcaed9bbf9ab", + "textNormalizedSha256": "cbf6afd89607bf8c5af9dd3dd20363e65108291d0d5a43e5b1d0fcaed9bbf9ab", + "identitySha256": "cbf6afd89607bf8c5af9dd3dd20363e65108291d0d5a43e5b1d0fcaed9bbf9ab" } ] }, @@ -41,17 +41,17 @@ "name": "orca-cli", "sourcePath": "skills/orca-cli", "releaseRevision": 37, - "packageDigest": "0736bcbbb69ed18f9a36a58ad2eda47b6db55b30509953cf5ba5f0032058c535", - "gitTreeSha": "572f7952ac451a30a9c2451b472a639b125ee584", + "packageDigest": "bdc0bbb1899b27a05eeb8fea6e3f1b234eb2eaa7685dfb848adcf1740a7223e8", + "gitTreeSha": "a9b4f439f75db5de948128a4366a648c0e957a3c", "files": [ { "path": "SKILL.md", - "size": 2372, + "size": 2604, "executable": false, "classification": "text", - "exactSha256": "aa76f86505010096e8ea9edda1705a78aae7af45e54485f3fe0460664c1d9e4a", - "textNormalizedSha256": "aa76f86505010096e8ea9edda1705a78aae7af45e54485f3fe0460664c1d9e4a", - "identitySha256": "aa76f86505010096e8ea9edda1705a78aae7af45e54485f3fe0460664c1d9e4a" + "exactSha256": "6797ddc4688ece98ff395b798b26b6a6dfe43130f13fbe0c56c37929400d2ffe", + "textNormalizedSha256": "6797ddc4688ece98ff395b798b26b6a6dfe43130f13fbe0c56c37929400d2ffe", + "identitySha256": "6797ddc4688ece98ff395b798b26b6a6dfe43130f13fbe0c56c37929400d2ffe" } ] }, @@ -59,17 +59,17 @@ "name": "orca-emulator", "sourcePath": "skills/orca-emulator", "releaseRevision": 8, - "packageDigest": "1dc42e5addc613abd85eba639d4ac36d9c7b3bc6f7186f0a2d54d10dae3f06d3", - "gitTreeSha": "110f6ab59bd73428d7de28bd4761d1fc332efa20", + "packageDigest": "0be86ec897b1a9dbf144e823a4acf0d989ccce87bc251539626a2912e2bb7de9", + "gitTreeSha": "98ef2478491db03fcb04bcbb186e071ea44ead66", "files": [ { "path": "SKILL.md", - "size": 2337, + "size": 2569, "executable": false, "classification": "text", - "exactSha256": "3da7191179e46cb0e1a6a936f1eb54254f6e98ec38849e1c95f0e11073076b48", - "textNormalizedSha256": "3da7191179e46cb0e1a6a936f1eb54254f6e98ec38849e1c95f0e11073076b48", - "identitySha256": "3da7191179e46cb0e1a6a936f1eb54254f6e98ec38849e1c95f0e11073076b48" + "exactSha256": "9a42e901ee282eb11ca17e854d4ec8ce26dbc0f70175f5cba582c76de48546ac", + "textNormalizedSha256": "9a42e901ee282eb11ca17e854d4ec8ce26dbc0f70175f5cba582c76de48546ac", + "identitySha256": "9a42e901ee282eb11ca17e854d4ec8ce26dbc0f70175f5cba582c76de48546ac" } ] }, @@ -77,17 +77,17 @@ "name": "orca-emulator-android", "sourcePath": "skills/orca-emulator-android", "releaseRevision": 6, - "packageDigest": "c348091d953427fc9800a1d49d94054866348008766879b24ef742cb613dc3d9", - "gitTreeSha": "437ed5e35698ee6421386a5a08fe7f8c7cf1a2a7", + "packageDigest": "52fa8998e9b3d0f5498c8f536f08d87c7719df177dbb0568af4611eb6139cdd5", + "gitTreeSha": "a17259cd07ac05a15059bafeca6088befd4e7f41", "files": [ { "path": "SKILL.md", - "size": 2234, + "size": 2466, "executable": false, "classification": "text", - "exactSha256": "3ade4e6f8f2717ca899fd841e61f116963a406e9527015b803854c16d012e278", - "textNormalizedSha256": "3ade4e6f8f2717ca899fd841e61f116963a406e9527015b803854c16d012e278", - "identitySha256": "3ade4e6f8f2717ca899fd841e61f116963a406e9527015b803854c16d012e278" + "exactSha256": "21e679811789903da8c776e4239dc681b0db8641ee59158ae3aa30b936fff298", + "textNormalizedSha256": "21e679811789903da8c776e4239dc681b0db8641ee59158ae3aa30b936fff298", + "identitySha256": "21e679811789903da8c776e4239dc681b0db8641ee59158ae3aa30b936fff298" } ] }, @@ -95,17 +95,17 @@ "name": "orca-linear", "sourcePath": "skills/orca-linear", "releaseRevision": 9, - "packageDigest": "95f52429823e887317046f23b671d05408a947c296e5b2e44e9173dfc1d5aa4e", - "gitTreeSha": "8e747165847651926ca54804b012689ebcbd9432", + "packageDigest": "86e626833901186c2a15f0062b54fdebb7ac9124f91a087841adcee33f33a408", + "gitTreeSha": "e16fcb62227c392fdfa352982798089743edd870", "files": [ { "path": "SKILL.md", - "size": 2088, + "size": 2320, "executable": false, "classification": "text", - "exactSha256": "8da23ef96470906315cace8ff84f8056255ee37d1b2d5db84d8b7b3270a0ba0f", - "textNormalizedSha256": "8da23ef96470906315cace8ff84f8056255ee37d1b2d5db84d8b7b3270a0ba0f", - "identitySha256": "8da23ef96470906315cace8ff84f8056255ee37d1b2d5db84d8b7b3270a0ba0f" + "exactSha256": "ade35a188703c61d3f7ef7d536f89b42be7cc5e8cca14972c3f749fabeebb888", + "textNormalizedSha256": "ade35a188703c61d3f7ef7d536f89b42be7cc5e8cca14972c3f749fabeebb888", + "identitySha256": "ade35a188703c61d3f7ef7d536f89b42be7cc5e8cca14972c3f749fabeebb888" } ] }, @@ -113,17 +113,17 @@ "name": "orca-per-workspace-env", "sourcePath": "skills/orca-per-workspace-env", "releaseRevision": 6, - "packageDigest": "103f0671da111c9ad3def6c46da8d432e656878b840e6cc742219f4a3a4dbceb", - "gitTreeSha": "58dfb5dc3ad287a6a42625f9d15c7c0c3dfd02ec", + "packageDigest": "321c1c4e08c4d93999db82ecd4d7b9a5f82653bf92aedc25faae066cca66ef13", + "gitTreeSha": "685470ac47e6402a9a3bec39df0f61ef82b4ebfe", "files": [ { "path": "SKILL.md", - "size": 2257, + "size": 2489, "executable": false, "classification": "text", - "exactSha256": "c005d126a13d2913351472f07690f1c1a660d4f286e2a5f21864aee294f436ce", - "textNormalizedSha256": "c005d126a13d2913351472f07690f1c1a660d4f286e2a5f21864aee294f436ce", - "identitySha256": "c005d126a13d2913351472f07690f1c1a660d4f286e2a5f21864aee294f436ce" + "exactSha256": "9eee084101f5a41d697e95f91505539abca3b3c40203e04077771c6c134bff56", + "textNormalizedSha256": "9eee084101f5a41d697e95f91505539abca3b3c40203e04077771c6c134bff56", + "identitySha256": "9eee084101f5a41d697e95f91505539abca3b3c40203e04077771c6c134bff56" } ] }, @@ -131,17 +131,17 @@ "name": "orchestration", "sourcePath": "skills/orchestration", "releaseRevision": 29, - "packageDigest": "195f26431ecfb6df41b941b22958a2330b110bac7b7e97004e0b35fe586e41d9", - "gitTreeSha": "b0cd1d58b0c317cf7c3726fef7e6b1197c405246", + "packageDigest": "85027b6598f0a6a99ed1267288574fec4b312372d9ef24ff4ee0bf3b51265c28", + "gitTreeSha": "1f31942ad58c785d917954c1bb3245f2278dac0a", "files": [ { "path": "SKILL.md", - "size": 3671, + "size": 3903, "executable": false, "classification": "text", - "exactSha256": "cd1b364bf35781bad06bf75ab1766afa8d6cec69cb2060529691d89871a2098a", - "textNormalizedSha256": "cd1b364bf35781bad06bf75ab1766afa8d6cec69cb2060529691d89871a2098a", - "identitySha256": "cd1b364bf35781bad06bf75ab1766afa8d6cec69cb2060529691d89871a2098a" + "exactSha256": "2832ac8b590f64823ceb1fb6c06c82dbfa02175ed16b0b5b69788bedf5a61002", + "textNormalizedSha256": "2832ac8b590f64823ceb1fb6c06c82dbfa02175ed16b0b5b69788bedf5a61002", + "identitySha256": "2832ac8b590f64823ceb1fb6c06c82dbfa02175ed16b0b5b69788bedf5a61002" } ] } diff --git a/resources/skills/snapshot-registry.json b/resources/skills/snapshot-registry.json index 731d0a85c8e..80309e533f6 100644 --- a/resources/skills/snapshot-registry.json +++ b/resources/skills/snapshot-registry.json @@ -580,17 +580,17 @@ }, { "releaseRevision": 37, - "packageDigest": "0736bcbbb69ed18f9a36a58ad2eda47b6db55b30509953cf5ba5f0032058c535", - "gitTreeSha": "572f7952ac451a30a9c2451b472a639b125ee584", + "packageDigest": "bdc0bbb1899b27a05eeb8fea6e3f1b234eb2eaa7685dfb848adcf1740a7223e8", + "gitTreeSha": "a9b4f439f75db5de948128a4366a648c0e957a3c", "files": [ { "path": "SKILL.md", - "size": 2372, + "size": 2604, "executable": false, "classification": "text", - "exactSha256": "aa76f86505010096e8ea9edda1705a78aae7af45e54485f3fe0460664c1d9e4a", - "textNormalizedSha256": "aa76f86505010096e8ea9edda1705a78aae7af45e54485f3fe0460664c1d9e4a", - "identitySha256": "aa76f86505010096e8ea9edda1705a78aae7af45e54485f3fe0460664c1d9e4a" + "exactSha256": "6797ddc4688ece98ff395b798b26b6a6dfe43130f13fbe0c56c37929400d2ffe", + "textNormalizedSha256": "6797ddc4688ece98ff395b798b26b6a6dfe43130f13fbe0c56c37929400d2ffe", + "identitySha256": "6797ddc4688ece98ff395b798b26b6a6dfe43130f13fbe0c56c37929400d2ffe" } ] } @@ -1046,17 +1046,17 @@ }, { "releaseRevision": 29, - "packageDigest": "195f26431ecfb6df41b941b22958a2330b110bac7b7e97004e0b35fe586e41d9", - "gitTreeSha": "b0cd1d58b0c317cf7c3726fef7e6b1197c405246", + "packageDigest": "85027b6598f0a6a99ed1267288574fec4b312372d9ef24ff4ee0bf3b51265c28", + "gitTreeSha": "1f31942ad58c785d917954c1bb3245f2278dac0a", "files": [ { "path": "SKILL.md", - "size": 3671, + "size": 3903, "executable": false, "classification": "text", - "exactSha256": "cd1b364bf35781bad06bf75ab1766afa8d6cec69cb2060529691d89871a2098a", - "textNormalizedSha256": "cd1b364bf35781bad06bf75ab1766afa8d6cec69cb2060529691d89871a2098a", - "identitySha256": "cd1b364bf35781bad06bf75ab1766afa8d6cec69cb2060529691d89871a2098a" + "exactSha256": "2832ac8b590f64823ceb1fb6c06c82dbfa02175ed16b0b5b69788bedf5a61002", + "textNormalizedSha256": "2832ac8b590f64823ceb1fb6c06c82dbfa02175ed16b0b5b69788bedf5a61002", + "identitySha256": "2832ac8b590f64823ceb1fb6c06c82dbfa02175ed16b0b5b69788bedf5a61002" } ] } @@ -1210,17 +1210,17 @@ }, { "releaseRevision": 9, - "packageDigest": "425634e3ebf27690cc613eaf17b6337b36769153ec6bca85dc4ebf65d4d6b8b4", - "gitTreeSha": "b59f27370a41225c22127e91da0c91cd2519f217", + "packageDigest": "a87375ac9e9250161fd73465c82364a865607aa0f5d90dee0d206293a5f1be53", + "gitTreeSha": "c1c110c2f328e9d97dc949f84fb6b325b73899de", "files": [ { "path": "SKILL.md", - "size": 2211, + "size": 2443, "executable": false, "classification": "text", - "exactSha256": "2839933fd35216845461466403e6061488005f6df57126d0cd0f769ea45753f3", - "textNormalizedSha256": "2839933fd35216845461466403e6061488005f6df57126d0cd0f769ea45753f3", - "identitySha256": "2839933fd35216845461466403e6061488005f6df57126d0cd0f769ea45753f3" + "exactSha256": "f5b644888461f1589fd20b03b38f6f3aafcd12d1102c346a63cfb76fd193b486", + "textNormalizedSha256": "f5b644888461f1589fd20b03b38f6f3aafcd12d1102c346a63cfb76fd193b486", + "identitySha256": "f5b644888461f1589fd20b03b38f6f3aafcd12d1102c346a63cfb76fd193b486" } ] } @@ -1340,17 +1340,17 @@ }, { "releaseRevision": 8, - "packageDigest": "1dc42e5addc613abd85eba639d4ac36d9c7b3bc6f7186f0a2d54d10dae3f06d3", - "gitTreeSha": "110f6ab59bd73428d7de28bd4761d1fc332efa20", + "packageDigest": "0be86ec897b1a9dbf144e823a4acf0d989ccce87bc251539626a2912e2bb7de9", + "gitTreeSha": "98ef2478491db03fcb04bcbb186e071ea44ead66", "files": [ { "path": "SKILL.md", - "size": 2337, + "size": 2569, "executable": false, "classification": "text", - "exactSha256": "3da7191179e46cb0e1a6a936f1eb54254f6e98ec38849e1c95f0e11073076b48", - "textNormalizedSha256": "3da7191179e46cb0e1a6a936f1eb54254f6e98ec38849e1c95f0e11073076b48", - "identitySha256": "3da7191179e46cb0e1a6a936f1eb54254f6e98ec38849e1c95f0e11073076b48" + "exactSha256": "9a42e901ee282eb11ca17e854d4ec8ce26dbc0f70175f5cba582c76de48546ac", + "textNormalizedSha256": "9a42e901ee282eb11ca17e854d4ec8ce26dbc0f70175f5cba582c76de48546ac", + "identitySha256": "9a42e901ee282eb11ca17e854d4ec8ce26dbc0f70175f5cba582c76de48546ac" } ] } @@ -1518,17 +1518,17 @@ }, { "releaseRevision": 11, - "packageDigest": "1eab442d048b79ab0b836adf57663ac384988dd79172ec5f14193eb05e037715", - "gitTreeSha": "30d9b40144d4a9a07ce12f0d1a9261fd9cf9649b", + "packageDigest": "02af6f3804d3184c16c80bacbd7e241cf4df7ba2c9b6c4c9974e84cfaef37ddc", + "gitTreeSha": "754c4849a3ca79574dcb37aab4ca1836811bf8e9", "files": [ { "path": "SKILL.md", - "size": 2231, + "size": 2463, "executable": false, "classification": "text", - "exactSha256": "e181f86073da65c492361469d504fe15e7ae61bc99990bc41bea47aa13455619", - "textNormalizedSha256": "e181f86073da65c492361469d504fe15e7ae61bc99990bc41bea47aa13455619", - "identitySha256": "e181f86073da65c492361469d504fe15e7ae61bc99990bc41bea47aa13455619" + "exactSha256": "cbf6afd89607bf8c5af9dd3dd20363e65108291d0d5a43e5b1d0fcaed9bbf9ab", + "textNormalizedSha256": "cbf6afd89607bf8c5af9dd3dd20363e65108291d0d5a43e5b1d0fcaed9bbf9ab", + "identitySha256": "cbf6afd89607bf8c5af9dd3dd20363e65108291d0d5a43e5b1d0fcaed9bbf9ab" } ] } @@ -1664,17 +1664,17 @@ }, { "releaseRevision": 9, - "packageDigest": "95f52429823e887317046f23b671d05408a947c296e5b2e44e9173dfc1d5aa4e", - "gitTreeSha": "8e747165847651926ca54804b012689ebcbd9432", + "packageDigest": "86e626833901186c2a15f0062b54fdebb7ac9124f91a087841adcee33f33a408", + "gitTreeSha": "e16fcb62227c392fdfa352982798089743edd870", "files": [ { "path": "SKILL.md", - "size": 2088, + "size": 2320, "executable": false, "classification": "text", - "exactSha256": "8da23ef96470906315cace8ff84f8056255ee37d1b2d5db84d8b7b3270a0ba0f", - "textNormalizedSha256": "8da23ef96470906315cace8ff84f8056255ee37d1b2d5db84d8b7b3270a0ba0f", - "identitySha256": "8da23ef96470906315cace8ff84f8056255ee37d1b2d5db84d8b7b3270a0ba0f" + "exactSha256": "ade35a188703c61d3f7ef7d536f89b42be7cc5e8cca14972c3f749fabeebb888", + "textNormalizedSha256": "ade35a188703c61d3f7ef7d536f89b42be7cc5e8cca14972c3f749fabeebb888", + "identitySha256": "ade35a188703c61d3f7ef7d536f89b42be7cc5e8cca14972c3f749fabeebb888" } ] } @@ -1762,17 +1762,17 @@ }, { "releaseRevision": 6, - "packageDigest": "c348091d953427fc9800a1d49d94054866348008766879b24ef742cb613dc3d9", - "gitTreeSha": "437ed5e35698ee6421386a5a08fe7f8c7cf1a2a7", + "packageDigest": "52fa8998e9b3d0f5498c8f536f08d87c7719df177dbb0568af4611eb6139cdd5", + "gitTreeSha": "a17259cd07ac05a15059bafeca6088befd4e7f41", "files": [ { "path": "SKILL.md", - "size": 2234, + "size": 2466, "executable": false, "classification": "text", - "exactSha256": "3ade4e6f8f2717ca899fd841e61f116963a406e9527015b803854c16d012e278", - "textNormalizedSha256": "3ade4e6f8f2717ca899fd841e61f116963a406e9527015b803854c16d012e278", - "identitySha256": "3ade4e6f8f2717ca899fd841e61f116963a406e9527015b803854c16d012e278" + "exactSha256": "21e679811789903da8c776e4239dc681b0db8641ee59158ae3aa30b936fff298", + "textNormalizedSha256": "21e679811789903da8c776e4239dc681b0db8641ee59158ae3aa30b936fff298", + "identitySha256": "21e679811789903da8c776e4239dc681b0db8641ee59158ae3aa30b936fff298" } ] } @@ -1860,17 +1860,17 @@ }, { "releaseRevision": 6, - "packageDigest": "103f0671da111c9ad3def6c46da8d432e656878b840e6cc742219f4a3a4dbceb", - "gitTreeSha": "58dfb5dc3ad287a6a42625f9d15c7c0c3dfd02ec", + "packageDigest": "321c1c4e08c4d93999db82ecd4d7b9a5f82653bf92aedc25faae066cca66ef13", + "gitTreeSha": "685470ac47e6402a9a3bec39df0f61ef82b4ebfe", "files": [ { "path": "SKILL.md", - "size": 2257, + "size": 2489, "executable": false, "classification": "text", - "exactSha256": "c005d126a13d2913351472f07690f1c1a660d4f286e2a5f21864aee294f436ce", - "textNormalizedSha256": "c005d126a13d2913351472f07690f1c1a660d4f286e2a5f21864aee294f436ce", - "identitySha256": "c005d126a13d2913351472f07690f1c1a660d4f286e2a5f21864aee294f436ce" + "exactSha256": "9eee084101f5a41d697e95f91505539abca3b3c40203e04077771c6c134bff56", + "textNormalizedSha256": "9eee084101f5a41d697e95f91505539abca3b3c40203e04077771c6c134bff56", + "identitySha256": "9eee084101f5a41d697e95f91505539abca3b3c40203e04077771c6c134bff56" } ] } diff --git a/skill-guides/orchestration.md b/skill-guides/orchestration.md index eafca12e363..d92fb30205a 100644 --- a/skill-guides/orchestration.md +++ b/skill-guides/orchestration.md @@ -65,35 +65,11 @@ non-Orca subagent tool when Orca orchestration provenance was requested. - Use the executable you used to run `skills get` for the entire run. In the examples below, replace `ORCA` with it; do not create a shell variable or run `ORCA` literally. If it fails, report that exact error instead of switching. - When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for - its chat sessions, where bare `orca` in a login shell can reach another Orca. - Invoke it as `"$ORCA_CLI_COMMAND"` in a POSIX shell (including Git Bash) and - as `& $env:ORCA_CLI_COMMAND` in PowerShell. +- Your address is `caller.address` in `ORCA status --json`: `session:` in a + chat, your handle in a terminal. Never name another agent with `--from`/`--terminal`. - A successful `orchestration send` proves durable enqueue; its wake or nudge is best-effort attention only and does not prove the recipient read or accepted it. -## Your address - -Every agent Orca runs has one orchestration address, and other agents reach it -there: - -- A chat session is `session:`, with the Orca session id. Never use the - provider's session id: it changes on `/clear` and names no live agent. -- A terminal agent is its terminal handle. - -`ORCA status --json` reports yours as `caller.address`, resolved by Orca from -the identity in your environment. A `caller` with `live: false` and a `refusal` -says why you cannot act as that session right now; `null` means this shell has -no orchestration identity. Send to another session with -`ORCA orchestration send --to session:`; a user may copy a chat's address -with its Copy Orchestration Address menu action and give it to you. `/clear` -starts a new session, so a new address: Orca moves your Runs and unread mail to -it, and a send to the old address is refused with the new one named. - -Your commands act as you without a caller flag. Never pass another agent's -address as `--from` or `--terminal`: in a chat session the CLI refuses it, and in -a terminal it acts as that agent and consumes its mail. - ## Worker obligations The injected preamble is authoritative. A dispatched worker must: @@ -138,13 +114,12 @@ dependencies or a retry of a known Task. Use dependencies only for real ordering and prefer parallel waves over chains deeper than three or four steps; nested workers obey the depth limit, and a new Run does not reset the caller's depth. -A consuming `check` reads its caller from your environment, like every other -verb: omit `--terminal` in a chat session and inside your own Orca terminal. -Elsewhere pass `--terminal` with your own handle, never `--from` and never -another agent's handle. It returns the bound Run's -oldest FIFO Delivery and replays that batch until acknowledged. Process every -message: reply to questions, validate each `worker_done` against the expected -active Dispatch, and decide each settled terminal's next owner before the ack: +A consuming `check` takes its caller from the environment in a chat or Orca +terminal; elsewhere pass your own `--terminal `, never `--from`. It +returns the bound Run's oldest FIFO Delivery and replays that batch until +acknowledged. Process every message: reply to questions, validate each +`worker_done` against the expected active Dispatch, and decide each settled +terminal's next owner before the ack: ```text ORCA orchestration reply --id --body "" --json @@ -168,26 +143,8 @@ worker's own observation of process exit, or a transcript whose final agent turn sent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose `worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence, including when `worker-show` reports `agentWait` null. Absence never authorizes -stop, abandon, retry, or release; keep waiting or inspect. - -### Chat coordinators: end the turn instead of waiting - -When `ORCA status --json` reports `caller.kind` `session`, you coordinate from a -chat. Never block in `check --wait`: your shell tool has its own timeout, and -Orca wakes you instead. When messages reach your Run, Orca starts a new turn in -this chat once you are idle, saying `You have orchestration message(s)`. - -1. Bind one Run and start the full independent wave, as above. -2. End your turn. -3. On each such turn run the `check` it names, without `--wait`. Process every - message as above, then acknowledge with `ORCA orchestration check --ack - --json`, which also returns the next batch. Repeat until no - Delivery is returned. -4. End your turn again. When every expected Dispatch has settled, report. - -A turn with no new Delivery is a checkpoint, not a failure. The empty-wait -enumeration above applies when a turn arrives and a Dispatch you expected has -still not settled. +stop, abandon, retry, or release; keep waiting or inspect. A chat coordinator +ends its turn instead of `check --wait`; see `references/coordinator-loop.md`. `worker-start` is the normal path, composing placement, terminal readiness, prompt injection, and supervised resource ownership. `dispatch --inject` leaves @@ -232,7 +189,7 @@ older CLI rejects `--full`, keep this kernel's safety floor, use that command's | Action gate | Bundled reference | | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | -| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` | +| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` | | You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` | | New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` | | Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` | diff --git a/skill-guides/orchestration/references/coordinator-loop.md b/skill-guides/orchestration/references/coordinator-loop.md index aec13667645..96c0b421ae1 100644 --- a/skill-guides/orchestration/references/coordinator-loop.md +++ b/skill-guides/orchestration/references/coordinator-loop.md @@ -1,9 +1,30 @@ # Coordinator loop -Load this reference for expanded DAG waves, per-invocation launch preferences, -same-terminal reuse, or review ownership. The compact guide remains the source +Load this reference for coordinating from a chat session, expanded DAG waves, +per-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source of truth for the loop order and completion boundary. +## Coordinating from a chat session + +When `ORCA status --json` reports `caller.kind` `session`, you coordinate from a +chat. Never block in `check --wait`: your shell tool has its own timeout, and +Orca wakes you instead. When messages reach your Run, Orca starts a new turn in +this chat once you are idle, saying `You have orchestration message(s)` and +naming the `check` to run. + +1. Bind one Run and start the full independent wave. +2. End your turn. +3. On each such turn run the `check` it names, without `--wait`. Process every + message as the compact guide requires, then acknowledge with + `ORCA orchestration check --ack --json`, which also returns the + next batch. Repeat until no Delivery is returned. +4. End your turn again. When every expected Dispatch has settled, report. + +A turn with no new Delivery is a checkpoint, not a failure. The compact guide's +empty-wait enumeration applies when a turn arrives and a Dispatch you expected +has still not settled. `/clear` gives the chat a new session and address; Orca +moves your Runs and unread mail to it. + ## Ready waves Create independent Tasks before the first wait. Encode only real dependencies, diff --git a/skill-guides/orchestration/references/messaging-and-gates.md b/skill-guides/orchestration/references/messaging-and-gates.md index bce8e585829..bed3fc33f88 100644 --- a/skill-guides/orchestration/references/messaging-and-gates.md +++ b/skill-guides/orchestration/references/messaging-and-gates.md @@ -39,8 +39,13 @@ ORCA orchestration send --to dispatch: --subject "Follow-up" --body Do not substitute a remote terminal handle. Omit `--from` for ordinary coordinator calls; a dispatched worker instead copies the exact `--from` and capability arguments in its preamble. Any live chat session on this host is -reachable at `session:`, its Orca session id; `ORCA status --json` reports -your own as `caller.address`. `check` is the exception: it identifies +reachable at `session:`, its Orca session id, never the provider's id (it +changes on `/clear`). `ORCA status --json` reports your own as `caller.address`; +a `caller` with `live: false` carries the refusal that stops you acting as that +session, and `null` means the shell has no orchestration identity. A user may +copy a chat's address with its Copy Orchestration Address menu action. `/clear` +gives a chat a new address: Orca moves its Runs and unread mail there, and a +send to the old one is refused with the new one named. `check` is the exception: it identifies its caller with `--terminal`, never `--from`. Group addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`, diff --git a/skill-stubs/_shared/cli-resolution.md b/skill-stubs/_shared/cli-resolution.md index 8c898be5ad6..dc5d238004f 100644 --- a/skill-stubs/_shared/cli-resolution.md +++ b/skill-stubs/_shared/cli-resolution.md @@ -7,7 +7,9 @@ Choose the executable once and reuse it for every later command: - If the `ORCA_CLI_COMMAND` environment variable is set, use its value. Orca exports this - for managed WSL sessions. + for managed WSL sessions and for its chat sessions, whose login shells (Codex's among + them) can put a different `orca` first on PATH. Invoke it as `"$ORCA_CLI_COMMAND"` in a + POSIX shell, Git Bash included, and as `& $env:ORCA_CLI_COMMAND` in PowerShell. - Otherwise, in a dev checkout whose session exposes `ORCA_DEV_REPO_ROOT`, use `orca-dev`. - Otherwise, on Linux outside an Orca-managed terminal, use `orca-ide`. Never run bare `orca` there — outside Orca's terminals it normally resolves to the diff --git a/skills/computer-use/SKILL.md b/skills/computer-use/SKILL.md index 8c89c613921..8abf2be8728 100644 --- a/skills/computer-use/SKILL.md +++ b/skills/computer-use/SKILL.md @@ -18,7 +18,9 @@ This discovery stub loads the version-matched guide from the Orca executable use Choose the executable once and reuse it for every later command: - If the `ORCA_CLI_COMMAND` environment variable is set, use its value. Orca exports this - for managed WSL sessions. + for managed WSL sessions and for its chat sessions, whose login shells (Codex's among + them) can put a different `orca` first on PATH. Invoke it as `"$ORCA_CLI_COMMAND"` in a + POSIX shell, Git Bash included, and as `& $env:ORCA_CLI_COMMAND` in PowerShell. - Otherwise, in a dev checkout whose session exposes `ORCA_DEV_REPO_ROOT`, use `orca-dev`. - Otherwise, on Linux outside an Orca-managed terminal, use `orca-ide`. Never run bare `orca` there — outside Orca's terminals it normally resolves to the diff --git a/skills/linear-tickets/SKILL.md b/skills/linear-tickets/SKILL.md index 86c9eba8285..109f7387435 100644 --- a/skills/linear-tickets/SKILL.md +++ b/skills/linear-tickets/SKILL.md @@ -19,7 +19,9 @@ This discovery stub uses the legacy name `linear-tickets` for `orca-linear`; bot Choose the executable once and reuse it for every later command: - If the `ORCA_CLI_COMMAND` environment variable is set, use its value. Orca exports this - for managed WSL sessions. + for managed WSL sessions and for its chat sessions, whose login shells (Codex's among + them) can put a different `orca` first on PATH. Invoke it as `"$ORCA_CLI_COMMAND"` in a + POSIX shell, Git Bash included, and as `& $env:ORCA_CLI_COMMAND` in PowerShell. - Otherwise, in a dev checkout whose session exposes `ORCA_DEV_REPO_ROOT`, use `orca-dev`. - Otherwise, on Linux outside an Orca-managed terminal, use `orca-ide`. Never run bare `orca` there — outside Orca's terminals it normally resolves to the diff --git a/skills/orca-cli/SKILL.md b/skills/orca-cli/SKILL.md index fbea1b6566c..0f012670cdd 100644 --- a/skills/orca-cli/SKILL.md +++ b/skills/orca-cli/SKILL.md @@ -19,7 +19,9 @@ This discovery stub loads the version-matched guide from the Orca executable use Choose the executable once and reuse it for every later command: - If the `ORCA_CLI_COMMAND` environment variable is set, use its value. Orca exports this - for managed WSL sessions. + for managed WSL sessions and for its chat sessions, whose login shells (Codex's among + them) can put a different `orca` first on PATH. Invoke it as `"$ORCA_CLI_COMMAND"` in a + POSIX shell, Git Bash included, and as `& $env:ORCA_CLI_COMMAND` in PowerShell. - Otherwise, in a dev checkout whose session exposes `ORCA_DEV_REPO_ROOT`, use `orca-dev`. - Otherwise, on Linux outside an Orca-managed terminal, use `orca-ide`. Never run bare `orca` there — outside Orca's terminals it normally resolves to the diff --git a/skills/orca-emulator-android/SKILL.md b/skills/orca-emulator-android/SKILL.md index 3754741f4ad..d4edcae7a7d 100644 --- a/skills/orca-emulator-android/SKILL.md +++ b/skills/orca-emulator-android/SKILL.md @@ -19,7 +19,9 @@ This discovery stub loads the version-matched guide from the Orca executable use Choose the executable once and reuse it for every later command: - If the `ORCA_CLI_COMMAND` environment variable is set, use its value. Orca exports this - for managed WSL sessions. + for managed WSL sessions and for its chat sessions, whose login shells (Codex's among + them) can put a different `orca` first on PATH. Invoke it as `"$ORCA_CLI_COMMAND"` in a + POSIX shell, Git Bash included, and as `& $env:ORCA_CLI_COMMAND` in PowerShell. - Otherwise, in a dev checkout whose session exposes `ORCA_DEV_REPO_ROOT`, use `orca-dev`. - Otherwise, on Linux outside an Orca-managed terminal, use `orca-ide`. Never run bare `orca` there — outside Orca's terminals it normally resolves to the diff --git a/skills/orca-emulator/SKILL.md b/skills/orca-emulator/SKILL.md index 317182bfbae..b89a37538f3 100644 --- a/skills/orca-emulator/SKILL.md +++ b/skills/orca-emulator/SKILL.md @@ -22,7 +22,9 @@ handles device scoping, helper lifecycle, and worktree context. Choose the executable once and reuse it for every later command: - If the `ORCA_CLI_COMMAND` environment variable is set, use its value. Orca exports this - for managed WSL sessions. + for managed WSL sessions and for its chat sessions, whose login shells (Codex's among + them) can put a different `orca` first on PATH. Invoke it as `"$ORCA_CLI_COMMAND"` in a + POSIX shell, Git Bash included, and as `& $env:ORCA_CLI_COMMAND` in PowerShell. - Otherwise, in a dev checkout whose session exposes `ORCA_DEV_REPO_ROOT`, use `orca-dev`. - Otherwise, on Linux outside an Orca-managed terminal, use `orca-ide`. Never run bare `orca` there — outside Orca's terminals it normally resolves to the diff --git a/skills/orca-linear/SKILL.md b/skills/orca-linear/SKILL.md index f70f55ca41e..7fa31063432 100644 --- a/skills/orca-linear/SKILL.md +++ b/skills/orca-linear/SKILL.md @@ -17,7 +17,9 @@ This discovery stub loads the version-matched guide from the Orca executable use Choose the executable once and reuse it for every later command: - If the `ORCA_CLI_COMMAND` environment variable is set, use its value. Orca exports this - for managed WSL sessions. + for managed WSL sessions and for its chat sessions, whose login shells (Codex's among + them) can put a different `orca` first on PATH. Invoke it as `"$ORCA_CLI_COMMAND"` in a + POSIX shell, Git Bash included, and as `& $env:ORCA_CLI_COMMAND` in PowerShell. - Otherwise, in a dev checkout whose session exposes `ORCA_DEV_REPO_ROOT`, use `orca-dev`. - Otherwise, on Linux outside an Orca-managed terminal, use `orca-ide`. Never run bare `orca` there — outside Orca's terminals it normally resolves to the diff --git a/skills/orca-per-workspace-env/SKILL.md b/skills/orca-per-workspace-env/SKILL.md index ff37d027767..7686d539187 100644 --- a/skills/orca-per-workspace-env/SKILL.md +++ b/skills/orca-per-workspace-env/SKILL.md @@ -18,7 +18,9 @@ This discovery stub loads the version-matched guide from the Orca executable use Choose the executable once and reuse it for every later command: - If the `ORCA_CLI_COMMAND` environment variable is set, use its value. Orca exports this - for managed WSL sessions. + for managed WSL sessions and for its chat sessions, whose login shells (Codex's among + them) can put a different `orca` first on PATH. Invoke it as `"$ORCA_CLI_COMMAND"` in a + POSIX shell, Git Bash included, and as `& $env:ORCA_CLI_COMMAND` in PowerShell. - Otherwise, in a dev checkout whose session exposes `ORCA_DEV_REPO_ROOT`, use `orca-dev`. - Otherwise, on Linux outside an Orca-managed terminal, use `orca-ide`. Never run bare `orca` there — outside Orca's terminals it normally resolves to the diff --git a/skills/orchestration/SKILL.md b/skills/orchestration/SKILL.md index 4ecd42624d4..785f1111433 100644 --- a/skills/orchestration/SKILL.md +++ b/skills/orchestration/SKILL.md @@ -30,7 +30,9 @@ state; never substitute a non-Orca subagent tool. Choose the executable once and reuse it for every later command: - If the `ORCA_CLI_COMMAND` environment variable is set, use its value. Orca exports this - for managed WSL sessions. + for managed WSL sessions and for its chat sessions, whose login shells (Codex's among + them) can put a different `orca` first on PATH. Invoke it as `"$ORCA_CLI_COMMAND"` in a + POSIX shell, Git Bash included, and as `& $env:ORCA_CLI_COMMAND` in PowerShell. - Otherwise, in a dev checkout whose session exposes `ORCA_DEV_REPO_ROOT`, use `orca-dev`. - Otherwise, on Linux outside an Orca-managed terminal, use `orca-ide`. Never run bare `orca` there — outside Orca's terminals it normally resolves to the diff --git a/src/cli/bundled-skill-guides.ts b/src/cli/bundled-skill-guides.ts index 9e878676b61..292f9bc3794 100644 --- a/src/cli/bundled-skill-guides.ts +++ b/src/cli/bundled-skill-guides.ts @@ -66,13 +66,13 @@ const ORCA_PER_WORKSPACE_ENV_SSH_HOST_REFERENCE_MARKDOWN = "# SSH connection mod const ORCA_PER_WORKSPACE_ENV_WINDOWS_SCRIPTS_REFERENCE_MARKDOWN = "# Windows local-side scripts\n\nLoad this when the user's desktop is Windows and you are scaffolding the local-side scripts. A bare\n`.sh` will not execute there. Either require WSL or Git Bash and point `orca.yaml` at a launcher such\nas `bash ./scripts/orca-vm/.sh` through a `.cmd` file, or scaffold PowerShell equivalents.\n\nThe remote-side commands you run inside the Linux environment stay bash regardless of the desktop OS.\n\n```powershell\n#requires -Version 5\n$ErrorActionPreference = 'Stop'\n# resolve env→state→fallback; run the provider CLI / ssh the same way;\n# capture provider output; build the result object for the chosen mode and write ONE line of JSON to stdout.\n# Orca-server mode: @{ schemaVersion=1; pairingCode=$pairingCode; projectRoot=$projectRoot; userData=@{...} }\n# SSH mode: @{ schemaVersion=1; connection=@{ type=\"ssh\"; projectRoot=$projectRoot;\n# target=@{ label=$label; host=$host; port=$port; username=$user } } }\n($result | ConvertTo-Json -Compress -Depth 6)\n# progress/errors → Write-Error / the error stream, never stdout.\n```\n\nThe doctor's executable-bit check is a POSIX concept and is skipped on Windows, so a script that is\nunusable on the user's machine for a different reason still has to be caught by the `--provision`\nself-test.\n" // oxfmt-ignore -const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n Invoke it as `\"$ORCA_CLI_COMMAND\"` in a POSIX shell (including Git Bash) and\n as `& $env:ORCA_CLI_COMMAND` in PowerShell.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you. `/clear`\nstarts a new session, so a new address: Orca moves your Runs and unread mail to\nit, and a send to the old address is refused with the new one named.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as above, then acknowledge with `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until no\n Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" +const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- Your address is `caller.address` in `ORCA status --json`: `session:` in a\n chat, your handle in a terminal. Never name another agent with `--from`/`--terminal`.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` takes its caller from the environment in a chat or Orca\nterminal; elsewhere pass your own `--terminal `, never `--from`. It\nreturns the bound Run's oldest FIFO Delivery and replays that batch until\nacknowledged. Process every message: reply to questions, validate each\n`worker_done` against the expected active Dispatch, and decide each settled\nterminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect. A chat coordinator\nends its turn instead of `check --wait`; see `references/coordinator-loop.md`.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" // oxfmt-ignore -const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n When `ORCA_CLI_COMMAND` is set, that executable is its value: Orca sets it for\n its chat sessions, where bare `orca` in a login shell can reach another Orca.\n Invoke it as `\"$ORCA_CLI_COMMAND\"` in a POSIX shell (including Git Bash) and\n as `& $env:ORCA_CLI_COMMAND` in PowerShell.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Your address\n\nEvery agent Orca runs has one orchestration address, and other agents reach it\nthere:\n\n- A chat session is `session:`, with the Orca session id. Never use the\n provider's session id: it changes on `/clear` and names no live agent.\n- A terminal agent is its terminal handle.\n\n`ORCA status --json` reports yours as `caller.address`, resolved by Orca from\nthe identity in your environment. A `caller` with `live: false` and a `refusal`\nsays why you cannot act as that session right now; `null` means this shell has\nno orchestration identity. Send to another session with\n`ORCA orchestration send --to session:`; a user may copy a chat's address\nwith its Copy Orchestration Address menu action and give it to you. `/clear`\nstarts a new session, so a new address: Orca moves your Runs and unread mail to\nit, and a send to the old address is refused with the new one named.\n\nYour commands act as you without a caller flag. Never pass another agent's\naddress as `--from` or `--terminal`: in a chat session the CLI refuses it, and in\na terminal it acts as that agent and consumes its mail.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` reads its caller from your environment, like every other\nverb: omit `--terminal` in a chat session and inside your own Orca terminal.\nElsewhere pass `--terminal` with your own handle, never `--from` and never\nanother agent's handle. It returns the bound Run's\noldest FIFO Delivery and replays that batch until acknowledged. Process every\nmessage: reply to questions, validate each `worker_done` against the expected\nactive Dispatch, and decide each settled terminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect.\n\n### Chat coordinators: end the turn instead of waiting\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)`.\n\n1. Bind one Run and start the full independent wave, as above.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as above, then acknowledge with `ORCA orchestration check --ack\n --json`, which also returns the next batch. Repeat until no\n Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The empty-wait\nenumeration above applies when a turn arrives and a Dispatch you expected has\nstill not settled.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id; `ORCA status --json` reports\nyour own as `caller.address`. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" +const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- Your address is `caller.address` in `ORCA status --json`: `session:` in a\n chat, your handle in a terminal. Never name another agent with `--from`/`--terminal`.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` takes its caller from the environment in a chat or Orca\nterminal; elsewhere pass your own `--terminal `, never `--from`. It\nreturns the bound Run's oldest FIFO Delivery and replays that batch until\nacknowledged. Process every message: reply to questions, validate each\n`worker_done` against the expected active Dispatch, and decide each settled\nterminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect. A chat coordinator\nends its turn instead of `check --wait`; see `references/coordinator-loop.md`.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. `/clear` gives the chat a new session and address; Orca\nmoves your Runs and unread mail to it.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. `/clear`\ngives a chat a new address: Orca moves its Runs and unread mail there, and a\nsend to the old one is refused with the new one named. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" // oxfmt-ignore -const ORCHESTRATION_COORDINATOR_LOOP_REFERENCE_MARKDOWN = "# Coordinator loop\n\nLoad this reference for expanded DAG waves, per-invocation launch preferences,\nsame-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n" +const ORCHESTRATION_COORDINATOR_LOOP_REFERENCE_MARKDOWN = "# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. `/clear` gives the chat a new session and address; Orca\nmoves your Runs and unread mail to it.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n" // oxfmt-ignore const ORCHESTRATION_LEGACY_CONTRACT_MIGRATION_REFERENCE_MARKDOWN = "# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n" @@ -81,7 +81,7 @@ const ORCHESTRATION_LEGACY_CONTRACT_MIGRATION_REFERENCE_MARKDOWN = "# Legacy con const ORCHESTRATION_LOW_LEVEL_TOPOLOGY_REFERENCE_MARKDOWN = "# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n" // oxfmt-ignore -const ORCHESTRATION_MESSAGING_AND_GATES_REFERENCE_MARKDOWN = "# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id; `ORCA status --json` reports\nyour own as `caller.address`. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n" +const ORCHESTRATION_MESSAGING_AND_GATES_REFERENCE_MARKDOWN = "# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. `/clear`\ngives a chat a new address: Orca moves its Runs and unread mail there, and a\nsend to the old one is refused with the new one named. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n" // oxfmt-ignore const ORCHESTRATION_PLACEMENT_AND_REMOTE_REFERENCE_MARKDOWN = "# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n" From edd86b2f126690f2f921ce8ddc5009dc198d7296 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 13:12:40 -0700 Subject: [PATCH 08/18] fix(orchestration): refuse a blocking check --wait from a native chat session A chat runs turn by turn through a shell tool with its own timeout, so a blocking wait is killed mid-wait and retried. The host now refuses it with wait_requires_terminal and the turn-loop recovery, keyed on the session's lease: a session a terminal view holds still runs in a PTY and may block. --- .../orchestration-caller-identity.ts | 3 + src/main/runtime/rpc/errors.ts | 1 + .../orchestration/messaging/check-methods.ts | 15 ++++ .../orchestration-check-wait-session.test.ts | 75 +++++++++++++++++++ .../rpc/orchestration-session-caller.ts | 3 +- 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/main/runtime/rpc/orchestration-check-wait-session.test.ts diff --git a/src/main/runtime/orchestration/orchestration-caller-identity.ts b/src/main/runtime/orchestration/orchestration-caller-identity.ts index 72b463b34b1..5e856aaae81 100644 --- a/src/main/runtime/orchestration/orchestration-caller-identity.ts +++ b/src/main/runtime/orchestration/orchestration-caller-identity.ts @@ -1,3 +1,4 @@ +import type { AgentSessionOwnerRuntimeKind } from '../../../shared/agent-session-record' import type { RunRow } from './types' import { isEquivalentPaneKey } from './db/pane-key-match' import { currentRunCoordinatorActor } from './db/runs/run-coordinator-actor' @@ -31,6 +32,8 @@ export type OrchestrationSessionCaller = OrchestrationCallerIdentity & sessionId: string /** Where the session runs, from its record; `worker-start --worktree current` places here. */ workspaceId: string + /** Who holds the lease: a native chat runs turn by turn, a TUI owner runs in a PTY. */ + runtimeKind: AgentSessionOwnerRuntimeKind }> /** A caller with neither a pane nor an actor can never be bound to a Run. */ diff --git a/src/main/runtime/rpc/errors.ts b/src/main/runtime/rpc/errors.ts index ec7f7a0559d..26da3e88df2 100644 --- a/src/main/runtime/rpc/errors.ts +++ b/src/main/runtime/rpc/errors.ts @@ -135,6 +135,7 @@ const STRUCTURED_RUNTIME_PASSTHROUGH_CODES: ReadonlySet = new Set([ 'answer_conflict', 'stale_delivery', 'waiter_exists', + 'wait_requires_terminal', 'invalid_argument', // Why (#19334): "your archive hook failed, nothing was deleted" is a distinct decision — retry, // waive, or skip the hook. Flattened to runtime_error a caller can only pattern-match the text. diff --git a/src/main/runtime/rpc/methods/orchestration/messaging/check-methods.ts b/src/main/runtime/rpc/methods/orchestration/messaging/check-methods.ts index ee52efed6b9..6e0d65bcea6 100644 --- a/src/main/runtime/rpc/methods/orchestration/messaging/check-methods.ts +++ b/src/main/runtime/rpc/methods/orchestration/messaging/check-methods.ts @@ -30,6 +30,9 @@ export const ORCHESTRATION_CHECK_METHODS = [ recordMutationReceipt } ) => { + if (params.wait === true && orchestrationCaller?.runtimeKind === 'native') { + throw waitRequiresTerminal(orchestrationCaller.sessionId) + } const db = runtime.getOrchestrationDb() const handle = params.terminal ?? 'unknown' const typeFilter = parseMessageTypes(params.types) @@ -113,3 +116,15 @@ export const ORCHESTRATION_CHECK_METHODS = [ } }) ] + +/** + * A native chat runs turn by turn through a shell tool with its own timeout, so a blocking wait is + * killed mid-wait and retried. Keyed on the lease: a session a terminal view holds may block. + */ +function waitRequiresTerminal(sessionId: string): OrchestrationError { + return new OrchestrationError( + 'wait_requires_terminal', + `Agent session ${sessionId} is a chat, which runs turn by turn, so check --wait would outlive your shell tool. Run check without --wait, process and --ack what it returns, then end your turn: Orca starts a new turn in this chat when mail arrives. No effects were applied.`, + { effectsApplied: false } + ) +} diff --git a/src/main/runtime/rpc/orchestration-check-wait-session.test.ts b/src/main/runtime/rpc/orchestration-check-wait-session.test.ts new file mode 100644 index 00000000000..265725c2e73 --- /dev/null +++ b/src/main/runtime/rpc/orchestration-check-wait-session.test.ts @@ -0,0 +1,75 @@ +/** + * A chat runs turn by turn through a shell tool with its own timeout, so the host refuses a + * blocking `check --wait` from it instead of leaving the rule to the guide. The gate is the lease: + * a session a terminal view holds runs in a PTY, where blocking is legitimate. + */ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { + createSessionCallerHarness, + isRecord, + orchestrationRequest, + resultOf, + sessionRecord, + SESSION_X, + type SessionCallerHarness +} from './orchestration-session-caller-test-fixture' + +const hostRef = vi.hoisted((): { current: unknown } => ({ current: null })) +vi.mock('../../native-chat/agent-session-wire/structured-agent-session-registry', () => ({ + getStructuredAgentSessionHost: () => hostRef.current +})) + +describe('check --wait from an agent session', () => { + let h: SessionCallerHarness + + beforeEach(async () => { + h = createSessionCallerHarness(hostRef) + resultOf( + await h.dispatch( + orchestrationRequest( + 'orchestration.runCreate', + { objective: 'chat coordinator' }, + { sessionId: SESSION_X } + ) + ) + ) + }) + + afterEach(() => { + h.close() + vi.restoreAllMocks() + }) + + function check(params: Record) { + return h.dispatch(orchestrationRequest('orchestration.check', params, { sessionId: SESSION_X })) + } + + it('refuses a native chat before any waiter registers, naming the turn loop', async () => { + const waitForMessage = vi.spyOn(h.runtime, 'waitForMessage') + + const response = await check({ wait: true, timeoutMs: 1_000 }) + + expect(response).toMatchObject({ + ok: false, + error: { code: 'wait_requires_terminal', data: { effectsApplied: false } } + }) + const message = isRecord(response) && isRecord(response.error) ? response.error.message : '' + expect(message).toContain('Run check without --wait') + expect(message).toContain('end your turn') + expect(waitForMessage).not.toHaveBeenCalled() + }) + + it('still answers the same chat a non-waiting check', async () => { + const result = resultOf(await check({})) + + expect(result.timedOut).not.toBe(true) + }) + + it('lets a session a terminal view holds block, because it runs in a PTY', async () => { + h.records.set(SESSION_X, sessionRecord(SESSION_X, { lease: { runtimeKind: 'tui' } })) + + const result = resultOf(await check({ wait: true, timeoutMs: 50 })) + + expect(result.timedOut).toBe(true) + }) +}) diff --git a/src/main/runtime/rpc/orchestration-session-caller.ts b/src/main/runtime/rpc/orchestration-session-caller.ts index 98fa7ae0ba7..c8f8a19d828 100644 --- a/src/main/runtime/rpc/orchestration-session-caller.ts +++ b/src/main/runtime/rpc/orchestration-session-caller.ts @@ -128,7 +128,8 @@ export async function resolveOrchestrationSessionCaller( const caller: OrchestrationSessionCaller = Object.freeze({ ...identity, sessionId, - workspaceId: record.location.workspaceId + workspaceId: record.location.workspaceId, + runtimeKind: record.lease.runtimeKind }) return { request: { From 652dcf4eb0774371f5720d2831cbc2dbe444d034 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 13:19:38 -0700 Subject: [PATCH 09/18] fix(orchestration): resolve orca status's caller with the verbs' ladder, host-side callerShow now answers a terminal caller the way the coordinator verbs act: the carried handle while it is live, else the handle its pane was reminted as. The CLI always asks, so the host decides that a process has no identity from the same envelope every verb sends; a pane key alone now resolves. --- src/cli/runtime/status-caller.test.ts | 18 ++++++- src/cli/runtime/status-caller.ts | 5 +- .../rpc/methods/orchestration/caller-show.ts | 49 ++++++++++++++++--- .../rpc/orchestration-caller-show.test.ts | 32 ++++++++++++ 4 files changed, 92 insertions(+), 12 deletions(-) diff --git a/src/cli/runtime/status-caller.test.ts b/src/cli/runtime/status-caller.test.ts index 75924e303a6..49dba68077b 100644 --- a/src/cli/runtime/status-caller.test.ts +++ b/src/cli/runtime/status-caller.test.ts @@ -170,9 +170,23 @@ describe.skipIf(process.platform === 'win32')('orca status reports its caller ad expect(JSON.parse(await status(true)).result).not.toHaveProperty('caller') }) - it('reports no caller, without asking the host, for a process with no identity', async () => { + it('lets the host decide that a process carries no identity', async () => { + callerShowReply = { result: { caller: null } } + expect(await statusCaller()).toBeNull() - expect(received.map((request) => request.method)).toEqual(['status.get']) + expect(callerShowRequests()).toHaveLength(1) expect(await status(false)).toContain('caller: none') }) + + it('asks the host about a process that carries only a pane key', async () => { + process.env.ORCA_PANE_KEY = 'tab_1:leaf_1' + callerShowReply = { + result: { caller: { kind: 'terminal', address: 'term_reminted', live: true } } + } + + expect(await statusCaller()).toEqual({ kind: 'terminal', address: 'term_reminted', live: true }) + expect(callerShowRequests()[0]?.orchestrationCompatibilityEvidence).toEqual({ + paneKey: 'tab_1:leaf_1' + }) + }) }) diff --git a/src/cli/runtime/status-caller.ts b/src/cli/runtime/status-caller.ts index f77e09495e9..a06580e8b2e 100644 --- a/src/cli/runtime/status-caller.ts +++ b/src/cli/runtime/status-caller.ts @@ -22,9 +22,8 @@ export async function resolveCliStatusCaller( client: Pick ): Promise { const sessionId = readInjectedAgentSessionId() - if (!sessionId && !process.env.ORCA_TERMINAL_HANDLE?.trim()) { - return null - } + // Why always asked: the host decides "no identity" from the same envelope every verb sends, so a + // pane key alone still resolves the caller its verbs would act as. try { const response = await client.call( 'orchestration.callerShow', diff --git a/src/main/runtime/rpc/methods/orchestration/caller-show.ts b/src/main/runtime/rpc/methods/orchestration/caller-show.ts index b2d38538ec1..cd5c5608329 100644 --- a/src/main/runtime/rpc/methods/orchestration/caller-show.ts +++ b/src/main/runtime/rpc/methods/orchestration/caller-show.ts @@ -1,4 +1,9 @@ -import type { OrchestrationCallerShowResult } from '../../../../../shared/orchestration-caller-status' +import type { + OrchestrationCallerAddress, + OrchestrationCallerShowResult +} from '../../../../../shared/orchestration-caller-status' +import type { OrchestrationCompatibilityEvidence } from '../../../../../shared/orchestration-compatibility-evidence' +import type { OrcaRuntimeService } from '../../../orca-runtime' import { defineMethod } from '../../core' export const ORCHESTRATION_CALLER_METHODS = [ @@ -22,12 +27,42 @@ export const ORCHESTRATION_CALLER_METHODS = [ } } } - const handle = orchestrationCompatibilityEvidence?.terminalHandle - if (!handle) { - return { caller: null } - } - const identity = runtime.resolveTerminalIdentity(handle) - return { caller: { kind: 'terminal', address: identity.handle, live: identity.live } } + return { caller: resolveTerminalCaller(runtime, orchestrationCompatibilityEvidence) } } }) ] + +/** + * The ladder the coordinator verbs climb for a terminal caller: the handle the environment carries + * while it is live, else the handle its pane was reminted as. Answering the stale handle instead + * would hand out a mailbox nothing reads. + */ +function resolveTerminalCaller( + runtime: OrcaRuntimeService, + evidence: OrchestrationCompatibilityEvidence | undefined +): OrchestrationCallerAddress | null { + const handle = evidence?.terminalHandle + if (handle) { + const identity = runtime.resolveTerminalIdentity(handle) + if (identity.live) { + return { kind: 'terminal', address: identity.handle, live: true } + } + } + const reminted = evidence?.paneKey ? resolvePaneHandle(runtime, evidence.paneKey) : null + if (reminted) { + return { kind: 'terminal', address: reminted, live: true } + } + return handle ? { kind: 'terminal', address: handle, live: false } : null +} + +function resolvePaneHandle(runtime: OrcaRuntimeService, paneKey: string): string | null { + try { + return runtime.resolveTerminalPane(paneKey).handle + } catch (error) { + // Why: the verbs treat an unresolvable pane as no remint, not as a failed call. + if (error instanceof Error && error.message === 'terminal_not_found') { + return null + } + throw error + } +} diff --git a/src/main/runtime/rpc/orchestration-caller-show.test.ts b/src/main/runtime/rpc/orchestration-caller-show.test.ts index f246b0b9249..7ce21959f36 100644 --- a/src/main/runtime/rpc/orchestration-caller-show.test.ts +++ b/src/main/runtime/rpc/orchestration-caller-show.test.ts @@ -116,6 +116,38 @@ describe('orchestration.callerShow: the caller learns its own address from the h expect(probe).toHaveBeenCalledTimes(2) }) + it('answers the reminted handle, as the coordinator verbs act, when the carried one went stale', async () => { + vi.spyOn(h.runtime, 'resolveTerminalIdentity').mockImplementation((handle) => ({ + handle, + live: handle === 'term_new' + })) + const resolvePane = vi.spyOn(h.runtime, 'resolveTerminalPane').mockImplementation((paneKey) => { + if (paneKey !== 'tab_1:leaf_1') { + throw new Error('terminal_not_found') + } + return { handle: 'term_new', tabId: 'tab_1', leafId: 'leaf_1', ptyId: null, connected: true } + }) + + const reminted = await h.dispatch( + callerShow({ evidence: { terminalHandle: 'term_old', paneKey: 'tab_1:leaf_1' } }) + ) + const paneOnly = await h.dispatch(callerShow({ evidence: { paneKey: 'tab_1:leaf_1' } })) + const gone = await h.dispatch( + callerShow({ evidence: { terminalHandle: 'term_old', paneKey: 'tab_gone:leaf' } }) + ) + + expect(resultOf(reminted)).toEqual({ + caller: { kind: 'terminal', address: 'term_new', live: true } + }) + expect(resultOf(paneOnly)).toEqual({ + caller: { kind: 'terminal', address: 'term_new', live: true } + }) + expect(resultOf(gone)).toEqual({ + caller: { kind: 'terminal', address: 'term_old', live: false } + }) + expect(resolvePane).toHaveBeenCalledTimes(3) + }) + it('answers null for a caller whose environment carries no identity', async () => { const response = await h.dispatch(callerShow({})) From 68745eac4abf90c8818a0ceeede657fe3d5e123d Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 13:30:58 -0700 Subject: [PATCH 10/18] fix(orchestration): show a structured worker as session: wherever agents read mail A structured worker was session: in orca status and its preamble, but structworker_ in check rows, banners, reply hints, its own check label and a sub-worker's coordinator line. The minted handle is now only the mailbox key: mailbox reads, the check label and preamble coordinator lines spell the worker session:, which the host binds back to that mailbox. Send receipts still echo the stored row, whose sender key worker_done settlement matches. --- .../orchestration/terminal-identity.ts | 6 +- .../orchestration-session-caller-cli.test.ts | 7 ++ src/cli/session-caller-flags.ts | 4 +- .../structured-session-mail-address.ts | 25 +++++ .../orchestration/messaging/check-direct.ts | 13 ++- .../orchestration/messaging/check-run.ts | 23 ++--- .../orchestration/messaging/check-worker.ts | 29 +++--- .../messaging/mailbox-message-receipt.ts | 23 +++++ .../orchestration/runs/dispatch-methods.ts | 7 +- .../deliver-worker-dispatch-preamble.ts | 6 +- ...structured-worker-address-spelling.test.ts | 97 +++++++++++++++++++ 11 files changed, 194 insertions(+), 46 deletions(-) create mode 100644 src/main/runtime/rpc/orchestration-structured-worker-address-spelling.test.ts diff --git a/src/cli/handlers/orchestration/terminal-identity.ts b/src/cli/handlers/orchestration/terminal-identity.ts index 572b9096bce..2a60e84ac09 100644 --- a/src/cli/handlers/orchestration/terminal-identity.ts +++ b/src/cli/handlers/orchestration/terminal-identity.ts @@ -4,7 +4,6 @@ import { RuntimeClientError } from '../../runtime-client' import { getTerminalHandle } from '../../selectors' import { hasStructuredSessionMarker } from '../../../shared/structured-session-marker' import { readInjectedAgentSessionId } from '../../../shared/agent-session-caller-env' -import { injectedSessionAddress } from '../../session-caller-flags' /** * The caller's terminal handle, or `undefined` when an injected agent session id names the caller: @@ -168,9 +167,10 @@ function getClientErrorMessage(err: unknown): string | undefined { return typeof message === 'string' ? message : undefined } -/** How check output names its caller: the handle, or the session's address. */ +/** How check output names its caller: the handle, or `session:`, a structured worker's too. */ export function orchestrationCallerLabel(handle: string | undefined): string { - return handle ?? injectedSessionAddress() ?? 'unknown' + const sessionId = readInjectedAgentSessionId() + return handle ?? (sessionId ? `session:${sessionId}` : 'unknown') } export async function resolveCoordinatorTerminalHandle( diff --git a/src/cli/orchestration-session-caller-cli.test.ts b/src/cli/orchestration-session-caller-cli.test.ts index 9ca398e35b2..eba798e168e 100644 --- a/src/cli/orchestration-session-caller-cli.test.ts +++ b/src/cli/orchestration-session-caller-cli.test.ts @@ -25,6 +25,7 @@ import { refuseConflictingSessionCallerFlags } from './session-caller-flags' import { createOrchestrationCompatibilityEnvelope } from './runtime/orchestration-compatibility-envelope' import { formatCliError, reportCliError } from './cli-error' import { RuntimeRpcFailureError } from './runtime/types' +import { orchestrationCallerLabel } from './handlers/orchestration/terminal-identity' const SESSION = 'f7a1c0de-1111-4222-8333-444455556666' const IDENTITY_ENV = [ @@ -415,6 +416,12 @@ describe('the identity a session presents', () => { expect(getTerminalHandleMock).not.toHaveBeenCalled() }) + it("labels a structured worker's check by its session address, not its minted handle", () => { + setEnv({ ORCA_AGENT_SESSION_ID: SESSION, ORCA_TERMINAL_HANDLE: 'structworker_self' }) + + expect(orchestrationCallerLabel(undefined)).toBe(`session:${SESSION}`) + }) + it('resumes a timed-out ask as the session, without naming a terminal', async () => { asSessionInTerminalView() callMock.mockResolvedValue({ result: { ...RESULT.result, answer: null, timedOut: true } }) diff --git a/src/cli/session-caller-flags.ts b/src/cli/session-caller-flags.ts index 1ef820d7fee..bfd8558b4da 100644 --- a/src/cli/session-caller-flags.ts +++ b/src/cli/session-caller-flags.ts @@ -52,8 +52,8 @@ function namesInjectedSession(value: string, sessionId: string, env: NodeJS.Proc } /** - * The address the host gives this session: a structured worker keeps the handle it was minted, any - * other session is `session:`. Only for text that must match what the host writes. + * The mailbox key the host binds this session to: a structured worker keeps the handle it was + * minted, any other session is `session:`. Never shown to the agent as its address. */ export function injectedSessionAddress(env: NodeJS.ProcessEnv = process.env): string | undefined { const sessionId = readInjectedAgentSessionId(env) diff --git a/src/main/runtime/orchestration/structured-session-mail-address.ts b/src/main/runtime/orchestration/structured-session-mail-address.ts index eed4be40a8b..196693c5b60 100644 --- a/src/main/runtime/orchestration/structured-session-mail-address.ts +++ b/src/main/runtime/orchestration/structured-session-mail-address.ts @@ -21,11 +21,13 @@ import { import { getStructuredAgentSessionHost } from '../../native-chat/agent-session-wire/structured-agent-session-registry' import { isRecordedStructuredWorkerSession, + resolveStructuredWorkerIdentity, resolveStructuredWorkerIdentityForSession } from '../structured-worker-authority' import { structuredWorkerHostScope } from '../structured-worker-identity' import type { OrchestrationDb } from './db' import type { OrchestrationCallerIdentity } from './orchestration-caller-identity' +import type { MessageRow } from './types' export type AgentSessionRecordReader = { getRecord: (sessionId: string) => AgentSessionRecord | null @@ -199,3 +201,26 @@ export function hasLostStructuredWorkerIdentity( isRecordedStructuredWorkerSession(conversation.id, db) ) } + +/** + * How an agent is shown a mailbox address. A structured worker's handle is only its mailbox key: it + * reads as `session:`, the one address that worker is taught, and routes back to that mailbox. + */ +export function agentVisibleOrchestrationAddress( + address: string, + db: OrchestrationDb | null | undefined +): string { + const worker = resolveStructuredWorkerIdentity(address, db) + return worker ? formatOrchestrationActor({ kind: 'session', id: worker.sessionId }) : address +} + +export function withAgentVisibleAddresses( + messages: readonly MessageRow[], + db: OrchestrationDb | null | undefined +): MessageRow[] { + return messages.map((message) => ({ + ...message, + from_handle: agentVisibleOrchestrationAddress(message.from_handle, db), + to_handle: agentVisibleOrchestrationAddress(message.to_handle, db) + })) +} diff --git a/src/main/runtime/rpc/methods/orchestration/messaging/check-direct.ts b/src/main/runtime/rpc/methods/orchestration/messaging/check-direct.ts index fd8293ae90d..0cdfaf46b74 100644 --- a/src/main/runtime/rpc/methods/orchestration/messaging/check-direct.ts +++ b/src/main/runtime/rpc/methods/orchestration/messaging/check-direct.ts @@ -1,8 +1,7 @@ import type { MessageType, OrchestrationDb } from '../../../../orchestration/db' import type { OrcaRuntimeService } from '../../../../orca-runtime' import { OrchestrationError } from '../../../../orchestration/orchestration-error' -import { formatMessageBanner } from '../../../../orchestration/formatter' -import { exposeMessages } from './mailbox-message-receipt' +import { exposeReadMessages, formatReadMessages } from './mailbox-message-receipt' import { reconcileLifecycleMessage } from '../../../../orchestration/lifecycle-reconciliation' import { ORCHESTRATION_LEGACY_RUN_ID } from '../../../../../../shared/orchestration-rpc-contract' import type { CheckParams } from '../schemas' @@ -48,10 +47,14 @@ export async function checkDirectMailbox(args: { db.markAsRead(messages.map((message) => message.id)) } if (params.format || params.inject) { - const formatted = visibleMessages.map(formatMessageBanner).join('\n\n') - return { messages: exposeMessages(visibleMessages), formatted, count: visibleMessages.length } + const formatted = formatReadMessages(visibleMessages, db) + return { + messages: exposeReadMessages(visibleMessages, db), + formatted, + count: visibleMessages.length + } } - return { messages: exposeMessages(visibleMessages), count: visibleMessages.length } + return { messages: exposeReadMessages(visibleMessages, db), count: visibleMessages.length } } if (signal?.aborted) { diff --git a/src/main/runtime/rpc/methods/orchestration/messaging/check-run.ts b/src/main/runtime/rpc/methods/orchestration/messaging/check-run.ts index 248d79ea68e..4b6dccbf84d 100644 --- a/src/main/runtime/rpc/methods/orchestration/messaging/check-run.ts +++ b/src/main/runtime/rpc/methods/orchestration/messaging/check-run.ts @@ -2,8 +2,7 @@ import type { MessageRow, MessageType, OrchestrationDb } from '../../../../orche import type { OrcaRuntimeService } from '../../../../orca-runtime' import type { RpcContext } from '../../../core' import { OrchestrationError } from '../../../../orchestration/orchestration-error' -import { formatMessageBanner } from '../../../../orchestration/formatter' -import { exposeMessages } from './mailbox-message-receipt' +import { exposeReadMessages, formatReadMessages } from './mailbox-message-receipt' import { interruptedAcknowledgedCheck } from '../routing' import { routeAllMailboxPages } from '../schemas' import { resolveRunScope } from '../runs/run-scope' @@ -104,14 +103,14 @@ export async function checkRunMailbox(args: { if (params.all || (params.unread === false && !params.peek)) { const messages = db.getRunMailboxHistory(run.id, 100, typeFilter) const result = { - messages: exposeMessages(messages), + messages: exposeReadMessages(messages, db), count: messages.length, acknowledged: acknowledged?.delivery.id ?? null } if (params.format || params.inject) { return { ...result, - formatted: messages.map(formatMessageBanner).join('\n\n'), + formatted: formatReadMessages(messages, db), runId: run.id } } @@ -120,12 +119,10 @@ export async function checkRunMailbox(args: { const peekResult = (messages: MessageRow[]) => ({ runId: run.id, - messages: exposeMessages(messages), + messages: exposeReadMessages(messages, db), count: messages.length, acknowledged: acknowledged?.delivery.id ?? null, - ...(params.format || params.inject - ? { formatted: messages.map(formatMessageBanner).join('\n\n') } - : {}) + ...(params.format || params.inject ? { formatted: formatReadMessages(messages, db) } : {}) }) const readPeek = () => db.getUnreadRunMailbox(run.id, 100, typeFilter) const readDelivery = (wakeTypes?: MessageType[]) => @@ -139,7 +136,7 @@ export async function checkRunMailbox(args: { return { runId: run.id, deliveryId: current.delivery.id, - messages: exposeMessages(current.messages), + messages: exposeReadMessages(current.messages, db), count: current.messages.length, replayed: current.replayed, acknowledged: acknowledged?.delivery.id ?? null, @@ -147,7 +144,7 @@ export async function checkRunMailbox(args: { cancelled: false, connectionLost: false, ...(params.format || params.inject - ? { formatted: current.messages.map(formatMessageBanner).join('\n\n') } + ? { formatted: formatReadMessages(current.messages, db) } : {}) } } @@ -243,15 +240,13 @@ export async function checkRunMailbox(args: { return { runId: run.id, deliveryId: current?.delivery.id ?? null, - messages: exposeMessages(current?.messages ?? []), + messages: exposeReadMessages(current?.messages ?? [], db), count: current?.messages.length ?? 0, replayed: current?.replayed ?? false, acknowledged: acknowledged?.delivery.id ?? null, timedOut: false, cancelled: false, connectionLost: false, - ...(params.format && current - ? { formatted: current.messages.map(formatMessageBanner).join('\n\n') } - : {}) + ...(params.format && current ? { formatted: formatReadMessages(current.messages, db) } : {}) } } diff --git a/src/main/runtime/rpc/methods/orchestration/messaging/check-worker.ts b/src/main/runtime/rpc/methods/orchestration/messaging/check-worker.ts index fc9fa6b04e9..b0f09d79c75 100644 --- a/src/main/runtime/rpc/methods/orchestration/messaging/check-worker.ts +++ b/src/main/runtime/rpc/methods/orchestration/messaging/check-worker.ts @@ -1,8 +1,7 @@ import type { MessageType, OrchestrationDb } from '../../../../orchestration/db' import type { OrcaRuntimeService } from '../../../../orca-runtime' import { OrchestrationError } from '../../../../orchestration/orchestration-error' -import { formatMessageBanner } from '../../../../orchestration/formatter' -import { exposeMessages } from './mailbox-message-receipt' +import { exposeReadMessages, formatReadMessages } from './mailbox-message-receipt' import { routeAllMailboxPages } from '../schemas' import { asDispatchFence, callerHoldsDispatchPane, dispatchFenced } from './dispatch-mailbox-fence' import type { CheckParams } from '../schemas' @@ -199,12 +198,10 @@ export async function checkWorkerMailbox(args: { return { ...(workerMailbox.runId ? { runId: workerMailbox.runId } : {}), dispatchId: workerMailbox.dispatchId, - messages: exposeMessages(messages), + messages: exposeReadMessages(messages, db), count: messages.length, acknowledged: acknowledged?.delivery.id ?? null, - ...(params.format || params.inject - ? { formatted: messages.map(formatMessageBanner).join('\n\n') } - : {}) + ...(params.format || params.inject ? { formatted: formatReadMessages(messages, db) } : {}) } } if (params.peek) { @@ -213,12 +210,10 @@ export async function checkWorkerMailbox(args: { return { ...(workerMailbox.runId ? { runId: workerMailbox.runId } : {}), dispatchId: workerMailbox.dispatchId, - messages: exposeMessages(messages), + messages: exposeReadMessages(messages, db), count: messages.length, acknowledged: acknowledged?.delivery.id ?? null, - ...(params.format || params.inject - ? { formatted: messages.map(formatMessageBanner).join('\n\n') } - : {}) + ...(params.format || params.inject ? { formatted: formatReadMessages(messages, db) } : {}) } } } else { @@ -228,7 +223,7 @@ export async function checkWorkerMailbox(args: { ...(workerMailbox.runId ? { runId: workerMailbox.runId } : {}), dispatchId: workerMailbox.dispatchId, deliveryId: current?.delivery.id ?? null, - messages: exposeMessages(current?.messages ?? []), + messages: exposeReadMessages(current?.messages ?? [], db), count: current?.messages.length ?? 0, replayed: current?.replayed ?? false, acknowledged: acknowledged?.delivery.id ?? null, @@ -236,7 +231,7 @@ export async function checkWorkerMailbox(args: { cancelled: false, connectionLost: false, ...(params.format || params.inject - ? { formatted: current?.messages.map(formatMessageBanner).join('\n\n') ?? '' } + ? { formatted: formatReadMessages(current?.messages, db) } : {}) } } @@ -267,12 +262,10 @@ export async function checkWorkerMailbox(args: { return { ...(workerMailbox.runId ? { runId: workerMailbox.runId } : {}), dispatchId: workerMailbox.dispatchId, - messages: exposeMessages(arrived), + messages: exposeReadMessages(arrived, db), count: arrived.length, acknowledged: acknowledged?.delivery.id ?? null, - ...(params.format || params.inject - ? { formatted: arrived.map(formatMessageBanner).join('\n\n') } - : {}) + ...(params.format || params.inject ? { formatted: formatReadMessages(arrived, db) } : {}) } } const arrived = readDelivery(typeFilter) @@ -280,12 +273,12 @@ export async function checkWorkerMailbox(args: { ...(workerMailbox.runId ? { runId: workerMailbox.runId } : {}), dispatchId: workerMailbox.dispatchId, deliveryId: arrived?.delivery.id ?? null, - messages: exposeMessages(arrived?.messages ?? []), + messages: exposeReadMessages(arrived?.messages ?? [], db), count: arrived?.messages.length ?? 0, replayed: arrived?.replayed ?? false, acknowledged: acknowledged?.delivery.id ?? null, ...(params.format || params.inject - ? { formatted: arrived?.messages.map(formatMessageBanner).join('\n\n') ?? '' } + ? { formatted: formatReadMessages(arrived?.messages, db) } : {}) } } diff --git a/src/main/runtime/rpc/methods/orchestration/messaging/mailbox-message-receipt.ts b/src/main/runtime/rpc/methods/orchestration/messaging/mailbox-message-receipt.ts index c843b4db9b9..0896abb9ce5 100644 --- a/src/main/runtime/rpc/methods/orchestration/messaging/mailbox-message-receipt.ts +++ b/src/main/runtime/rpc/methods/orchestration/messaging/mailbox-message-receipt.ts @@ -1,3 +1,6 @@ +import type { OrchestrationDb } from '../../../../orchestration/db' +import { formatMessageBanner } from '../../../../orchestration/formatter' +import { withAgentVisibleAddresses } from '../../../../orchestration/structured-session-mail-address' import type { MessageRow } from '../../../../orchestration/types' // Why: read/sequence and the pointer_* and sender_pane_key columns are delivery plumbing @@ -26,3 +29,23 @@ export function exposeMessages(messages: MessageRow[]): MailboxMessageReceipt[] return exposed as MailboxMessageReceipt }) } + +/** + * Rows as the reader of a mailbox sees them. Only reads are re-spelled: a send receipt echoes its + * stored row, whose sender key worker_done settlement matches. + */ +export function exposeReadMessages( + messages: readonly MessageRow[], + db: OrchestrationDb +): MailboxMessageReceipt[] { + return exposeMessages(withAgentVisibleAddresses(messages, db)) +} + +export function formatReadMessages( + messages: readonly MessageRow[] | undefined, + db: OrchestrationDb +): string { + return withAgentVisibleAddresses(messages ?? [], db) + .map((message) => formatMessageBanner(message)) + .join('\n\n') +} diff --git a/src/main/runtime/rpc/methods/orchestration/runs/dispatch-methods.ts b/src/main/runtime/rpc/methods/orchestration/runs/dispatch-methods.ts index e3a73e60194..0f6296d2f84 100644 --- a/src/main/runtime/rpc/methods/orchestration/runs/dispatch-methods.ts +++ b/src/main/runtime/rpc/methods/orchestration/runs/dispatch-methods.ts @@ -11,6 +11,7 @@ import { taskNotStartableError } from '../../../../orchestration/task-dispatch-refusal' import { resolveRunScope } from './run-scope' +import { agentVisibleOrchestrationAddress } from '../../../../orchestration/structured-session-mail-address' import { DispatchParams, DispatchShowParams } from '../schemas' export const ORCHESTRATION_DISPATCH_METHODS = [ @@ -60,7 +61,7 @@ export const ORCHESTRATION_DISPATCH_METHODS = [ dispatchId: 'ctx_dryrun', canDispatchSubWorkers: previewDepth < maxDepth, taskSpec: task.spec, - coordinatorHandle: params.from ?? 'coordinator', + coordinatorHandle: agentVisibleOrchestrationAddress(params.from ?? 'coordinator', db), workerHandle: params.to ?? 'worker', devMode: params.devMode, ...(params.to @@ -150,7 +151,7 @@ export const ORCHESTRATION_DISPATCH_METHODS = [ dispatchId: ctx.id, canDispatchSubWorkers: ctx.depth < runtime.getNestedWorkerMaxDepth(), taskSpec: task.spec, - coordinatorHandle: params.from ?? 'coordinator', + coordinatorHandle: agentVisibleOrchestrationAddress(params.from ?? 'coordinator', db), workerHandle: to, dispatchCapability, devMode: params.devMode, @@ -209,7 +210,7 @@ export const ORCHESTRATION_DISPATCH_METHODS = [ dispatchId: ctx?.id ?? 'ctx_preview', canDispatchSubWorkers: (ctx?.depth ?? 1) < runtime.getNestedWorkerMaxDepth(), taskSpec: task.spec, - coordinatorHandle: params.from ?? 'coordinator', + coordinatorHandle: agentVisibleOrchestrationAddress(params.from ?? 'coordinator', db), workerHandle, devMode: params.devMode, ...(ctx ? { cliCommand: runtime.getTerminalOrchestrationCliCommand(workerHandle) } : {}) diff --git a/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts index 415773f00c7..9acb6d5c969 100644 --- a/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts +++ b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts @@ -5,6 +5,7 @@ import { dispatchPreambleSendOptions } from '../../../../orchestration/preamble' import { structuredSessionCliInvocation } from '../../../../orchestration/cli-command' +import { agentVisibleOrchestrationAddress } from '../../../../orchestration/structured-session-mail-address' import { sendStructuredWorkerPreamble } from '../../orchestration-structured-worker-session' import type { createStructuredWorkerSessionForWorktree } from './worker-topology' @@ -39,7 +40,10 @@ export async function deliverWorkerDispatchPreamble(args: { taskId: args.taskId, dispatchId: args.dispatchId, taskSpec: args.taskSpec, - coordinatorHandle: args.coordinatorHandle, + coordinatorHandle: agentVisibleOrchestrationAddress( + args.coordinatorHandle, + runtime.getOrchestrationDb() + ), workerHandle: terminalHandle, ...(structuredSession ? { diff --git a/src/main/runtime/rpc/orchestration-structured-worker-address-spelling.test.ts b/src/main/runtime/rpc/orchestration-structured-worker-address-spelling.test.ts new file mode 100644 index 00000000000..320d316f7bb --- /dev/null +++ b/src/main/runtime/rpc/orchestration-structured-worker-address-spelling.test.ts @@ -0,0 +1,97 @@ +/** + * A structured worker is taught one address, `session:`. The handle it was minted is only its + * mailbox key, so every mailbox read an agent sees spells the worker the way its preamble does. + */ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { + mintStructuredWorkerHandle, + mintStructuredWorkerPaneKey, + structuredWorkerIdentities, + structuredWorkerProcessIncarnation +} from '../structured-worker-identity' +import { formatReadMessages } from './methods/orchestration/messaging/mailbox-message-receipt' +import { + createSessionCallerHarness, + orchestrationRequest, + resultOf, + SESSION_X, + SESSION_Y, + type SessionCallerHarness +} from './orchestration-session-caller-test-fixture' + +const hostRef = vi.hoisted((): { current: unknown } => ({ current: null })) +vi.mock('../../native-chat/agent-session-wire/structured-agent-session-registry', () => ({ + getStructuredAgentSessionHost: () => hostRef.current +})) + +describe('a structured worker reads as session: wherever an agent reads mail', () => { + let h: SessionCallerHarness + let workerHandle: string + + beforeEach(() => { + h = createSessionCallerHarness(hostRef) + workerHandle = mintStructuredWorkerHandle() + structuredWorkerIdentities.register({ + handle: workerHandle, + sessionId: SESSION_Y, + agent: 'claude', + paneKey: mintStructuredWorkerPaneKey(SESSION_Y), + processIncarnation: structuredWorkerProcessIncarnation(SESSION_Y), + worktreeId: 'wt_1', + hostScope: { kind: 'local', hostId: 'local' } + }) + }) + + afterEach(() => { + h.close() + vi.restoreAllMocks() + }) + + it("shows the coordinator its worker's session address in the rows and the banner", async () => { + const created = resultOf( + await h.dispatch( + orchestrationRequest( + 'orchestration.runCreate', + { objective: 'o' }, + { sessionId: SESSION_X } + ) + ) + ) + const runId = String((created.run as { id: string }).id) + h.db.insertMessage({ + from: workerHandle, + to: `run:${runId}`, + subject: 'progress', + type: 'status', + runId + }) + + const checked = resultOf( + await h.dispatch( + orchestrationRequest('orchestration.check', { format: true }, { sessionId: SESSION_X }) + ) + ) + + expect(checked.messages).toEqual([ + expect.objectContaining({ from_handle: `session:${SESSION_Y}` }) + ]) + expect(checked.formatted).toContain(`(session:${SESSION_Y})`) + expect(JSON.stringify(checked)).not.toContain(workerHandle) + }) + + it('tells the worker to reply as its session address, which the host binds to the same mailbox', () => { + const row = h.db.insertMessage({ + from: 'term_coord', + to: workerHandle, + subject: 'follow-up', + type: 'status' + }) + + const formatted = formatReadMessages([row], h.db) + + expect(formatted).toContain(`--from session:${SESSION_Y} `) + expect(formatted).not.toContain(workerHandle) + // Stored under the mailbox key: only the reading is re-spelled. + expect(h.db.getMessageById(row.id)?.to_handle).toBe(workerHandle) + }) +}) From f9404c1a51e0edc50c8922f3feb593dadd69faca Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 13:31:02 -0700 Subject: [PATCH 11/18] fix(orchestration): teach a chat worker the turn loop and pin preamble parity at the contract The worker preamble was byte-identical across modes except its address, so a chat worker was taught a 600s blocking ask its shell tool kills before the message ID for --resume prints, heartbeat exemptions for check --wait, and to keep a shell open. Parity now pins the contract (sections, verbs, flags, lifecycle ids); interaction discipline follows the mode: a chat asks with a 5s wait and ends its turn, owns sub-workers through the turn loop, and names itself session: in every command. The guide says a chat's address survives /clear and that Orca refuses a chat's check --wait. --- skill-guides/orchestration.md | 12 +-- .../references/coordinator-loop.md | 7 +- .../references/messaging-and-gates.md | 7 +- .../references/worker-contract.md | 9 +- src/cli/bundled-skill-guides.ts | 10 +- src/cli/root-help-text-secondary.ts | 2 +- src/cli/specs/core.ts | 2 +- src/cli/specs/orchestration.ts | 2 +- .../runtime/orchestration/preamble.test.ts | 49 ++++++++- src/main/runtime/orchestration/preamble.ts | 100 ++++++++++++------ .../orchestration-worker-mode-opacity.test.ts | 56 ++++++---- .../orchestration-check-wait-session.test.ts | 3 +- 12 files changed, 187 insertions(+), 72 deletions(-) diff --git a/skill-guides/orchestration.md b/skill-guides/orchestration.md index d92fb30205a..d87a4f2140d 100644 --- a/skill-guides/orchestration.md +++ b/skill-guides/orchestration.md @@ -66,7 +66,8 @@ non-Orca subagent tool when Orca orchestration provenance was requested. examples below, replace `ORCA` with it; do not create a shell variable or run `ORCA` literally. If it fails, report that exact error instead of switching. - Your address is `caller.address` in `ORCA status --json`: `session:` in a - chat, your handle in a terminal. Never name another agent with `--from`/`--terminal`. + chat (a chat worker too; it survives `/clear`), your handle in a terminal. + Never name another agent with `--from`/`--terminal`. - A successful `orchestration send` proves durable enqueue; its wake or nudge is best-effort attention only and does not prove the recipient read or accepted it. @@ -74,15 +75,14 @@ non-Orca subagent tool when Orca orchestration provenance was requested. The injected preamble is authoritative. A dispatched worker must: -1. Do only the current Task and use the preamble's `ask` command for a blocking - coordinator question. Never open a local question TUI the coordinator cannot - answer. Resume the same message ID after an ask timeout. +1. Do only the current Task. Ask the coordinator only with the preamble's `ask` + command, never a local question TUI; resume its message ID after a timeout. 2. Send heartbeats only at the cadence in the preamble. A heartbeat proves liveness, not completion. 3. Read coordinator follow-ups at each natural checkpoint — before starting a new file, after a test run — and once more immediately before `worker_done`, with the preamble's own `check` command. -4. Send `worker_done` exactly once, from the dispatched terminal, with a +4. Send `worker_done` exactly once, as the dispatched worker, with a three-sentence executive summary, both lifecycle IDs, and explicit `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose. 5. Append `--files-modified` and `--report-path` only with real values when @@ -144,7 +144,7 @@ sent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose `worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence, including when `worker-show` reports `agentWait` null. Absence never authorizes stop, abandon, retry, or release; keep waiting or inspect. A chat coordinator -ends its turn instead of `check --wait`; see `references/coordinator-loop.md`. +ends its turn instead; Orca refuses its `check --wait` (`references/coordinator-loop.md`). `worker-start` is the normal path, composing placement, terminal readiness, prompt injection, and supervised resource ownership. `dispatch --inject` leaves diff --git a/skill-guides/orchestration/references/coordinator-loop.md b/skill-guides/orchestration/references/coordinator-loop.md index 96c0b421ae1..4581a41fc82 100644 --- a/skill-guides/orchestration/references/coordinator-loop.md +++ b/skill-guides/orchestration/references/coordinator-loop.md @@ -8,7 +8,8 @@ of truth for the loop order and completion boundary. When `ORCA status --json` reports `caller.kind` `session`, you coordinate from a chat. Never block in `check --wait`: your shell tool has its own timeout, and -Orca wakes you instead. When messages reach your Run, Orca starts a new turn in +Orca wakes you instead. Orca refuses it with `wait_requires_terminal` while the +session runs as a chat; only its terminal view may wait. When messages reach your Run, Orca starts a new turn in this chat once you are idle, saying `You have orchestration message(s)` and naming the `check` to run. @@ -22,8 +23,8 @@ naming the `check` to run. A turn with no new Delivery is a checkpoint, not a failure. The compact guide's empty-wait enumeration applies when a turn arrives and a Dispatch you expected -has still not settled. `/clear` gives the chat a new session and address; Orca -moves your Runs and unread mail to it. +has still not settled. Your address survives `/clear`: your Runs and unread +mail stay with the chat. ## Ready waves diff --git a/skill-guides/orchestration/references/messaging-and-gates.md b/skill-guides/orchestration/references/messaging-and-gates.md index bed3fc33f88..607ad1d8316 100644 --- a/skill-guides/orchestration/references/messaging-and-gates.md +++ b/skill-guides/orchestration/references/messaging-and-gates.md @@ -43,9 +43,10 @@ reachable at `session:`, its Orca session id, never the provider's id (it changes on `/clear`). `ORCA status --json` reports your own as `caller.address`; a `caller` with `live: false` carries the refusal that stops you acting as that session, and `null` means the shell has no orchestration identity. A user may -copy a chat's address with its Copy Orchestration Address menu action. `/clear` -gives a chat a new address: Orca moves its Runs and unread mail there, and a -send to the old one is refused with the new one named. `check` is the exception: it identifies +copy a chat's address with its Copy Orchestration Address menu action. A chat's +address survives `/clear`, and its Runs and unread mail stay with it. A worker +running as a chat is `session:` too; its internal `structworker_` mailbox +key is never an address to hand out. `check` is the exception: it identifies its caller with `--terminal`, never `--from`. Group addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`, diff --git a/skill-guides/orchestration/references/worker-contract.md b/skill-guides/orchestration/references/worker-contract.md index 6e35da7b8f9..7f0e2a66456 100644 --- a/skill-guides/orchestration/references/worker-contract.md +++ b/skill-guides/orchestration/references/worker-contract.md @@ -2,12 +2,15 @@ The injected preamble is authoritative. Copy its command rather than reconstructing flags. In particular, preserve the exact executable, worker -handle, Dispatch capability, Task ID, and Dispatch ID. +address, Dispatch capability, Task ID, and Dispatch ID. A worker running as a +chat names itself `session:`, never a `structworker_` handle, and follows +its preamble's chat forms below. ## Heartbeat Send heartbeats only at the cadence required by the live preamble. Skip them while blocked inside `ask` or `check --wait`; those calls are liveness signals. +A chat skips them only while its turn has ended waiting for an answer. ```text ORCA orchestration send --from --dispatch-capability --type heartbeat --subject "alive" --task-id --dispatch-id --phase "" @@ -30,6 +33,10 @@ ORCA orchestration ask --from --dispatch-capability A timeout or disconnect leaves the original question pending. Resume its message ID; do not create a duplicate question. +A chat never blocks here: its shell tool would kill the call before the message +ID prints. It asks with the preamble's short `--timeout-ms`, ends its turn on a +timeout, and runs the printed resume command on the turn the reply starts. + ## Reading coordinator follow-ups The coordinator steers a running worker with `send --to dispatch:`. That diff --git a/src/cli/bundled-skill-guides.ts b/src/cli/bundled-skill-guides.ts index 292f9bc3794..c3c37cb856d 100644 --- a/src/cli/bundled-skill-guides.ts +++ b/src/cli/bundled-skill-guides.ts @@ -66,13 +66,13 @@ const ORCA_PER_WORKSPACE_ENV_SSH_HOST_REFERENCE_MARKDOWN = "# SSH connection mod const ORCA_PER_WORKSPACE_ENV_WINDOWS_SCRIPTS_REFERENCE_MARKDOWN = "# Windows local-side scripts\n\nLoad this when the user's desktop is Windows and you are scaffolding the local-side scripts. A bare\n`.sh` will not execute there. Either require WSL or Git Bash and point `orca.yaml` at a launcher such\nas `bash ./scripts/orca-vm/.sh` through a `.cmd` file, or scaffold PowerShell equivalents.\n\nThe remote-side commands you run inside the Linux environment stay bash regardless of the desktop OS.\n\n```powershell\n#requires -Version 5\n$ErrorActionPreference = 'Stop'\n# resolve env→state→fallback; run the provider CLI / ssh the same way;\n# capture provider output; build the result object for the chosen mode and write ONE line of JSON to stdout.\n# Orca-server mode: @{ schemaVersion=1; pairingCode=$pairingCode; projectRoot=$projectRoot; userData=@{...} }\n# SSH mode: @{ schemaVersion=1; connection=@{ type=\"ssh\"; projectRoot=$projectRoot;\n# target=@{ label=$label; host=$host; port=$port; username=$user } } }\n($result | ConvertTo-Json -Compress -Depth 6)\n# progress/errors → Write-Error / the error stream, never stdout.\n```\n\nThe doctor's executable-bit check is a POSIX concept and is skipped on Windows, so a script that is\nunusable on the user's machine for a different reason still has to be caught by the `--provision`\nself-test.\n" // oxfmt-ignore -const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- Your address is `caller.address` in `ORCA status --json`: `session:` in a\n chat, your handle in a terminal. Never name another agent with `--from`/`--terminal`.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` takes its caller from the environment in a chat or Orca\nterminal; elsewhere pass your own `--terminal `, never `--from`. It\nreturns the bound Run's oldest FIFO Delivery and replays that batch until\nacknowledged. Process every message: reply to questions, validate each\n`worker_done` against the expected active Dispatch, and decide each settled\nterminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect. A chat coordinator\nends its turn instead of `check --wait`; see `references/coordinator-loop.md`.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" +const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- Your address is `caller.address` in `ORCA status --json`: `session:` in a\n chat (a chat worker too; it survives `/clear`), your handle in a terminal.\n Never name another agent with `--from`/`--terminal`.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task. Ask the coordinator only with the preamble's `ask`\n command, never a local question TUI; resume its message ID after a timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, as the dispatched worker, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` takes its caller from the environment in a chat or Orca\nterminal; elsewhere pass your own `--terminal `, never `--from`. It\nreturns the bound Run's oldest FIFO Delivery and replays that batch until\nacknowledged. Process every message: reply to questions, validate each\n`worker_done` against the expected active Dispatch, and decide each settled\nterminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect. A chat coordinator\nends its turn instead; Orca refuses its `check --wait` (`references/coordinator-loop.md`).\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" // oxfmt-ignore -const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- Your address is `caller.address` in `ORCA status --json`: `session:` in a\n chat, your handle in a terminal. Never name another agent with `--from`/`--terminal`.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task and use the preamble's `ask` command for a blocking\n coordinator question. Never open a local question TUI the coordinator cannot\n answer. Resume the same message ID after an ask timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, from the dispatched terminal, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` takes its caller from the environment in a chat or Orca\nterminal; elsewhere pass your own `--terminal `, never `--from`. It\nreturns the bound Run's oldest FIFO Delivery and replays that batch until\nacknowledged. Process every message: reply to questions, validate each\n`worker_done` against the expected active Dispatch, and decide each settled\nterminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect. A chat coordinator\nends its turn instead of `check --wait`; see `references/coordinator-loop.md`.\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. `/clear` gives the chat a new session and address; Orca\nmoves your Runs and unread mail to it.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. `/clear`\ngives a chat a new address: Orca moves its Runs and unread mail there, and a\nsend to the old one is refused with the new one named. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" +const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- Your address is `caller.address` in `ORCA status --json`: `session:` in a\n chat (a chat worker too; it survives `/clear`), your handle in a terminal.\n Never name another agent with `--from`/`--terminal`.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task. Ask the coordinator only with the preamble's `ask`\n command, never a local question TUI; resume its message ID after a timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, as the dispatched worker, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` takes its caller from the environment in a chat or Orca\nterminal; elsewhere pass your own `--terminal `, never `--from`. It\nreturns the bound Run's oldest FIFO Delivery and replays that batch until\nacknowledged. Process every message: reply to questions, validate each\n`worker_done` against the expected active Dispatch, and decide each settled\nterminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect. A chat coordinator\nends its turn instead; Orca refuses its `check --wait` (`references/coordinator-loop.md`).\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. Orca refuses it with `wait_requires_terminal` while the\nsession runs as a chat; only its terminal view may wait. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. Your address survives `/clear`: your Runs and unread\nmail stay with the chat.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. A chat's\naddress survives `/clear`, and its Runs and unread mail stay with it. A worker\nrunning as a chat is `session:` too; its internal `structworker_` mailbox\nkey is never an address to hand out. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\naddress, Dispatch capability, Task ID, and Dispatch ID. A worker running as a\nchat names itself `session:`, never a `structworker_` handle, and follows\nits preamble's chat forms below.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\nA chat skips them only while its turn has ended waiting for an answer.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\nA chat never blocks here: its shell tool would kill the call before the message\nID prints. It asks with the preamble's short `--timeout-ms`, ends its turn on a\ntimeout, and runs the printed resume command on the turn the reply starts.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" // oxfmt-ignore -const ORCHESTRATION_COORDINATOR_LOOP_REFERENCE_MARKDOWN = "# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. `/clear` gives the chat a new session and address; Orca\nmoves your Runs and unread mail to it.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n" +const ORCHESTRATION_COORDINATOR_LOOP_REFERENCE_MARKDOWN = "# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. Orca refuses it with `wait_requires_terminal` while the\nsession runs as a chat; only its terminal view may wait. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. Your address survives `/clear`: your Runs and unread\nmail stay with the chat.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n" // oxfmt-ignore const ORCHESTRATION_LEGACY_CONTRACT_MIGRATION_REFERENCE_MARKDOWN = "# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n" @@ -81,7 +81,7 @@ const ORCHESTRATION_LEGACY_CONTRACT_MIGRATION_REFERENCE_MARKDOWN = "# Legacy con const ORCHESTRATION_LOW_LEVEL_TOPOLOGY_REFERENCE_MARKDOWN = "# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n" // oxfmt-ignore -const ORCHESTRATION_MESSAGING_AND_GATES_REFERENCE_MARKDOWN = "# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. `/clear`\ngives a chat a new address: Orca moves its Runs and unread mail there, and a\nsend to the old one is refused with the new one named. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n" +const ORCHESTRATION_MESSAGING_AND_GATES_REFERENCE_MARKDOWN = "# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. A chat's\naddress survives `/clear`, and its Runs and unread mail stay with it. A worker\nrunning as a chat is `session:` too; its internal `structworker_` mailbox\nkey is never an address to hand out. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n" // oxfmt-ignore const ORCHESTRATION_PLACEMENT_AND_REMOTE_REFERENCE_MARKDOWN = "# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n" @@ -90,7 +90,7 @@ const ORCHESTRATION_PLACEMENT_AND_REMOTE_REFERENCE_MARKDOWN = "# Placement and r const ORCHESTRATION_RECOVERY_AND_CLEANUP_REFERENCE_MARKDOWN = "# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n" // oxfmt-ignore -const ORCHESTRATION_WORKER_CONTRACT_REFERENCE_MARKDOWN = "# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\nhandle, Dispatch capability, Task ID, and Dispatch ID.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" +const ORCHESTRATION_WORKER_CONTRACT_REFERENCE_MARKDOWN = "# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\naddress, Dispatch capability, Task ID, and Dispatch ID. A worker running as a\nchat names itself `session:`, never a `structworker_` handle, and follows\nits preamble's chat forms below.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\nA chat skips them only while its turn has ended waiting for an answer.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\nA chat never blocks here: its shell tool would kill the call before the message\nID prints. It asks with the preamble's short `--timeout-ms`, ends its turn on a\ntimeout, and runs the printed resume command on the turn the reply starts.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" // oxfmt-ignore export const BUNDLED_SKILL_GUIDES = [ diff --git a/src/cli/root-help-text-secondary.ts b/src/cli/root-help-text-secondary.ts index 1ffa40eb1bd..dc8aa5fea54 100644 --- a/src/cli/root-help-text-secondary.ts +++ b/src/cli/root-help-text-secondary.ts @@ -113,7 +113,7 @@ export const ROOT_HELP_TEXT_SECONDARY = [ ' Remote runtime access can also be supplied with ORCA_PAIRING_CODE or ORCA_ENVIRONMENT.', ' Use selectors for discovery and handles for repeated live terminal operations.', ' Inside an Orca agent, `orca status --json` reports its orchestration address as caller.address:', - ' session: for a chat session, its terminal handle for a terminal agent.', + ' session: for a chat session, kept across /clear; its terminal handle for a terminal agent.', ' When ORCA_CLI_COMMAND is set, run that executable: "$ORCA_CLI_COMMAND" in a POSIX shell,', ' & $env:ORCA_CLI_COMMAND in PowerShell. Bare `orca` in a login shell can reach another Orca.', '', diff --git a/src/cli/specs/core.ts b/src/cli/specs/core.ts index 71bffaf3733..e64ef732aa8 100644 --- a/src/cli/specs/core.ts +++ b/src/cli/specs/core.ts @@ -20,7 +20,7 @@ export const CORE_COMMAND_SPECS: CommandSpec[] = [ usage: 'orca status [--json]', allowedFlags: [...GLOBAL_FLAGS], notes: [ - "caller is this agent's orchestration address as Orca resolved it from its environment: session: for a chat session, the terminal handle for a terminal agent, null outside an Orca agent." + "caller is this agent's orchestration address as Orca resolved it from its environment: session: for a chat session, kept across /clear, the terminal handle for a terminal agent, null outside an Orca agent." ], examples: ['orca status', 'orca status --json'] }, diff --git a/src/cli/specs/orchestration.ts b/src/cli/specs/orchestration.ts index 4143fc7716f..48183a320db 100644 --- a/src/cli/specs/orchestration.ts +++ b/src/cli/specs/orchestration.ts @@ -116,7 +116,7 @@ export const ORCHESTRATION_COMMAND_SPECS: CommandSpec[] = [ identityFlagRoles: { terminal: 'caller' }, notes: [ 'The caller is this agent: session: in a chat session, else the Orca terminal it runs in. Omit --terminal in both; pass only your own handle elsewhere.', - 'A chat coordinator never uses --wait: Orca starts a turn in the chat when mail arrives, and that turn runs check.', + 'A chat never uses --wait, and Orca refuses it (wait_requires_terminal): Orca starts a turn in the chat when mail arrives, and that turn runs check.', 'On Windows PowerShell, quote comma-separated type filters, e.g. --types "worker_done,escalation".', '--types is the wake condition for --wait; a returned Delivery is always the whole FIFO batch, so it is never filtered by type. Without --wait it has no effect on consuming checks. Only --peek and --all filter their rows.', '--format renders the returned rows as local text only; it never writes to another terminal.', diff --git a/src/main/runtime/orchestration/preamble.test.ts b/src/main/runtime/orchestration/preamble.test.ts index 0734370f744..f26a12d57bc 100644 --- a/src/main/runtime/orchestration/preamble.test.ts +++ b/src/main/runtime/orchestration/preamble.test.ts @@ -421,10 +421,57 @@ describe('the worker is told its own orchestration address', () => { ) expect(preamble).toContain(`Your orchestration address is: session:${sessionId}\n`) - expect(preamble).toContain('Your coordinator reaches you there or at dispatch:ctx_def456.') + expect(preamble).toContain('Your coordinator reaches you there.') expect(preamble).toContain("Your coordinator's address is: term_coord\n") }) + it('names a structured worker by one address in every command, never its minted handle', () => { + const preamble = buildDispatchPreamble( + baseParams({ workerHandle: 'structworker_1', structuredSession: posixSession }) + ) + + expect(preamble).not.toContain('structworker_1') + expect(preamble).not.toContain('dispatch:ctx_def456') + expect(cliFence(preamble)).toContain(`--from session:${sessionId} `) + expect(cliFence(preamble)).toContain(`check --terminal session:${sessionId} --json`) + }) +}) + +describe('a chat worker is taught the turn loop, not a blocking one', () => { + const sessionId = '4a1f6c2e-8b3d-4e7a-9c15-0d2b6e8f1a37' + const chat = () => + buildDispatchPreamble( + baseParams({ + workerHandle: 'structworker_1', + canDispatchSubWorkers: true, + structuredSession: { sessionId, cliInvocation: '"$ORCA_CLI_COMMAND"' } + }) + ) + + it('asks with a wait no shell tool kills, so the message ID for --resume is always printed', () => { + const ask = cliFence(chat()) + .split('\n') + .find((line) => line.includes('orchestration ask ')) + const timeoutMs = Number(/--timeout-ms (\d+)/.exec(ask ?? '')?.[1]) + + // Below the shortest default any supported agent's shell tool applies to a command. + expect(timeoutMs).toBeLessThan(10_000) + expect(chat()).toContain("it prints the question's message ID and a resume command") + expect(chat()).toContain('the reply starts a new turn in this chat') + }) + + it('never teaches a blocking wait, a shell to keep open, or a terminal it does not have', () => { + const preamble = chat() + + expect(preamble).not.toContain('--timeout-ms 600000') + expect(preamble).not.toContain('blocked inside') + expect(preamble).not.toContain('block until') + expect(preamble).not.toContain('Do not exit the shell') + expect(preamble).not.toMatch(/this terminal/) + expect(preamble).toContain('never in `check --wait`') + expect(afterWorkerDoneSection(preamble)).toContain('starts a new turn here') + }) + it.each([ ['a POSIX shell', '"$ORCA_CLI_COMMAND"'], ['PowerShell', '& $env:ORCA_CLI_COMMAND'] diff --git a/src/main/runtime/orchestration/preamble.ts b/src/main/runtime/orchestration/preamble.ts index a606649f33c..4e71d789056 100644 --- a/src/main/runtime/orchestration/preamble.ts +++ b/src/main/runtime/orchestration/preamble.ts @@ -63,10 +63,17 @@ export function buildDispatchPreamble(params: PreambleParams): string { : params.devMode ? 'orca-dev' : (params.cliCommand ?? 'orca') + const chat = params.structuredSession !== undefined + // Why one spelling: a structured worker's minted handle is only its mailbox key; the host binds + // `session:` to that same caller, so every command names it the way its address line does. + const self = params.structuredSession + ? `session:${params.structuredSession.sessionId}` + : params.workerHandle const postDoneInstructions = buildPostWorkerDoneInstructions({ cli, - workerKind: params.workerKind ?? 'prompt-returning-agent' + workerKind: chat ? 'chat' : (params.workerKind ?? 'prompt-returning-agent') }) + const surface = chat ? 'chat' : 'terminal' const capabilityFlag = params.dispatchCapability ? ` --dispatch-capability ${params.dispatchCapability}` : '' @@ -79,8 +86,8 @@ export function buildDispatchPreamble(params: PreambleParams): string { Your coordinator's address is: ${params.coordinatorHandle} Your task ID is: ${params.taskId} ${buildWorkerAddressSection(params)} -The coordinator cannot see this terminal, so reach it with the \`${cli} orchestration\` -commands below; a question or result left only in this terminal never gets to it. +The coordinator cannot see this ${surface}, so reach it with the \`${cli} orchestration\` +commands below; a question or result left only in this ${surface} never gets to it. Don't post to Slack, GitHub, or other channels during the run; report through these commands. === CLI COMMANDS === @@ -100,41 +107,29 @@ Don't post to Slack, GitHub, or other channels during the run; report through th # Never encode failure only in prose and never silently exit. # Include BOTH taskId and dispatchId in the payload so a late completion # from a failed retry cannot complete the current dispatch. - ${cli} orchestration send --from ${params.workerHandle}${capabilityFlag} --type worker_done --subject "" --body "<3-sentence summary: what you did, what you found, what's left>" --task-id ${params.taskId} --dispatch-id ${params.dispatchId} --outcome succeeded + ${cli} orchestration send --from ${self}${capabilityFlag} --type worker_done --subject "" --body "<3-sentence summary: what you did, what you found, what's left>" --task-id ${params.taskId} --dispatch-id ${params.dispatchId} --outcome succeeded # Send a heartbeat every ${HEARTBEAT_INTERVAL_MIN} minutes # while actively working on the task. The coordinator uses this to - # distinguish "still thinking" from "hung / crashed." Skip heartbeats only - # while blocked inside \`check --wait\` or \`ask\` — those calls are - # themselves liveness signals. + # distinguish "still thinking" from "hung / crashed." ${chat ? 'Skip heartbeats only\n # while your turn has ended waiting for an answer to `ask`.' : 'Skip heartbeats only\n # while blocked inside `check --wait` or `ask` — those calls are\n # themselves liveness signals.'} # # Include BOTH taskId and dispatchId in the payload: the coordinator # attributes the heartbeat to the specific dispatch context, not just # the task, so a straggler heartbeat from a previously-failed dispatch # cannot mask a hung retry. - ${cli} orchestration send --from ${params.workerHandle}${capabilityFlag} --type heartbeat --subject "alive" --task-id ${params.taskId} --dispatch-id ${params.dispatchId} --phase "" + ${cli} orchestration send --from ${self}${capabilityFlag} --type heartbeat --subject "alive" --task-id ${params.taskId} --dispatch-id ${params.dispatchId} --phase "" - # Ask the coordinator a question and block until it answers. - # - # Use this instead of AskUserQuestion: that opens a local prompt the - # coordinator cannot see or answer, so the task would stall until someone - # happened to look at this terminal. Send every question through \`ask\`. - # - # The \`ask\` verb durably records a question in this Dispatch's Run and - # blocks until the coordinator replies, then prints the reply body. If the - # call times out or disconnects, resume with the returned message ID instead - # of creating a duplicate question. - ${cli} orchestration ask --from ${params.workerHandle}${capabilityFlag} --question "" --options "" --timeout-ms 600000 +${buildAskRecipe({ chat, cli, self, capabilityFlag })} # Escalate a blocker or failure (pre-completion, when you need the # coordinator to do something before you can continue): - ${cli} orchestration send --from ${params.workerHandle}${capabilityFlag} --type escalation --subject "Blocked: " --body "
" --task-id ${params.taskId} --dispatch-id ${params.dispatchId} + ${cli} orchestration send --from ${self}${capabilityFlag} --type escalation --subject "Blocked: " --body "
" --task-id ${params.taskId} --dispatch-id ${params.dispatchId} # Read coordinator follow-ups. Nothing interrupts you: a durable message only # arrives when you look, so run this at each natural checkpoint — before you # start a new file and after a test run — and once more immediately before # you send worker_done, so a redirect lands before the task settles. - ${cli} orchestration check --terminal ${params.workerHandle} --json + ${cli} orchestration check --terminal ${self} --json \`\`\` ${postDoneInstructions}` @@ -147,7 +142,7 @@ ${postDoneInstructions}` const drift = params.baseDrift && params.baseDrift.behind > 0 ? buildDriftSection(params.baseDrift) : '' - const subDispatch = params.canDispatchSubWorkers ? buildSubDispatchSection(cli) : '' + const subDispatch = params.canDispatchSubWorkers ? buildSubDispatchSection(cli, chat) : '' return `${header}${drift}${subDispatch} @@ -178,8 +173,8 @@ function buildWorkerAddressSection(params: PreambleParams): string { ` } return `Your orchestration address is: session:${session.sessionId} -Your coordinator reaches you there or at dispatch:${params.dispatchId}. Mail that arrives while -you are idle starts a new turn in this chat; mid-task, read it with the check command below. +Your coordinator reaches you there. Mail that arrives while you are idle starts a new turn in +this chat; mid-task, read it with the check command below. Run every command below exactly as written: \`${session.cliInvocation}\` runs this Orca's CLI from ORCA_CLI_COMMAND, and a bare \`orca\` in a login shell can reach a different Orca. ` @@ -190,7 +185,7 @@ function buildPostWorkerDoneInstructions({ workerKind }: { cli: string - workerKind: NonNullable + workerKind: NonNullable | 'chat' }): string { // Why: re-dispatch reaches idle agents as terminal input; inbox polling // after completion cannot receive that new TASK block and looks hung. @@ -208,10 +203,11 @@ prompt for Orca to reuse; if the coordinator has more for you it will dispatch or prompt another worker with a fresh TASK block.` } + const chat = workerKind === 'chat' return `=== AFTER YOU SEND worker_done === worker_done ends your turn for this task. Your dispatched work is complete: -stop, return to an idle prompt, and take no further actions — do NOT start +stop, ${chat ? 'end your turn' : 'return to an idle prompt'}, and take no further actions — do NOT start new or unrelated work, do NOT run a sleep/poll loop, and do NOT keep calling \`${cli} orchestration check\`. The coordinator has already recorded your completion and expects no further output. @@ -221,18 +217,57 @@ Treat it as new user-owned work: follow it without coordinator approval or a fresh Dispatch, and do not send lifecycle messages using the settled task or Dispatch IDs. Never refuse a direct user request because you were a worker. -Do not exit the shell. Your terminal stays available, and if the +${ + chat + ? `This chat stays available: if the coordinator has more for you, a fresh +preamble + TASK block starts a new turn here.` + : `Do not exit the shell. Your terminal stays available, and if the coordinator has more for you it will re-engage this terminal with a fresh -preamble + TASK block, which arrives as new input. Treat that as supervised +preamble + TASK block, which arrives as new input.` +} Treat that as supervised work under the new Dispatch; ignore stale follow-ups from the settled task.` } +// Why: a chat's shell tool kills a long blocking call, and the message ID `--resume` needs is printed +// only when the call returns — so a chat asks with a wait shorter than any shell tool's timeout. +const CHAT_ASK_TIMEOUT_MS = 5_000 + +function buildAskRecipe(args: { + chat: boolean + cli: string + self: string + capabilityFlag: string +}): string { + const lead = args.chat + ? ` # Ask the coordinator a question.` + : ` # Ask the coordinator a question and block until it answers.` + const semantics = args.chat + ? ` # The \`ask\` verb durably records a question in this Dispatch's Run and + # waits ${CHAT_ASK_TIMEOUT_MS / 1000} seconds, well inside your shell tool's timeout. With no reply + # by then it prints the question's message ID and a resume command: end + # your turn, and the reply starts a new turn in this chat. Run that resume + # command then instead of asking again.` + : ` # The \`ask\` verb durably records a question in this Dispatch's Run and + # blocks until the coordinator replies, then prints the reply body. If the + # call times out or disconnects, resume with the returned message ID instead + # of creating a duplicate question.` + const timeoutMs = args.chat ? CHAT_ASK_TIMEOUT_MS : 600_000 + return `${lead} + # + # Use this instead of AskUserQuestion: that opens a local prompt the + # coordinator cannot see or answer, so the task would stall until someone + # happened to look at this ${args.chat ? 'chat' : 'terminal'}. Send every question through \`ask\`. + # +${semantics} + ${args.cli} orchestration ask --from ${args.self}${args.capabilityFlag} --question "" --options "" --timeout-ms ${timeoutMs}` +} + // Why the whole section is omitted rather than softened when nesting is off: a // worker told it "usually cannot" delegate still tries, then reports the refusal // as a blocker. // Why fenced + blank line before the closing `---`: unfenced `` are stripped as raw // HTML by the Chat UI, and a rule directly under a paragraph is a setext H2 (giant last sentence). -function buildSubDispatchSection(cli: string): string { +function buildSubDispatchSection(cli: string, chat: boolean): string { return ` === SUB-DISPATCH === @@ -245,7 +280,12 @@ and start each one: ${cli} orchestration worker-start --task --worktree current --agent --json \`\`\` -You own those sub-workers: wait for their worker_done, and do not report your own +You own those sub-workers: ${ + chat + ? `end your turn and handle their mail on the turns it starts, +never in \`check --wait\`, and do not report your own worker_done` + : 'wait for their worker_done, and do not report your own' + } until they have settled. Nesting is capped, so a sub-worker of yours may not be able to dispatch further. diff --git a/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts b/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts index cb79ba36ccb..88aaa883e29 100644 --- a/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts +++ b/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts @@ -3,9 +3,10 @@ * * Two properties are pinned here, because both were false at some point in this lane: * - * - a worker is TAUGHT the same thing whichever mode it runs in, byte for byte once the handle and - * dispatch id are normalised. The sub-dispatch section used to be withheld from a structured - * worker, which is a two-tier capability model dressed as a preamble tweak; + * - a worker is TAUGHT the same contract whichever mode it runs in: the same sections, verbs, + * flags and lifecycle ids. The sub-dispatch section used to be withheld from a structured + * worker, which is a two-tier capability model dressed as a preamble tweak. How it waits is + * not contract: a chat's shell tool kills a blocking call, so that discipline follows the mode; * - a structured worker can actually BE a coordinator. `worker-start` used to resolve `--from` * through `showTerminal`, which needs a PTY, so the capability the preamble withheld was in fact * missing rather than merely unadvertised. @@ -92,16 +93,24 @@ function installStructuredCoordinator(handle: string, sessionId: string): string return paneKey } -/** Strips the ids that legitimately differ per dispatch, leaving what the agent is taught. */ /** - * The two facts that legitimately differ by mode, and nothing else: the worker's own address (its - * handle, or `session:` with how mail reaches a chat) and how its shell invokes the CLI. + * The contract a preamble teaches: its sections, then every command with the worker's own address, + * its CLI invocation and its wait budget normalised. Those three follow the mode; nothing else may. */ -function normalizeWorkerIdentity(preamble: string, cli: string): string { - return preamble - .replace(/^Your orchestration address is: [^\n]*\n(?:[^\n]+\n)*/m, '\n') - .split(`${cli} orchestration`) - .join(' orchestration') +function preambleContract(preamble: string, self: string, cli: string): string[] { + const sections = preamble.match(/^=== [A-Z -]+ ===$/gm) ?? [] + const commands = preamble + .split('\n') + .map((line) => line.trim()) + .filter((line) => line.startsWith(`${cli} orchestration `)) + .map((line) => + line + .slice(cli.length) + .split(self) + .join('') + .replace(/--timeout-ms \d+/g, '--timeout-ms ') + ) + return [...sections, ...commands] } function normalizePreamble(preamble: string, handle: string, dispatchId: string): string { @@ -195,7 +204,7 @@ describe('a worker cannot tell which mode it is running in', () => { return result } - it('teaches byte-identical instructions in both modes', async () => { + it('teaches the same contract in both modes', async () => { vi.spyOn(runtime, 'showTerminal').mockResolvedValue({ handle: 'term_coord', worktreeId: WORKTREE, @@ -217,17 +226,22 @@ describe('a worker cannot tell which mode it is running in', () => { expect(terminal.mode.mode).toBe('terminal') const structuredPreamble = structuredPreambles[0] as string const terminalPreamble = vi.mocked(runtime.sendTerminalAgentPrompt).mock.calls[0]?.[1] as string - expect( - normalizeWorkerIdentity( - normalizePreamble(structuredPreamble, STRUCTURED_HANDLE, structured.dispatchId), - '"$ORCA_CLI_COMMAND"' - ) - ).toBe( - normalizeWorkerIdentity( + const structuredContract = preambleContract( + normalizePreamble(structuredPreamble, STRUCTURED_HANDLE, structured.dispatchId), + 'session:sess_worker', + '"$ORCA_CLI_COMMAND"' + ) + expect(structuredContract).toEqual( + preambleContract( normalizePreamble(terminalPreamble, TERMINAL_HANDLE, terminal.dispatchId), + '', 'orca' ) ) + // Guards the equality against both sides losing their commands. + expect(structuredContract.filter((line) => line.includes(' orchestration '))).toHaveLength(8) + // One agent-visible address: the minted handle is the mailbox key, never taught. + expect(structuredPreamble).not.toContain(STRUCTURED_HANDLE) expect(structuredPreamble).toContain('Your orchestration address is: session:sess_worker\n') expect(terminalPreamble).toContain(`Your orchestration address is: ${TERMINAL_HANDLE}\n`) // The section the structured lane used to withhold, asserted by name so the equality above @@ -250,6 +264,10 @@ describe('a worker cannot tell which mode it is running in', () => { expect(result).toMatchObject({ state: 'ready' }) expect(showTerminal).not.toHaveBeenCalled() + // Its sub-worker is told the coordinator's one address, not the handle it was minted. + expect(vi.mocked(runtime.sendTerminalAgentPrompt).mock.calls[0]?.[1]).toContain( + "Your coordinator's address is: session:sess_coord\n" + ) expect(vi.mocked(runtime.sendTerminalAgentPrompt).mock.calls[0]?.[1]).toContain( '=== SUB-DISPATCH ===' ) diff --git a/src/main/runtime/rpc/orchestration-check-wait-session.test.ts b/src/main/runtime/rpc/orchestration-check-wait-session.test.ts index 265725c2e73..421968106c9 100644 --- a/src/main/runtime/rpc/orchestration-check-wait-session.test.ts +++ b/src/main/runtime/rpc/orchestration-check-wait-session.test.ts @@ -53,7 +53,8 @@ describe('check --wait from an agent session', () => { ok: false, error: { code: 'wait_requires_terminal', data: { effectsApplied: false } } }) - const message = isRecord(response) && isRecord(response.error) ? response.error.message : '' + const failure: unknown = response + const message = isRecord(failure) && isRecord(failure.error) ? failure.error.message : '' expect(message).toContain('Run check without --wait') expect(message).toContain('end your turn') expect(waitForMessage).not.toHaveBeenCalled() From 11f9c4affddc4d2cee5ebbc57991a0507c1b7937 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 13:35:44 -0700 Subject: [PATCH 12/18] test(orchestration): pass the db to preamble delivery and fence a terminal-view waiter The coordinator line maps a structured coordinator's handle through the orchestration db, so delivery takes it from its caller. The consumer-fencing waiter test now waits as a terminal-view session, the only session kind that may still block in check --wait. --- .../worker/deliver-worker-dispatch-preamble.test.ts | 11 +++++++++-- .../worker/deliver-worker-dispatch-preamble.ts | 7 +++---- .../worker/worker-start-readiness-settlement.ts | 1 + .../rpc/orchestration-session-coordinator.test.ts | 2 ++ 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.test.ts b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.test.ts index f8d4c33da6e..8588a191571 100644 --- a/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.test.ts +++ b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.test.ts @@ -1,5 +1,6 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest' +import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest' import type { OrcaRuntimeService } from '../../../../orca-runtime' +import { OrchestrationDb } from '../../../../orchestration/db' import { deliverWorkerDispatchPreamble } from './deliver-worker-dispatch-preamble' const sent = vi.hoisted((): { preambles: string[] } => ({ preambles: [] })) @@ -36,6 +37,7 @@ function structuredSession(agent: 'claude' | 'codex' = 'claude'): StructuredSess } const args = { + db: new OrchestrationDb(':memory:'), dispatchId: 'ctx_1', dispatchDepth: 1, taskId: 'task_1', @@ -51,6 +53,10 @@ describe('deliverWorkerDispatchPreamble tells each worker its own address', () = sent.preambles = [] }) + afterAll(() => { + args.db.close() + }) + it('names a structured worker by the session it was started as', async () => { const prompts: string[] = [] await deliverWorkerDispatchPreamble({ @@ -64,8 +70,9 @@ describe('deliverWorkerDispatchPreamble tells each worker its own address', () = expect(sent.preambles).toHaveLength(1) expect(sent.preambles[0]).toContain(`Your orchestration address is: session:${SESSION}\n`) expect(sent.preambles[0]).toContain( - '"$ORCA_CLI_COMMAND" orchestration send --from structworker_1' + `"$ORCA_CLI_COMMAND" orchestration send --from session:${SESSION}` ) + expect(sent.preambles[0]).not.toContain('structworker_1') }) it("renders the CLI in the worker's own shell: PowerShell for Codex on Windows", async () => { diff --git a/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts index 9acb6d5c969..70417a4a2e3 100644 --- a/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts +++ b/src/main/runtime/rpc/methods/orchestration/worker/deliver-worker-dispatch-preamble.ts @@ -1,5 +1,6 @@ import type { RuntimeTerminalSend } from '../../../../../../shared/runtime-terminal-contracts' import type { OrcaRuntimeService } from '../../../../orca-runtime' +import type { OrchestrationDb } from '../../../../orchestration/db' import { buildDispatchPreamble, dispatchPreambleSendOptions @@ -20,6 +21,7 @@ type StructuredSession = Awaited { const runId = await runCreate(SESSION_X) + // A terminal view: only a PTY-held session may block in check --wait. + h.records.set(SESSION_X, sessionRecord(SESSION_X, { lease: { runtimeKind: 'tui' } })) const waiter = vi.spyOn(h.runtime, 'waitForMessage') const waiting = h.dispatch( orchestrationRequest( From f0a390d8525686140b37993383488be74dd955c6 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 13:41:12 -0700 Subject: [PATCH 13/18] test(orchestration): read the Run id with the fixture's checked accessor --- .../orchestration-structured-worker-address-spelling.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/runtime/rpc/orchestration-structured-worker-address-spelling.test.ts b/src/main/runtime/rpc/orchestration-structured-worker-address-spelling.test.ts index 320d316f7bb..ce18cbd0dbe 100644 --- a/src/main/runtime/rpc/orchestration-structured-worker-address-spelling.test.ts +++ b/src/main/runtime/rpc/orchestration-structured-worker-address-spelling.test.ts @@ -12,6 +12,7 @@ import { import { formatReadMessages } from './methods/orchestration/messaging/mailbox-message-receipt' import { createSessionCallerHarness, + idOf, orchestrationRequest, resultOf, SESSION_X, @@ -57,7 +58,7 @@ describe('a structured worker reads as session: wherever an agent reads mail ) ) ) - const runId = String((created.run as { id: string }).id) + const runId = idOf(created.run) h.db.insertMessage({ from: workerHandle, to: `run:${runId}`, From 1c043cbd2cf9e83d0ba97f01d4e85cfd39d5210e Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 14:01:05 -0700 Subject: [PATCH 14/18] feat(orchestration): copy a chat's conversation address, which /clear keeps Copy Orchestration Address copied session:. A chat's address is its conversation's, derived by the host from the session records, so the menu now asks the host for it at copy time through orchestration.sessionAddress, the same derivation a verb acting as that session binds to. A host that predates the method has no /clear lineage, so there the live id is the address. The guide's /clear text says the address survives and nothing moves. --- .../references/coordinator-loop.md | 4 +- .../references/messaging-and-gates.md | 3 +- src/cli/bundled-skill-guides.ts | 6 +- .../rpc/methods/orchestration/caller-show.ts | 25 +++++++- .../methods/orchestration/runs/runs.test.ts | 3 +- .../rpc/orchestration-caller-show.test.ts | 33 ++++++++++ .../rpc/orchestration-session-caller.test.ts | 4 +- .../NativeChatCopyAddressMenuItem.tsx | 16 +++-- .../NativeChatStructuredSession.tsx | 19 +++--- .../use-native-chat-context-menu.test.tsx | 3 +- .../use-native-chat-context-menu.tsx | 14 ++--- ...se-structured-native-chat-pane-commands.ts | 6 +- ...ured-session-orchestration-address.test.ts | 61 +++++++++++++++++++ ...tructured-session-orchestration-address.ts | 34 +++++++++++ src/shared/orchestration-caller-status.ts | 3 + .../rpc-contract/orchestration-params.ts | 5 ++ .../rpc-params-catalog.generated.ts | 2 + 17 files changed, 207 insertions(+), 34 deletions(-) create mode 100644 src/renderer/src/runtime/structured-session-orchestration-address.test.ts create mode 100644 src/renderer/src/runtime/structured-session-orchestration-address.ts diff --git a/skill-guides/orchestration/references/coordinator-loop.md b/skill-guides/orchestration/references/coordinator-loop.md index 4581a41fc82..59c40a10376 100644 --- a/skill-guides/orchestration/references/coordinator-loop.md +++ b/skill-guides/orchestration/references/coordinator-loop.md @@ -23,8 +23,8 @@ naming the `check` to run. A turn with no new Delivery is a checkpoint, not a failure. The compact guide's empty-wait enumeration applies when a turn arrives and a Dispatch you expected -has still not settled. Your address survives `/clear`: your Runs and unread -mail stay with the chat. +has still not settled. Your address survives `/clear`; nothing moves, and your +Runs and unread mail stay where they are. ## Ready waves diff --git a/skill-guides/orchestration/references/messaging-and-gates.md b/skill-guides/orchestration/references/messaging-and-gates.md index 607ad1d8316..dd39c302fb5 100644 --- a/skill-guides/orchestration/references/messaging-and-gates.md +++ b/skill-guides/orchestration/references/messaging-and-gates.md @@ -44,7 +44,8 @@ changes on `/clear`). `ORCA status --json` reports your own as `caller.address`; a `caller` with `live: false` carries the refusal that stops you acting as that session, and `null` means the shell has no orchestration identity. A user may copy a chat's address with its Copy Orchestration Address menu action. A chat's -address survives `/clear`, and its Runs and unread mail stay with it. A worker +address survives `/clear`: it names the conversation, so `caller.address` stays +the same while `caller.sessionId` becomes the new session, and nothing moves. A worker running as a chat is `session:` too; its internal `structworker_` mailbox key is never an address to hand out. `check` is the exception: it identifies its caller with `--terminal`, never `--from`. diff --git a/src/cli/bundled-skill-guides.ts b/src/cli/bundled-skill-guides.ts index c3c37cb856d..d4e6727ff18 100644 --- a/src/cli/bundled-skill-guides.ts +++ b/src/cli/bundled-skill-guides.ts @@ -69,10 +69,10 @@ const ORCA_PER_WORKSPACE_ENV_WINDOWS_SCRIPTS_REFERENCE_MARKDOWN = "# Windows loc const ORCHESTRATION_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- Your address is `caller.address` in `ORCA status --json`: `session:` in a\n chat (a chat worker too; it survives `/clear`), your handle in a terminal.\n Never name another agent with `--from`/`--terminal`.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task. Ask the coordinator only with the preamble's `ask`\n command, never a local question TUI; resume its message ID after a timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, as the dispatched worker, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` takes its caller from the environment in a chat or Orca\nterminal; elsewhere pass your own `--terminal `, never `--from`. It\nreturns the bound Run's oldest FIFO Delivery and replays that batch until\nacknowledged. Process every message: reply to questions, validate each\n`worker_done` against the expected active Dispatch, and decide each settled\nterminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect. A chat coordinator\nends its turn instead; Orca refuses its `check --wait` (`references/coordinator-loop.md`).\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n" // oxfmt-ignore -const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- Your address is `caller.address` in `ORCA status --json`: `session:` in a\n chat (a chat worker too; it survives `/clear`), your handle in a terminal.\n Never name another agent with `--from`/`--terminal`.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task. Ask the coordinator only with the preamble's `ask`\n command, never a local question TUI; resume its message ID after a timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, as the dispatched worker, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` takes its caller from the environment in a chat or Orca\nterminal; elsewhere pass your own `--terminal `, never `--from`. It\nreturns the bound Run's oldest FIFO Delivery and replays that batch until\nacknowledged. Process every message: reply to questions, validate each\n`worker_done` against the expected active Dispatch, and decide each settled\nterminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect. A chat coordinator\nends its turn instead; Orca refuses its `check --wait` (`references/coordinator-loop.md`).\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. Orca refuses it with `wait_requires_terminal` while the\nsession runs as a chat; only its terminal view may wait. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. Your address survives `/clear`: your Runs and unread\nmail stay with the chat.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. A chat's\naddress survives `/clear`, and its Runs and unread mail stay with it. A worker\nrunning as a chat is `session:` too; its internal `structworker_` mailbox\nkey is never an address to hand out. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\naddress, Dispatch capability, Task ID, and Dispatch ID. A worker running as a\nchat names itself `session:`, never a `structworker_` handle, and follows\nits preamble's chat forms below.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\nA chat skips them only while its turn has ended waiting for an answer.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\nA chat never blocks here: its shell tool would kill the call before the message\nID prints. It asks with the preamble's short `--timeout-ms`, ends its turn on a\ntimeout, and runs the printed resume command on the turn the reply starts.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" +const ORCHESTRATION_FULL_MARKDOWN = "---\nname: orchestration\ndescription: >-\n Coordinate supervised Orca workers: threaded messages, blocking ask/reply,\n task dispatch, worker_done/escalation waits, task DAGs, decision gates,\n coordinator loops, and decomposing work across agents. Use `orca-cli` for full\n ownership handoffs — \"hand off\", \"handoff\", \"handover\", \"give this to another\n agent\", \"another worktree\" — unless asked to supervise, monitor, or coordinate\n a DAG, and for terminal control, lightweight terminal prompts, shell commands,\n Orca worktree management, and reading or waiting on terminals.\n---\n\n# Orca orchestration\n\nOrchestration is Orca's structured coordination layer. It records who owns work,\nwhich attempt is authoritative, and when supervised work has settled.\n\n## Outcome\n\n**Result:** every in-scope Task has one explicit outcome and every settled worker\nterminal has a next owner or cleanup decision. **Next consumer:** the user who\nrequested supervision. **Done:** all expected Dispatches have settled, every\ndelivered message was processed before acknowledgment, each settled worker was\nreused, explicitly retained, or released, and the turn ends only when the report\nto that user names, per Task, its outcome, the evidence behind it, and any\nunresolved blocker.\n\n**Safe failure:** preserve work and authority and report the state as unknown or\n`unverifiable`. Only positive proof of exit authorizes stop, abandon, or retry,\nand only an accepted settlement authorizes release. Every other observation,\nabsence included, is a checkpoint.\n\n## Classify the role\n\n| Current context | Role | Route |\n| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |\n| The user explicitly asks to supervise, monitor, wait for results, track completion, coordinate a DAG, use a decision gate, or manage ask/reply | Coordinator | Use the supervised loop below |\n| The current prompt contains a live injected preamble with Task and Dispatch IDs | Dispatched worker | Follow the preamble and the worker obligations below |\n| The user asks to hand off ownership or start another agent/worktree without supervision | Handoff owner | Use `orca-cli`; create no Run, Task, or Dispatch and do not monitor completion |\n| A message carries a legacy authority label | Compatibility operator | Load the legacy contract reference before any lifecycle mutation |\n| No live preamble and no explicit supervision | Ordinary terminal agent | Do not emit lifecycle messages; use `orca-cli` for terminal/worktree work |\n\nModel or effort selection does not make a handoff supervised. Never substitute a\nnon-Orca subagent tool when Orca orchestration provenance was requested.\n\n## Authority and safety floor\n\n- A Run is a durable namespace and coordinator inbox; it does not schedule or\n place workers. A Task is work. A Dispatch is one authoritative Task attempt.\n- Lifecycle authority comes from the active Dispatch, not a terminal title,\n copied ID, old database row, provider transcript, or visible pane.\n- Workers use the exact executable, handle, capability, Task ID, and Dispatch ID\n in the live preamble. Never reconstruct, translate, or broaden those arguments.\n- After remote start, address the worker by Dispatch ID. The execution host owns\n process, filesystem, transcript, stop, and cleanup facts. Preserve the verdicts\n `live` / `unverifiable` / `exited`; contact loss is not process death.\n- Liveness is layered: `worker-list`'s `projection.liveness` is the fleet verdict\n for the agent; `worker-show`'s `observation.status` is PTY liveness only. A live\n terminal can still hold a dead or stuck agent.\n- Folder workspaces are valid; never require Git or assume a worktree.\n- Clients and remote servers update independently. Treat unknown optional fields\n as absent. A new stream operation requires advertised capability because old\n decoders may silently drop unknown opcodes. Never fall back to local execution\n when remote authority or capability is unproven.\n- Use the executable you used to run `skills get` for the entire run. In the\n examples below, replace `ORCA` with it; do not create a shell variable or run\n `ORCA` literally. If it fails, report that exact error instead of switching.\n- Your address is `caller.address` in `ORCA status --json`: `session:` in a\n chat (a chat worker too; it survives `/clear`), your handle in a terminal.\n Never name another agent with `--from`/`--terminal`.\n- A successful `orchestration send` proves durable enqueue; its wake or nudge is\n best-effort attention only and does not prove the recipient read or accepted it.\n\n## Worker obligations\n\nThe injected preamble is authoritative. A dispatched worker must:\n\n1. Do only the current Task. Ask the coordinator only with the preamble's `ask`\n command, never a local question TUI; resume its message ID after a timeout.\n2. Send heartbeats only at the cadence in the preamble. A heartbeat proves\n liveness, not completion.\n3. Read coordinator follow-ups at each natural checkpoint — before starting a\n new file, after a test run — and once more immediately before `worker_done`,\n with the preamble's own `check` command.\n4. Send `worker_done` exactly once, as the dispatched worker, with a\n three-sentence executive summary, both lifecycle IDs, and explicit\n `--outcome succeeded` or `--outcome failed`. Never encode failure only in prose.\n5. Append `--files-modified` and `--report-path` only with real values when\n applicable. After `worker_done`, end the dispatched turn and idle; do not poll\n or start new work.\n\nA direct user instruction after completion starts new user-owned work and takes\nprecedence over the idle rule. Do not reuse the settled lifecycle IDs.\n\n## Canonical supervised loop\n\nConfirm the runtime, bind one Run, and start the full independent wave before\nwaiting. `worker-start --spec` creates the Task and its attempt in one call:\n\n```text\nORCA status --json\nORCA orchestration run-create --objective \"\" --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent codex --json\nORCA orchestration worker-start --spec \"\" --worktree current --agent claude --json\nORCA orchestration check --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nIf `worker-start` exits non-zero, do not relaunch. Read the receipt's\n`failedStage` and `residualResources`, then load\n`references/recovery-and-cleanup.md`.\n\nUse `task-create` plus `worker-start --task ` for planned fan-out with\ndependencies or a retry of a known Task. Use dependencies only for real ordering\nand prefer parallel waves over chains deeper than three or four steps; nested\nworkers obey the depth limit, and a new Run does not reset the caller's depth.\n\nA consuming `check` takes its caller from the environment in a chat or Orca\nterminal; elsewhere pass your own `--terminal `, never `--from`. It\nreturns the bound Run's oldest FIFO Delivery and replays that batch until\nacknowledged. Process every message: reply to questions, validate each\n`worker_done` against the expected active Dispatch, and decide each settled\nterminal's next owner before the ack:\n\n```text\nORCA orchestration reply --id --body \"\" --json\nORCA orchestration worker-release --dispatch --json\nORCA orchestration check --ack --wait --types \"worker_done,escalation,question\" --timeout-ms 900000 --json\n```\n\nKeep waiting until every expected Dispatch settles. A timeout or empty result is\na checkpoint, not a failure. Do not stop, retry, release, or launch a duplicate\neditor without the positive proof `## Outcome` requires.\n\nAfter three consecutive empty waits, stop waiting blindly and enumerate with\n`ORCA orchestration worker-list --include-remote --json` (defaults to the bound\nRun; `--run ` overrides; the receipt's `scope` names which), acting on\neach row's `projection.attention` categories, `projection.attention.requiresAction`, and literal `projection.nextAction` argv.\nRows come newest first and page at 100: while `page.hasMore`, follow `page.nextCursor` with `--cursor `.\nA `none` `nextAction` has no argv to run: read `liveness.reason` and keep waiting\nwith `check --wait`. Absence never earns an argv; settlement and pending work still do.\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Then load `references/recovery-and-cleanup.md` and choose\n`worker-stop` or `worker-abandon` explicitly. `unverifiable` is absence,\nincluding when `worker-show` reports `agentWait` null. Absence never authorizes\nstop, abandon, retry, or release; keep waiting or inspect. A chat coordinator\nends its turn instead; Orca refuses its `check --wait` (`references/coordinator-loop.md`).\n\n`worker-start` is the normal path, composing placement, terminal readiness,\nprompt injection, and supervised resource ownership. `dispatch --inject` leaves\nan operator-created process unsupervised and is only for an expressiveness gap.\n\n## Task-spec contract\n\nEvery Task spec must be self-contained and name:\n\n- **Target:** the files, component, or environment in scope.\n- **Change:** the concrete result to produce.\n- **Constraints:** invariants, compatibility rules, and do-not-touch boundaries.\n- **Ownership:** what this worker may edit and any coordination boundary.\n- **Observable acceptance:** the test, output, or evidence that proves completion.\n\n## Completion accounting\n\nAfter an accepted success or failure report, immediately do exactly one:\n\n1. Reuse the same proven agent terminal for an immediate follow-up Dispatch.\n2. Record user-requested retention with `worker-retain`.\n3. Run `worker-release`.\n\nRelease is post-settlement cleanup, not cancellation. Only an accepted\nsettlement authorizes it; no other observation does. If release is uncertain,\nfollow its exact recovery receipt and never substitute `terminal close`.\n\nA valid `worker_done` settles the Task and Dispatch automatically; do not follow\nit with `task-update --status completed`. Enumerate the terminals still owing a\ndecision with `worker-list --run --terminal-state reclaimable --json`,\nand do not end the coordinator turn until it returns none.\n\n## Conditional references\n\nThis compact guide is sufficient for the normal local loop. At an action gate\nbelow, run `ORCA skills get orchestration --reference references/.md` and\nread only that document; `--references` lists the names. If the CLI rejects\n`--reference`, run `ORCA skills get orchestration --full` once instead: it\nreturns this exact kernel and every reference, so read only the named one. If an\nolder CLI rejects `--full`, keep this kernel's safety floor, use that command's\n`--help`, and never guess newer flags.\n\n| Action gate | Bundled reference |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |\n| Chat coordination, expanded DAG waves, launch model/effort, same-terminal reuse, or review ownership | `references/coordinator-loop.md` |\n| You are a dispatched worker and the live preamble does not answer your question, or `check` returned an error | `references/worker-contract.md` |\n| New worktree, exact workspace, SSH, WSL, or connected-server placement | `references/placement-and-remote.md` |\n| Inbox replay, follow-up messages, group addresses, or decision gates | `references/messaging-and-gates.md` |\n| Failed/stopped/unknown attempts, retry, stop, abandon, retain, or uncertain release | `references/recovery-and-cleanup.md` |\n| Custom argv or terminal topology that `worker-start` cannot express | `references/low-level-topology.md` |\n| Any legacy label, adopted Run, compatibility receipt, or takeover | `references/legacy-contract-migration.md` |\n\nRetired scheduler commands are not aliases for Run creation. Recovery commands\nmust provide their exact next action; follow it with the same selected executable.\n\n---\n\n# Bundled references\n\nThese references belong to the version-matched guide above. Read only the documents named by its action gates.\n\n\n\n# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. Orca refuses it with `wait_requires_terminal` while the\nsession runs as a chat; only its terminal view may wait. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. Your address survives `/clear`; nothing moves, and your\nRuns and unread mail stay where they are.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n\n\n\n# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n\n\n\n# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n\n\n\n# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. A chat's\naddress survives `/clear`: it names the conversation, so `caller.address` stays\nthe same while `caller.sessionId` becomes the new session, and nothing moves. A worker\nrunning as a chat is `session:` too; its internal `structworker_` mailbox\nkey is never an address to hand out. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n\n\n\n# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n\n\n\n# Recovery and cleanup\n\nLoad this reference only after a failed/stopped/unknown attempt, explicit retry\ndecision, stop/abandon request, retention request, or uncertain release.\n\n| Proven state | Safe action |\n| ----------------------- | ------------------------------------------------------------------ |\n| `ready` or active | Keep waiting; optionally read bounded output |\n| `failed` or `stopped` | Start a replacement with `--retry-of`; repeat placement explicitly |\n| `outcome_unknown` | Inspect, then choose `worker-stop` or explicit `worker-abandon` |\n| Accepted `worker_done` | Reuse, retain, or release |\n| Remote contact lost | Preserve `unverifiable`; do not stop or retry from absence alone |\n| `unverifiable` liveness | Keep waiting or inspect; never stop, abandon, retry, or release |\n| Proven `exited` agent | Enumerate with `worker-list`; follow its `nextAction` |\n\n## Inspect before acting\n\n```text\nORCA orchestration worker-list --run --json\nORCA orchestration worker-list --run --include-remote --json\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\n```\n\n`worker-list` is the enumerating command and the authority on agent liveness:\neach row carries `projection.liveness`, `projection.attention.categories`,\n`projection.attention.requiresAction`, and a literal `projection.nextAction`\nargv to run. Always scope it with `--run `; an unscoped list reports\nevery Dispatch this runtime has ever recorded and buries the live ones.\n`worker-show`'s `observation.status` is PTY liveness only, so a `live` terminal\nwhose agent died at a trust prompt still reads `live` there.\n\nWhen the two disagree, the fleet verdict decides — unless the fleet row is\n`unverifiable` for a reason that names a gap on this client rather than a fact\nabout the worker. `missing_status`, `host_unavailable`, and\n`capability_unsupported` are such gaps: the first means this runtime holds no\nstatus row, the second that it could not ask the execution host at all, and the\nthird that a stale peer answered but lacks the fleet-snapshot capability.\nAgainst any of them, a `worker-show` verdict sourced from the execution host is\nthe better evidence and outranks the row. Only `host_unavailable` is contact\nloss; the other two mean the host was never asked or answered without the\ncapability.\n\nThis never promotes absence. `unverifiable` from either command still authorizes\nnothing — only a positive `live` or `exited` verdict does.\n\nA worker started with `--on ` reads `unverifiable` until you\nenumerate with `--include-remote`, which asks its execution host for the\nverdict. Rows come newest first and past 100 the response pages, so follow\n`page.nextCursor` with `--cursor ` until `page.hasMore` is false.\n\n## Stall needs positive evidence\n\nLeave the wait only on positive proof the agent stopped: `exited` liveness, the\nworker's own observation of process exit, or a transcript whose final agent turn\nsent no `worker_done`. Only then choose `worker-stop` or `worker-abandon`.\n\n`unverifiable` is always absence — `missing_status`, `stale_status`,\n`restored_unconfirmed`, or a remote worker with no connection — and a null\n`agentWait` or an unchanged `worker-read` tail is that same absence seen again.\nAbsence never authorizes stop, abandon, retry, or release: keep waiting, or\ninspect until you hold one of the positive signals above. A `nextAction` that\nnames an inspecting command is asking for evidence, not for cleanup.\n\n`worker-read --source auto` uses a proven provider transcript when available and\notherwise returns bounded terminal output with a typed `fallbackReason`.\nContinue with its top-level cursor, which is pinned to that source. If Orca\nreports `source_changed`, restart without the old cursor. A bounded initial\ntranscript tail can return an EOF cursor that follows only newly appended records;\nread `contentComplete`, `clipping`, and `warnings` before assuming omitted older\nrecords are pageable. Never guess a provider session ID, transcript path, or\nremote terminal handle.\n\n## Was the mutation applied?\n\nWhen a mutation's response was lost and named no Dispatch, do not replay blind.\nEvery orchestration mutation accepts `--retry-request `, which reuses one\noperation identity so Orca can replay, join, or recover it instead of starting a\nduplicate. Ask what happened first:\n\n```text\nORCA orchestration request-show --request --json\n```\n\n`completed` means the mutation already took effect; read its recorded receipt\ninstead of rerunning. `pending` means the original mutation is still running or\nOrca restarted before recording its outcome; replay the original command with\n`--retry-request `. `absent` means this runtime holds no receipt\nunder your caller identity — that is not proof nothing happened, so inspect the\naffected Task, Dispatch, and terminal before deciding whether to retry.\n\nWhen a worker's terminal accepted input but the submit is unconfirmed, use\n`terminal send --wait-submit `: it observes the accepted prompt for that\nlong and, on timeout, returns the input-accepted receipt without resending.\n\n## Refused starts\n\n`dispatch` and `worker-start` refuse the following preflight cases with a stable\n`error.code`; read it before choosing a recovery, and treat `error.data.nextSteps`\nas the exact recovery text. Older hosts may omit `data`, so treat every field as\noptional.\n\n| Code | Meaning | Recovery |\n| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `task_not_found` | No Task with that id, or not in the bound Run (`data.taskId`, `data.runId`) | Check `task-list --json`; create the Task with `task-create` if it does not exist |\n| `task_not_startable` | Task cannot start now: not `ready`, or invalid `--retry-of` (`data.status`, `data.unmetDependencies`, `data.retryOf`) | Wait for running dependencies with `check --wait`; retry or unblock failed ones; inspect `dispatch-show` if already dispatched |\n| `inject_rejected` | `--inject` refused because no recognized agent runs in the target (`data.terminal`, `data.reason`) | Start a recognized agent there or pick another terminal; or dispatch without `--inject` and use `terminal send` |\n| `runtime_error` | Any other failure, including a target terminal that already owns an active Dispatch | Read the message, inspect state, and do not retry unchanged |\n\n## Retry, stop, and abandon\n\nRetry only a positively proven failed or stopped attempt. Name the failed Task\nwith `--task`, since `--spec` creates a new one. Placement is never silently\ninherited:\n\n```text\nORCA orchestration worker-start --task --retry-of --worktree --agent --json\n```\n\nAfter three consecutive failures for one Task, its dispatch context\ncircuit-breaks and the Task is failed. Do not route around that boundary with a\nnew Run or an unrelated Dispatch.\n\nFor `outcome_unknown`, inspect first, then make an explicit choice:\n\n```text\nORCA orchestration worker-stop --dispatch --json\nORCA orchestration worker-abandon --dispatch --json\n```\n\n`worker-stop` closes only the exact proven supervised agent terminal. It never\ndeletes the worktree, setup terminal, configured tabs, or unrelated processes.\n`worker-abandon` fences orchestration while accepting that resources may remain\nlive; it performs no remote, process, or filesystem action.\n\n## Retain and release\n\n```text\nORCA orchestration worker-retain --dispatch --json\nORCA orchestration worker-release --dispatch --json\n```\n\nRetain only when the user explicitly wants the settled terminal kept live.\nRelease works after succeeded and failed reports, archives readable output, and\ncloses only the exact terminal owned by that settled Dispatch. Replays may call\nrelease again safely. Reused, pre-existing, setup, coordinator, active,\nuser-taken-over, and unproven terminals are retained.\n\nA `worker-start` that failed before its agent was ready still owns the terminal\nit created. Its receipt names `worker-release`, and `worker-list` reports that\nrow as `reclaimable`; release it there rather than closing the terminal by hand.\n\nNever release because of timeout, TUI idle, heartbeat, status, question,\nescalation, or stale/rejected completion. If the receipt says `release_pending`\nor `release_unknown`, follow its exact recovery action. Never substitute\n`terminal close`.\n\n`orchestration reset` is destructive recovery. Do not run it during active\ncoordination unless the user explicitly abandons that state.\n\n\n\n# Worker contract\n\nThe injected preamble is authoritative. Copy its command rather than\nreconstructing flags. In particular, preserve the exact executable, worker\naddress, Dispatch capability, Task ID, and Dispatch ID. A worker running as a\nchat names itself `session:`, never a `structworker_` handle, and follows\nits preamble's chat forms below.\n\n## Heartbeat\n\nSend heartbeats only at the cadence required by the live preamble. Skip them\nwhile blocked inside `ask` or `check --wait`; those calls are liveness signals.\nA chat skips them only while its turn has ended waiting for an answer.\n\n```text\nORCA orchestration send --from --dispatch-capability --type heartbeat --subject \"alive\" --task-id --dispatch-id --phase \"\"\n```\n\nUse typed lifecycle flags, not a hand-written JSON payload. A heartbeat proves\nliveness, never completion.\n\n## Ask and resume\n\nUse Orca `ask` whenever the coordinator must answer. Never open a local question\nTUI the coordinator cannot answer.\n\n```text\nORCA orchestration ask --from --dispatch-capability --question \"\" --options \",\" --timeout-ms 600000\n\nORCA orchestration ask --from --dispatch-capability --resume --timeout-ms 600000\n```\n\nA timeout or disconnect leaves the original question pending. Resume its\nmessage ID; do not create a duplicate question.\n\nA chat never blocks here: its shell tool would kill the call before the message\nID prints. It asks with the preamble's short `--timeout-ms`, ends its turn on a\ntimeout, and runs the printed resume command on the turn the reply starts.\n\n## Reading coordinator follow-ups\n\nThe coordinator steers a running worker with `send --to dispatch:`. That\nenqueue is durable but does not interrupt you, so nothing arrives unless you\nlook:\n\n```text\nORCA orchestration check --terminal --json\n```\n\nRun it at each natural checkpoint — before starting a new file, after a test\nrun — and once more immediately before `worker_done`, so a redirect or a\ncancellation lands before the Task settles. `check` names its caller with\n`--terminal`, never `--from`. Stop checking after `worker_done`.\n\nIf `check` returns `consumer_fenced`, this process no longer owns its Dispatch:\nthe Attempt was re-attached to another worker or settled without you. Stop, do\nnot send `worker_done`, and do not retry the check. An empty `check` never means\nyou were replaced; `consumer_fenced` is the only way you learn that.\n\n## Escalation\n\nEscalate only before completion and only when the coordinator must intervene:\n\n```text\nORCA orchestration send --from --dispatch-capability --type escalation --subject \"Blocked: \" --body \"
\" --task-id --dispatch-id \n```\n\n## Completion\n\nSend exactly one terminal report. `--body` is three sentences: what changed,\nwhat was found, and what remains. Use `--outcome failed` when the requested work\nis not complete; never hide failure in prose or silently exit.\n\nAppend `--files-modified` or `--report-path` only when applicable, using actual\npaths. Do not send documentation placeholders as metadata.\n\n```text\nORCA orchestration send --from --dispatch-capability --type worker_done --subject \"\" --body \"\" --task-id --dispatch-id --outcome succeeded\n```\n\nAfter `worker_done`, end the dispatched turn and idle. Do not poll, close your\nown terminal, or begin unrelated work. A later direct user instruction is new\nuser-owned work and must not reuse settled lifecycle IDs; a supervised follow-up\narrives with a fresh preamble and Task block.\n" // oxfmt-ignore -const ORCHESTRATION_COORDINATOR_LOOP_REFERENCE_MARKDOWN = "# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. Orca refuses it with `wait_requires_terminal` while the\nsession runs as a chat; only its terminal view may wait. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. Your address survives `/clear`: your Runs and unread\nmail stay with the chat.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n" +const ORCHESTRATION_COORDINATOR_LOOP_REFERENCE_MARKDOWN = "# Coordinator loop\n\nLoad this reference for coordinating from a chat session, expanded DAG waves,\nper-invocation launch preferences, same-terminal reuse, or review ownership. The compact guide remains the source\nof truth for the loop order and completion boundary.\n\n## Coordinating from a chat session\n\nWhen `ORCA status --json` reports `caller.kind` `session`, you coordinate from a\nchat. Never block in `check --wait`: your shell tool has its own timeout, and\nOrca wakes you instead. Orca refuses it with `wait_requires_terminal` while the\nsession runs as a chat; only its terminal view may wait. When messages reach your Run, Orca starts a new turn in\nthis chat once you are idle, saying `You have orchestration message(s)` and\nnaming the `check` to run.\n\n1. Bind one Run and start the full independent wave.\n2. End your turn.\n3. On each such turn run the `check` it names, without `--wait`. Process every\n message as the compact guide requires, then acknowledge with\n `ORCA orchestration check --ack --json`, which also returns the\n next batch. Repeat until no Delivery is returned.\n4. End your turn again. When every expected Dispatch has settled, report.\n\nA turn with no new Delivery is a checkpoint, not a failure. The compact guide's\nempty-wait enumeration applies when a turn arrives and a Dispatch you expected\nhas still not settled. Your address survives `/clear`; nothing moves, and your\nRuns and unread mail stay where they are.\n\n## Ready waves\n\nCreate independent Tasks before the first wait. Encode only real dependencies,\nthen use the ready view as external memory:\n\n```text\nORCA orchestration task-create --spec \"\" --deps --json\nORCA orchestration task-list --ready --brief --json\n```\n\n`--brief` collapses whitespace and caps echoed specs at 160 characters;\n`spec_truncated` identifies shortened rows. Omit it when full specs are needed or\nwhen an older CLI rejects the flag. A nested worker must respect\n`nested_worker_depth_exceeded`; creating another Run does not reset depth.\n\n## Launch preferences\n\nFor a fresh Claude, Codex, Cursor, Antigravity, or Muse terminal, `--model`\naccepts an opaque provider model ID. Pass it only when the user named a model;\notherwise omit it so the worker inherits the user's configured agent default.\nAdd `--effort` only when that model supports it:\n\n```text\nORCA orchestration worker-start --task --worktree current --agent claude --model opus --effort high --json\nORCA orchestration worker-start --task --worktree current --agent muse --model muse-spark-1.3 --json\n```\n\nOther agents, including `opencode`, reject `--model`; they run the model set in\ntheir own config, so a coordinator wanting a same-model opencode worker relies\non that config.\n\n`--effort` requires `--model`; neither option combines with `--terminal`. A\nconnected worker server must advertise launch-preference support before Orca\nforwards either field. Compare `launch.requested` with `launch.effective`; never\nclaim a model or effort from requested arguments alone.\n\n## Reuse after settlement\n\nChoose the terminal's next owner before acknowledging the Delivery. When the\nsame exact agent has immediate follow-up work, recover the proven handle and\ntransfer cleanup ownership to the new Dispatch:\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-start --task --terminal --json\n```\n\nOtherwise explicitly retain or release the settled worker. Do not leave it live\nonly to inspect output; archived output remains available through `worker-read`.\n\n## Review ownership\n\nA review-only `worker_done` authorizes synthesis of findings, not coordinator\nfile edits. Dispatch or hand off fixes unless the user explicitly assigned them\nto the coordinator. If the user's plan names a next owner, post-review fixes and\nPR preparation remain with that owner; the coordinator routes and synthesizes.\n" // oxfmt-ignore const ORCHESTRATION_LEGACY_CONTRACT_MIGRATION_REFERENCE_MARKDOWN = "# Legacy contract migration\n\nLoad this reference only for an authority label, adopted Run, compatibility or\nrecovery receipt, or explicit legacy takeover. A newly created attempt always\nuses the current grammar.\n\n## Authority labels\n\n- `[LEGACY COMPATIBILITY]` is live and attested. Run only the exact supported\n command printed with the message, using the same selected executable and\n arguments supplied by the original prompt.\n- `[LEGACY RECOVERY REPLAY — MAY HAVE BEEN SEEN]` is one bounded,\n at-least-once cutover replay. Process it idempotently and acknowledge only\n through the exact displayed guidance.\n- `[LEGACY READ-ONLY]` is inspection-only. It has no reply, acknowledgment, or\n lifecycle mutation.\n- An unlabeled current message uses the current guide and grammar.\n\nAn explicitly selected current Run, attested current binding, current Dispatch,\nor federated attachment takes precedence over legacy fallback. A retained\nadoption record alone does not grant mutation authority. If liveness, principal\nownership, capability, or the exact legacy contract is unproven, degrade to\nread-only inspection and never fall back to local execution.\n\nAdoption preserves the live agent process, PTY/session, terminal handle,\ntab/pane, worktree or folder workspace, Task, and Dispatch. It never restarts or\nreplaces the worker and never revives the retired scheduler. Loss of lifecycle\nauthority does not invalidate the existing process, assignment, or filesystem\nwork. Exact recovery may restore the same PTY once in its original inactive\nbackground tab; it must not spawn, write, signal, stop, switch, focus, split, or\ninject a terminal.\n\n## Compatibility recovery\n\nWhen a compatibility response returns structured next-step arguments, execute\nthose exact arguments with the same selected CLI executable. Do not translate\nfrom memory, broaden the recipient, or retry as a current mutation unless the\nreceipt explicitly authorizes it.\n\nA pending ask, reply, final Dispatch settlement, and consuming check have\ndurable recovery identities. Heartbeat and escalation remain at-least-once\nacross a manual contract-boundary retry. If an ask may already have been\nanswered, run the exact non-consuming recovery check printed by Orca before\ncreating any new question. Never guess among identical question threads.\n\nOn packaged Windows, a legacy ask uses a two-step commit/resume protocol. The\ninitial command commits the question, prints its exact\n`ask --resume ` command, and exits with launcher status `75`. Run\nthat exact resume after the launcher or update boundary. For an attested WSL\nlaunch, preserve the printed `orca-ide` executable and distro route. Older WSL\nworkers without launch proof remain lifecycle read-only even while their\nterminal and filesystem work continue.\n\n## Read-only inspection and takeover\n\nRead-only inspection does not consume mail:\n\n```text\nORCA orchestration run-list --json\nORCA orchestration run-show --id run_legacy_local --json\nORCA orchestration run-show --id --json\nORCA orchestration task-list --run --json\nORCA orchestration inbox --full --json\nORCA orchestration check --terminal --peek --format --json\nORCA terminal read --terminal --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\n```\n\n`run_legacy_local` is an empty audit tombstone after adoption. Find the ordinary\nRun whose objective is `Recovered orchestration work from a contract update`.\n\nOnly when the original coordinator is unavailable or cannot prove retained\nauthority may a new live coordinator take over from its own terminal:\n\n```text\nORCA orchestration run-use --id --takeover-legacy --json\nORCA orchestration check --run --json\n```\n\nTakeover binds the authenticated invoking terminal; `--from` cannot nominate\nanother coordinator. It fences only the old coordinator and moves pending mail\ninto current Run delivery. It preserves live workers, Tasks, Dispatches, processes, and files.\nNever take over while the original coordinator is actively coordinating.\n\nDo not launch a replacement editor merely because Orca updated or authority is\nunclear. Keep the original worker as the only editor until a stable handoff\npoint, then use a fresh current Dispatch in a conflict-free placement.\n" @@ -81,7 +81,7 @@ const ORCHESTRATION_LEGACY_CONTRACT_MIGRATION_REFERENCE_MARKDOWN = "# Legacy con const ORCHESTRATION_LOW_LEVEL_TOPOLOGY_REFERENCE_MARKDOWN = "# Low-level topology\n\nLoad this reference only when `worker-start` cannot express required custom argv\nor terminal topology. It is not the normal supervised loop and is never a full\nhandoff recipe.\n\n```text\nORCA terminal create --worktree active --title --command \"\" --json\nORCA terminal wait --terminal --for tui-idle --timeout-ms 60000 --json\nORCA orchestration dispatch --task --to --inject --json\n```\n\nWait for readiness only when startup could lose injected input. Prefer\nagent-first `worker-start` whenever its argv and topology are sufficient.\n\n`dispatch --inject` creates authoritative Task/Dispatch context but deliberately\nkeeps an operator-created process unsupervised: it creates no supervised worker\nresource row. `worker-show`, `worker-read`, and `worker-list` report the lane as\n`unsupervised`; `worker-stop` and `worker-abandon` do not close that process, and\nsettled retain/release take no process action.\n\nUse `worker-start --terminal ` when lifecycle ownership of an existing\nagent terminal is required. Never imply that low-level dispatch retroactively\nowns a process, never use it to route around the nested-depth limit, and never\nuse it for an ownership handoff.\n" // oxfmt-ignore -const ORCHESTRATION_MESSAGING_AND_GATES_REFERENCE_MARKDOWN = "# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. A chat's\naddress survives `/clear`, and its Runs and unread mail stay with it. A worker\nrunning as a chat is `session:` too; its internal `structworker_` mailbox\nkey is never an address to hand out. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n" +const ORCHESTRATION_MESSAGING_AND_GATES_REFERENCE_MARKDOWN = "# Messaging and gates\n\nLoad this reference for inbox replay, attempt-specific guidance, group\naddresses, blocking questions, or coordinator-managed DAG decisions.\n\nA successful `send` proves durable enqueue. Wake and nudge are best-effort\nattention only: neither proves the recipient read the message, began a turn, or\naccepted steering.\n\n## Coordinator delivery loop\n\n`check` names its caller with `--terminal ` and is the only verb that\nrejects `--from`. Omit `--terminal` in a chat session, whose caller is always\n`session:`, and inside an Orca terminal, where Orca resolves the caller.\nPass your own handle explicitly from anywhere else, including a dispatched\nworker reading coordinator follow-ups. A chat coordinator never waits: it\nchecks without `--wait` on each turn Orca starts for new mail.\n\nA consuming coordinator `check` returns the bound Run's oldest FIFO Delivery,\nup to 50 messages, and replays that exact batch until acknowledged. Process\nevery row and required terminal ownership decision before `--ack`. Type filters\ndecide when a waiter wakes; they do not authorize skipping older actionable\nmail. A Delivery therefore always carries the whole FIFO batch whatever its\ntypes, and a `check` without `--wait` hands that batch over unfiltered.\n`--peek` and `--all` are read-only inspection, not progress through the\ncoordinator inbox.\n\nAn empty wait or timeout is a checkpoint. Continue rolling waits until every\nexpected Dispatch settles. Heartbeat or visible activity means alive, not done.\n\n## Addresses\n\nUse a stable Dispatch address for attempt-specific coordinator guidance:\n\n```text\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\n```\n\nDo not substitute a remote terminal handle. Omit `--from` for ordinary\ncoordinator calls; a dispatched worker instead copies the exact `--from` and\ncapability arguments in its preamble. Any live chat session on this host is\nreachable at `session:`, its Orca session id, never the provider's id (it\nchanges on `/clear`). `ORCA status --json` reports your own as `caller.address`;\na `caller` with `live: false` carries the refusal that stops you acting as that\nsession, and `null` means the shell has no orchestration identity. A user may\ncopy a chat's address with its Copy Orchestration Address menu action. A chat's\naddress survives `/clear`: it names the conversation, so `caller.address` stays\nthe same while `caller.sessionId` becomes the new session, and nothing moves. A worker\nrunning as a chat is `session:` too; its internal `structworker_` mailbox\nkey is never an address to hand out. `check` is the exception: it identifies\nits caller with `--terminal`, never `--from`.\n\nGroup addresses include `@all`, `@idle`, `@claude`, `@codex`, `@opencode`,\n`@gemini`, `@droid`, `@grok`, `@cursor`, and `@worktree:`. Every group but\n`@worktree:` means the live Dispatches of the sender's own Run. Mail goes\nto each `dispatch:` mailbox, except a worker coordinating a child Run\nreceives it in that `run:` mailbox. A sender bound to no Run is refused;\n`--run` must match the group audience and never grants membership.\nA Run group excludes its owning coordinator; a worker raising a blocker sends\nto `run:`. A worker that created its own Run addresses that Run's workers,\nnot its siblings. `@worktree:` reaches matching workspace terminals,\nincluding coordinators. Use groups only for intentional fan-out status or\nquestions. `worker_done`, heartbeat, and other\nDispatch lifecycle messages never target groups.\n\n## Questions and gates\n\nA worker uses `ask`; its timeout leaves one durable question pending, which the\nworker resumes by message ID. The coordinator answers that message with `reply`.\n\nUse a gate only for a coordinator-owned Task-DAG decision:\n\n```text\nORCA orchestration gate-create --task --question \"\" --options --json\nORCA orchestration gate-resolve --id --resolution \"\" --json\nORCA orchestration gate-list --task --json\n```\n\nPass `json_array` using the quoting rules of the active shell; do not copy POSIX\nsingle-quote syntax into PowerShell or `cmd.exe`.\n\nDo not create a gate merely to answer a worker's `ask`.\n" // oxfmt-ignore const ORCHESTRATION_PLACEMENT_AND_REMOTE_REFERENCE_MARKDOWN = "# Placement and remote execution\n\nLoad this reference before creating a new worktree or placing work through SSH,\nWSL, or another connected Orca server.\n\n## Placement choices\n\nA fresh worker means a fresh agent terminal, not a new Git worktree. Use the\ncurrent or an exact existing workspace by default. Create a worktree only when\nthe user requested one or a concrete checkout or filesystem conflict makes\nsharing unsafe.\n\n```text\n# Current workspace; setup is not rerun.\nORCA orchestration worker-start --task --worktree current --agent codex --json\n\n# Stacked child worktree.\nORCA orchestration worker-start --task --worktree new-child --name --agent codex --setup run --json\n\n# Independent top-level worktree.\nORCA orchestration worker-start --task --worktree new-top-level --name --agent codex --setup run --json\n```\n\nCurrent and exact existing workspaces create a fresh terminal unless\n`--terminal` is explicit. Folder workspaces are first-class; do not invoke Git\nor require worktree lineage when the selected workspace is a folder.\n\nRegister a folder workspace through project setup. `repo add --path `\nrequires a valid Git repository and rejects a plain directory:\n\n```text\nORCA project setup-existing-folder --project --host --path --kind folder --json\n```\n\nThen place work on the returned workspace with an exact selector. A worktree\nselector needs the full `::` value Orca returned, passed as\n`id:`; a bare repo id is not a worktree id. `new-child` and\n`new-top-level` are worktree creation and do not apply to a folder.\n\nNew worktrees use agent-first creation and run setup by default. Preserve the\nrepository's startup policy: `start-immediately` can report setup as `running`,\nwhile `wait-for-setup` gates prompt delivery on success. Orca lineage, Git base,\nfilesystem isolation, coordination parentage, UI grouping, and execution host\nare separate decisions.\n\n## Connected servers\n\nThe Run and Tasks remain authoritative on the current server. `--on` selects\nonly the worker's execution server and appears only on `worker-start`:\n\n```text\nORCA orchestration worker-start --task --on --worktree new-top-level --repo --name --agent codex --setup run --json\n```\n\nRemote `current` and `new-child` are invalid because they are ambiguous across\nservers. Use an exact discovered remote workspace, or `new-top-level` with an\nexact remote repository selector. After start, route every follow-up, read,\nstop, and cleanup by Dispatch ID; never repeat `--on` or substitute a remote\nterminal handle.\n\n```text\nORCA orchestration worker-show --dispatch --json\nORCA orchestration worker-read --dispatch --limit 50 --json\nORCA orchestration send --to dispatch: --subject \"Follow-up\" --body \"\" --json\nORCA orchestration worker-list --run --include-remote --json\n```\n\n`worker-list` reads local fleet state only; enumerate remote workers with\n`--include-remote` or every one of them reads `unverifiable`. Scope every list\nwith `--run `: unscoped, it reports every Dispatch this runtime has\nrecorded, and the workers you are waiting on are lost in that history.\n\n## Execution-host and mixed-version floor\n\nThe execution host owns process, filesystem, transcript, stop, and cleanup\nfacts. Render only `live`, `unverifiable`, or `exited`. Connection loss, relay\nabsence, missing client inventory, or timeout yields `unverifiable`, never\nsynthetic exit and never a client-local substitute action.\n\nClients and servers update independently. Optional response fields may be\nabsent. Forward model/effort, transcript reads, cleanup, or another new remote\noperation only when the peer advertises the relevant capability; unknown stream\nopcodes can be silently dropped. A narrow unsupported response may degrade to a\ndocumented older path, but must not broaden the target or cross the execution\nboundary. Changing host-published content reaches old clients even without a\nwire-shape change, so preserve established semantics or negotiate the behavior.\n\nFor WSL, use the exact executable and arguments returned by Orca so the distro\nand packaged launcher remain bound. Do not translate a printed `orca-ide`\nrecovery command into a PATH-resolved local command.\n" diff --git a/src/main/runtime/rpc/methods/orchestration/caller-show.ts b/src/main/runtime/rpc/methods/orchestration/caller-show.ts index cd5c5608329..af99ac440a6 100644 --- a/src/main/runtime/rpc/methods/orchestration/caller-show.ts +++ b/src/main/runtime/rpc/methods/orchestration/caller-show.ts @@ -1,9 +1,15 @@ import type { OrchestrationCallerAddress, - OrchestrationCallerShowResult + OrchestrationCallerShowResult, + OrchestrationSessionAddressResult } from '../../../../../shared/orchestration-caller-status' import type { OrchestrationCompatibilityEvidence } from '../../../../../shared/orchestration-compatibility-evidence' +import { sessionOrchestrationActor } from '../../../../../shared/orchestration-actor' +import { ORCHESTRATION_SESSION_CALLER_ERROR_CODES as CODES } from '../../../../../shared/orchestration-session-caller-codes' +import { SessionAddressParams } from '../../../../../shared/rpc-contract/orchestration-params' import type { OrcaRuntimeService } from '../../../orca-runtime' +import { OrchestrationError } from '../../../orchestration/orchestration-error' +import { sessionOrchestrationIdentity } from '../../../orchestration/structured-session-mail-address' import { defineMethod } from '../../core' export const ORCHESTRATION_CALLER_METHODS = [ @@ -29,6 +35,23 @@ export const ORCHESTRATION_CALLER_METHODS = [ } return { caller: resolveTerminalCaller(runtime, orchestrationCompatibilityEvidence) } } + }), + defineMethod({ + name: 'orchestration.sessionAddress', + params: SessionAddressParams, + // Why host-side: the address is derived from the session records, which only the host holds, the + // same derivation a verb acting as that session binds to. + handler: (params, { runtime }): OrchestrationSessionAddressResult => { + const actor = sessionOrchestrationActor(params.sessionId) + if (!actor) { + throw new OrchestrationError( + CODES.unknown, + `${params.sessionId} is not an Orca agent session id.`, + { effectsApplied: false } + ) + } + return { address: sessionOrchestrationIdentity(actor.id, runtime.getOrchestrationDb()).actor } + } }) ] diff --git a/src/main/runtime/rpc/methods/orchestration/runs/runs.test.ts b/src/main/runtime/rpc/methods/orchestration/runs/runs.test.ts index f729db58b93..80ce46b2d73 100644 --- a/src/main/runtime/rpc/methods/orchestration/runs/runs.test.ts +++ b/src/main/runtime/rpc/methods/orchestration/runs/runs.test.ts @@ -26,8 +26,9 @@ describe('orchestration RPC methods', () => { it('registers all expected methods', () => { const registry = buildRegistry(ORCHESTRATION_METHODS) - expect(registry.size).toBe(42) + expect(registry.size).toBe(43) expect(registry.has('orchestration.callerShow')).toBe(true) + expect(registry.has('orchestration.sessionAddress')).toBe(true) expect(registry.has('orchestration.workerRelease')).toBe(true) expect(registry.has('orchestration.workerRetain')).toBe(true) expect(registry.has('orchestration.workerList')).toBe(true) diff --git a/src/main/runtime/rpc/orchestration-caller-show.test.ts b/src/main/runtime/rpc/orchestration-caller-show.test.ts index 7ce21959f36..dc61eac3dec 100644 --- a/src/main/runtime/rpc/orchestration-caller-show.test.ts +++ b/src/main/runtime/rpc/orchestration-caller-show.test.ts @@ -148,6 +148,39 @@ describe('orchestration.callerShow: the caller learns its own address from the h expect(resolvePane).toHaveBeenCalledTimes(3) }) + it('gives the menu the exact address each session of a cleared chat acts as', async () => { + const cleared = sessionRecord(SESSION_X) + h.records.set(SESSION_X, { + ...cleared, + conversationCommand: { + command: 'clear', + state: 'completed', + replacementSessionId: SESSION_Y, + operationId: 'op', + callerKey: 'caller', + phase: 'committed' + } + }) + + for (const sessionId of [SESSION_X, SESSION_Y]) { + const shown = resultOf( + await h.dispatch(orchestrationRequest('orchestration.sessionAddress', { sessionId })) + ) + const acting = resultOf(await h.dispatch(callerShow({ sessionId }))) + // One derivation: whatever address the host gives the conversation, the copy is the actor's. + expect(shown.address).toMatch(/^session:/) + expect(acting.caller).toMatchObject({ kind: 'session', address: shown.address }) + } + }) + + it('refuses an address for an id that is not an Orca session id', async () => { + const response = await h.dispatch( + orchestrationRequest('orchestration.sessionAddress', { sessionId: 'not an id' }) + ) + + expect(response).toMatchObject({ ok: false, error: { code: CODES.unknown } }) + }) + it('answers null for a caller whose environment carries no identity', async () => { const response = await h.dispatch(callerShow({})) diff --git a/src/main/runtime/rpc/orchestration-session-caller.test.ts b/src/main/runtime/rpc/orchestration-session-caller.test.ts index 310c8bf30a9..e4960731974 100644 --- a/src/main/runtime/rpc/orchestration-session-caller.test.ts +++ b/src/main/runtime/rpc/orchestration-session-caller.test.ts @@ -92,8 +92,8 @@ describe('orchestration session callers at the dispatch entry', () => { .map((method) => method.name) .sort() - // The population: 42 registered methods, 21 of which carry a party-naming field. - expect(registry.size).toBe(42) + // The population: 43 registered methods, 21 of which carry a party-naming field. + expect(registry.size).toBe(43) expect(partyNaming).toHaveLength(21) expect(partyNaming).toEqual( [ diff --git a/src/renderer/src/components/native-chat/NativeChatCopyAddressMenuItem.tsx b/src/renderer/src/components/native-chat/NativeChatCopyAddressMenuItem.tsx index ffbb2b0c86e..cb012a428d3 100644 --- a/src/renderer/src/components/native-chat/NativeChatCopyAddressMenuItem.tsx +++ b/src/renderer/src/components/native-chat/NativeChatCopyAddressMenuItem.tsx @@ -4,13 +4,21 @@ import { DropdownMenuItem } from '@/components/ui/dropdown-menu' import { translate } from '@/i18n/i18n' /** - * Copies the session's orchestration address (`session:`), the Orca-minted id other agents - * message it by. Distinct from "Copy Session ID", which copies the provider's id and changes on - * `/clear`. + * Copies the chat's orchestration address (`session:`), the one other agents message it by, + * resolved when selected because `/clear` keeps the conversation's address, not the live id. + * Distinct from "Copy Session ID", which copies the provider's id and changes on `/clear`. */ -export function NativeChatCopyAddressMenuItem({ address }: { address: string }): React.JSX.Element { +export function NativeChatCopyAddressMenuItem({ + resolveAddress +}: { + resolveAddress: () => Promise +}): React.JSX.Element { const copyAddress = async (): Promise => { try { + const address = await resolveAddress() + if (!address) { + throw new Error('no orchestration address') + } await window.api.ui.writeClipboardText(address) toast.success( translate( diff --git a/src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx b/src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx index 7f85fa0a318..e36497d3a5e 100644 --- a/src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx +++ b/src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx @@ -2,10 +2,8 @@ import { useMemo, useRef, useState } from 'react' import { encodeAgentSessionQuestionAnswers } from '../../../../shared/agent-session-question-answer' import { dispatchStructuredAgentSessionComposerCommand } from '../../../../shared/structured-agent-session-composer' import { structuredAgentSessionPaneKey } from '../../../../shared/structured-agent-session-projection' -import { - formatOrchestrationActor, - sessionOrchestrationActor -} from '../../../../shared/orchestration-actor' +import { sessionOrchestrationActor } from '../../../../shared/orchestration-actor' +import { resolveStructuredSessionOrchestrationAddress } from '../../runtime/structured-session-orchestration-address' import type { NativeChatLiveSession } from './use-native-chat-live-session' import { NativeChatApprovalCard } from './NativeChatApprovalCard' import { NativeChatComposer, type NativeChatComposerHandle } from './NativeChatComposer' @@ -64,10 +62,13 @@ export function NativeChatStructuredSession( ) const rootRef = useRef(null) const composerRef = useRef(null) - const orchestrationAddress = useMemo(() => { - const actor = sessionOrchestrationActor(props.sessionId) - return actor ? formatOrchestrationActor(actor) : undefined - }, [props.sessionId]) + const resolveOrchestrationAddress = useMemo( + () => + sessionOrchestrationActor(props.sessionId) + ? () => resolveStructuredSessionOrchestrationAddress(props.target, props.sessionId) + : undefined, + [props.sessionId, props.target] + ) const paneCommands = useStructuredNativeChatPaneCommands({ tabId: props.tabId, groupId: props.groupId, @@ -75,7 +76,7 @@ export function NativeChatStructuredSession( rootRef, composerRef, terminalPaneActions: props.contextMenuActions, - orchestrationAddress + resolveOrchestrationAddress }) const session = useMemo( () => ({ diff --git a/src/renderer/src/components/native-chat/use-native-chat-context-menu.test.tsx b/src/renderer/src/components/native-chat/use-native-chat-context-menu.test.tsx index 26ec5550c21..78a1b783935 100644 --- a/src/renderer/src/components/native-chat/use-native-chat-context-menu.test.tsx +++ b/src/renderer/src/components/native-chat/use-native-chat-context-menu.test.tsx @@ -93,7 +93,8 @@ function Harness({ onSwitchToTerminal, showTerminalPaneActions: !structured, workspaceLayout: structured ? { unifiedTabId: 'chat-tab', groupId: 'group-1' } : undefined, - orchestrationAddress, + resolveOrchestrationAddress: + orchestrationAddress === undefined ? undefined : async () => orchestrationAddress, actions: { ...emptyNativeChatContextMenuActions, canCopyAgentSessionId, diff --git a/src/renderer/src/components/native-chat/use-native-chat-context-menu.tsx b/src/renderer/src/components/native-chat/use-native-chat-context-menu.tsx index 058a8ad010d..f999f7eeb61 100644 --- a/src/renderer/src/components/native-chat/use-native-chat-context-menu.tsx +++ b/src/renderer/src/components/native-chat/use-native-chat-context-menu.tsx @@ -53,8 +53,8 @@ type UseNativeChatContextMenuArgs = { groupId: string shortcutLabels?: Partial> } - /** A structured session's `session:`; terminal-backed chats are addressed by their handle. */ - orchestrationAddress?: string + /** Resolves a structured session's `session:`; terminal-backed chats are addressed by their handle. */ + resolveOrchestrationAddress?: () => Promise } export type NativeChatContextMenuActions = { @@ -107,7 +107,7 @@ export function useNativeChatContextMenu({ showTerminalPaneActions = true, splitShortcutLabels, workspaceLayout, - orchestrationAddress + resolveOrchestrationAddress }: UseNativeChatContextMenuArgs): { onContextMenuCapture: MouseEventHandler onSelectionCapture: () => void @@ -288,8 +288,8 @@ export function useNativeChatContextMenu({ 'Set Title…' )} - {orchestrationAddress ? ( - + {resolveOrchestrationAddress ? ( + ) : null} {actions.canCopyAgentSessionId ? ( @@ -327,10 +327,10 @@ export function useNativeChatContextMenu({ ) : null} - ) : orchestrationAddress ? ( + ) : resolveOrchestrationAddress ? ( <> - + ) : null} diff --git a/src/renderer/src/components/native-chat/use-structured-native-chat-pane-commands.ts b/src/renderer/src/components/native-chat/use-structured-native-chat-pane-commands.ts index 0695f564861..25db2cc0e99 100644 --- a/src/renderer/src/components/native-chat/use-structured-native-chat-pane-commands.ts +++ b/src/renderer/src/components/native-chat/use-structured-native-chat-pane-commands.ts @@ -19,7 +19,7 @@ export function useStructuredNativeChatPaneCommands({ rootRef, composerRef, terminalPaneActions, - orchestrationAddress + resolveOrchestrationAddress }: { tabId: string groupId?: string @@ -27,7 +27,7 @@ export function useStructuredNativeChatPaneCommands({ rootRef: RefObject composerRef: RefObject terminalPaneActions?: Omit - orchestrationAddress?: string + resolveOrchestrationAddress?: () => Promise }) { const keybindings = useAppStore((state) => state.keybindings) const pasteClipboardIntoComposer = useNativeChatPasteBridge({ rootRef, composerRef }) @@ -39,7 +39,7 @@ export function useStructuredNativeChatPaneCommands({ onPaste: pasteClipboardIntoComposer }, enabled: isVisible, - orchestrationAddress, + resolveOrchestrationAddress, showTerminalPaneActions: terminalPaneActions !== undefined, splitShortcutLabels: { right: formatShortcutLabel('terminal.splitRight', keybindings), diff --git a/src/renderer/src/runtime/structured-session-orchestration-address.test.ts b/src/renderer/src/runtime/structured-session-orchestration-address.test.ts new file mode 100644 index 00000000000..28e1b86772f --- /dev/null +++ b/src/renderer/src/runtime/structured-session-orchestration-address.test.ts @@ -0,0 +1,61 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' + +const callRuntimeRpc = vi.hoisted(() => vi.fn()) +vi.mock('./runtime-rpc-client', async (importOriginal) => ({ + ...(await importOriginal>()), + callRuntimeRpc +})) + +import { RuntimeRpcCallError } from './runtime-rpc-result' +import { resolveStructuredSessionOrchestrationAddress } from './structured-session-orchestration-address' + +const LIVE = '7e3b9d15-2c4a-4f86-a0b1-5c9e2d7f3b64' +const ROOT = '4a1f6c2e-8b3d-4e7a-9c15-0d2b6e8f1a37' +const LOCAL = { kind: 'local' } as const + +function failure(code: string, message: string): RuntimeRpcCallError { + return new RuntimeRpcCallError({ + id: 'rpc_1', + ok: false, + error: { code, message }, + _meta: { runtimeId: 'runtime_1' } + }) +} + +describe('the orchestration address a chat copies', () => { + beforeEach(() => { + callRuntimeRpc.mockReset() + }) + + it("is the host's address for the conversation, not the live session id", async () => { + callRuntimeRpc.mockResolvedValue({ address: `session:${ROOT}` }) + + await expect(resolveStructuredSessionOrchestrationAddress(LOCAL, LIVE)).resolves.toBe( + `session:${ROOT}` + ) + expect(callRuntimeRpc).toHaveBeenCalledWith(LOCAL, 'orchestration.sessionAddress', { + sessionId: LIVE + }) + }) + + it('is the live id on a host that predates the method, where it is the address', async () => { + callRuntimeRpc.mockRejectedValue(failure('method_not_found', 'Unknown method')) + + await expect(resolveStructuredSessionOrchestrationAddress(LOCAL, LIVE)).resolves.toBe( + `session:${LIVE}` + ) + }) + + it('surfaces any other failure instead of guessing', async () => { + callRuntimeRpc.mockRejectedValue(failure('runtime_unavailable', 'down')) + + await expect(resolveStructuredSessionOrchestrationAddress(LOCAL, LIVE)).rejects.toThrow('down') + }) + + it('asks nothing for an id that is not an Orca session id', async () => { + await expect(resolveStructuredSessionOrchestrationAddress(LOCAL, 'not an id')).resolves.toBe( + null + ) + expect(callRuntimeRpc).not.toHaveBeenCalled() + }) +}) diff --git a/src/renderer/src/runtime/structured-session-orchestration-address.ts b/src/renderer/src/runtime/structured-session-orchestration-address.ts new file mode 100644 index 00000000000..740411f89ac --- /dev/null +++ b/src/renderer/src/runtime/structured-session-orchestration-address.ts @@ -0,0 +1,34 @@ +import { + formatOrchestrationActor, + sessionOrchestrationActor +} from '../../../shared/orchestration-actor' +import type { OrchestrationSessionAddressResult } from '../../../shared/orchestration-caller-status' +import { callRuntimeRpc, RuntimeRpcCallError, type RuntimeClientTarget } from './runtime-rpc-client' + +/** + * The address other agents reach a chat at: its conversation's, which the host derives from the + * session records and which `/clear` keeps. Null for an id that is not an Orca session id. + */ +export async function resolveStructuredSessionOrchestrationAddress( + target: RuntimeClientTarget, + sessionId: string +): Promise { + const actor = sessionOrchestrationActor(sessionId) + if (!actor) { + return null + } + try { + const result = await callRuntimeRpc( + target, + 'orchestration.sessionAddress', + { sessionId } + ) + return result.address + } catch (error) { + // Why: a host that predates the method has no /clear lineage, so there the live id is the address. + if (error instanceof RuntimeRpcCallError && error.code === 'method_not_found') { + return formatOrchestrationActor(actor) + } + throw error + } +} diff --git a/src/shared/orchestration-caller-status.ts b/src/shared/orchestration-caller-status.ts index 38d28bcdb89..c1feb905d3a 100644 --- a/src/shared/orchestration-caller-status.ts +++ b/src/shared/orchestration-caller-status.ts @@ -34,3 +34,6 @@ export type OrchestrationCallerRefusal = { export type CliStatusCaller = OrchestrationCallerAddress | OrchestrationCallerRefusal | null export type OrchestrationCallerShowResult = { caller: OrchestrationCallerAddress | null } + +/** `orchestration.sessionAddress`: the `session:` another agent reaches a session's chat at. */ +export type OrchestrationSessionAddressResult = { address: string } diff --git a/src/shared/rpc-contract/orchestration-params.ts b/src/shared/rpc-contract/orchestration-params.ts index e58dca2143c..68d90f2ec55 100644 --- a/src/shared/rpc-contract/orchestration-params.ts +++ b/src/shared/rpc-contract/orchestration-params.ts @@ -106,6 +106,11 @@ export const DispatchParams = z.object({ run: OptionalString }) +/** An Orca agent session id; the answer is the address its conversation is reached at. */ +export const SessionAddressParams = z.object({ + sessionId: requiredString('Missing sessionId') +}) + export const DispatchShowParams = z.object({ task: OptionalString, preamble: OptionalBoolean, diff --git a/src/shared/rpc-contract/rpc-params-catalog.generated.ts b/src/shared/rpc-contract/rpc-params-catalog.generated.ts index c07c68471e9..c4d590f490e 100644 --- a/src/shared/rpc-contract/rpc-params-catalog.generated.ts +++ b/src/shared/rpc-contract/rpc-params-catalog.generated.ts @@ -378,6 +378,7 @@ import { InboxParams, ReplyParams, ResetParams, + SessionAddressParams, TaskCreateParams, TaskListParams } from './orchestration-params' @@ -1007,6 +1008,7 @@ export const RPC_PARAMS_BY_METHOD = { 'orchestration.runShow': RunShowParams, 'orchestration.runStop': RunStopParams, 'orchestration.runUse': RunUseParams, + 'orchestration.sessionAddress': SessionAddressParams, 'orchestration.taskCreate': TaskCreateParams, 'orchestration.taskList': TaskListParams, 'orchestration.workerAbandon': WorkerDispatchParams, From 73c3d11e21d6bad4dd3b3632e31a522684135543 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 14:33:35 -0700 Subject: [PATCH 15/18] fix(orchestration): spell a structured worker by its session's actor, the lineage-aware address The read-side spelling formatted the worker's live session id. It now uses the session's orchestration actor, the same derivation the caller resolver binds, so it follows a chat's /clear lineage wherever that derivation does. --- .../runtime/orchestration/structured-session-mail-address.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/runtime/orchestration/structured-session-mail-address.ts b/src/main/runtime/orchestration/structured-session-mail-address.ts index 196693c5b60..9e814993342 100644 --- a/src/main/runtime/orchestration/structured-session-mail-address.ts +++ b/src/main/runtime/orchestration/structured-session-mail-address.ts @@ -204,14 +204,14 @@ export function hasLostStructuredWorkerIdentity( /** * How an agent is shown a mailbox address. A structured worker's handle is only its mailbox key: it - * reads as `session:`, the one address that worker is taught, and routes back to that mailbox. + * reads as its session's actor, the one address that worker is taught, which routes back to it. */ export function agentVisibleOrchestrationAddress( address: string, db: OrchestrationDb | null | undefined ): string { const worker = resolveStructuredWorkerIdentity(address, db) - return worker ? formatOrchestrationActor({ kind: 'session', id: worker.sessionId }) : address + return worker ? sessionOrchestrationIdentity(worker.sessionId, db).actor : address } export function withAgentVisibleAddresses( From c32ac98b69bb086a5930efb65dc74ae5554e3c52 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 14:51:57 -0700 Subject: [PATCH 16/18] test(orchestration): pin that a cleared chat's successor copies its conversation's root address --- src/main/runtime/rpc/orchestration-caller-show.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/runtime/rpc/orchestration-caller-show.test.ts b/src/main/runtime/rpc/orchestration-caller-show.test.ts index dc61eac3dec..d7db92abd3e 100644 --- a/src/main/runtime/rpc/orchestration-caller-show.test.ts +++ b/src/main/runtime/rpc/orchestration-caller-show.test.ts @@ -167,8 +167,8 @@ describe('orchestration.callerShow: the caller learns its own address from the h await h.dispatch(orchestrationRequest('orchestration.sessionAddress', { sessionId })) ) const acting = resultOf(await h.dispatch(callerShow({ sessionId }))) - // One derivation: whatever address the host gives the conversation, the copy is the actor's. - expect(shown.address).toMatch(/^session:/) + // One derivation: the conversation's root, which the successor copies and acts as too. + expect(shown.address).toBe(ACTOR_X) expect(acting.caller).toMatchObject({ kind: 'session', address: shown.address }) } }) From 4a8f01f7d695d83a60c47b9be7a090070a019dd3 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 16:23:53 -0700 Subject: [PATCH 17/18] test(orchestration): give the mode-opacity fixture's record store the listing a lineage lookup reads A structured worker's agent-visible address now resolves through its conversation's lineage, which lists the session records; the fixture's partial store lacked that listing, so the sub-worker start failed at dispatch input. --- .../rpc/methods/orchestration-worker-mode-opacity.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts b/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts index 88aaa883e29..7c4e19c47a9 100644 --- a/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts +++ b/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts @@ -86,7 +86,9 @@ function installStructuredCoordinator(handle: string, sessionId: string): string deathEvidence: null, runtimeFence: 1 } - }) + }), + // No committed /clear: each session is its own conversation's root. + listRecords: () => [] } } } as never) From 3952a52d8b49d05d3f90d31a37fa490e8dee0b05 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 24 Sep 2026 16:41:38 -0700 Subject: [PATCH 18/18] test(orchestration): hand the mode-opacity test its session host through a mocked registry, not a cast The fixture set a partial session host through a type assertion; it now serves a structural fake from a mocked registry getter, as the other session-host tests do, so no host type is claimed. --- .../orchestration-worker-mode-opacity.test.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts b/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts index 7c4e19c47a9..2eaca382f40 100644 --- a/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts +++ b/src/main/runtime/rpc/methods/orchestration-worker-mode-opacity.test.ts @@ -13,7 +13,6 @@ */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { setStructuredAgentSessionHost } from '../../../native-chat/agent-session-wire/structured-agent-session-registry' import { OrcaRuntimeService } from '../../orca-runtime' import { OrchestrationDb } from '../../orchestration/db' import { @@ -30,6 +29,12 @@ const STRUCTURED_HANDLE = 'structworker_worker' const TERMINAL_HANDLE = 'term_worker' const structuredPreambles: string[] = [] +// The session host the code under test reads; a structural fake, so no host type is claimed. +const hostRef = vi.hoisted((): { current: unknown } => ({ current: null })) + +vi.mock('../../../native-chat/agent-session-wire/structured-agent-session-registry', () => ({ + getStructuredAgentSessionHost: () => hostRef.current +})) vi.mock('./orchestration/worker/worker-topology', async (importOriginal) => ({ ...(await importOriginal>()), @@ -73,7 +78,7 @@ function installStructuredCoordinator(handle: string, sessionId: string): string worktreeId: WORKTREE, hostScope: { kind: 'local', hostId: 'local' } }) - setStructuredAgentSessionHost({ + hostRef.current = { hasSession: () => true, deps: { store: { @@ -91,7 +96,7 @@ function installStructuredCoordinator(handle: string, sessionId: string): string listRecords: () => [] } } - } as never) + } return paneKey } @@ -174,7 +179,7 @@ describe('a worker cannot tell which mode it is running in', () => { afterEach(() => { db.close() - setStructuredAgentSessionHost(null) + hostRef.current = null structuredWorkerIdentities.clear() vi.restoreAllMocks() })