# Orchestration

## Operating model

The Pi parent owns Analyze, ambiguity resolution, operator interaction, final
acceptance, and authorized shipping. The launcher defaults to
`openai-codex/gpt-5.6-sol` at high thinking, while respecting operator model and
effort overrides.

Bounded Explore, Research, Plan, Implement, Verify, and authorized Deploy work
uses `arc_delegate` under **runner-routing-v4**. Every request includes an exact
`outcome`, `scope`, `preserved_behavior`, `verification`, `prohibitions`, and a
short non-sensitive `label`.

An optional explicit `task_slug` enables task-scoped Markdown evidence. It must
be one lowercase path segment containing only letters, numbers, and hyphens.
ARC Pi never infers it.

Analyze is never sent to a worker. An explicit `phase: analyze` call fails
locally with guidance to use the current Pi parent session.

During Analyze, `arc_prompt_recommend` may provide read-only drafting guidance.
If its canonical result contains `needsOperator`, the parent queries
`arc_decisions` by `needsOperator.question.semantic_key` and reuses a choice
only when exactly one current-effective decision answer still names a returned
alternative. Otherwise the parent passes `needsOperator.question` verbatim to
`arc_ask_operator`. Cancellation, unresolved input, no dialog UI, and stale,
invalid, or ambiguous effective answers leave the recommendation unresolved and
block reliance on it. Pattern-choice records and reuse always report
`authorization_granted: false`; they never satisfy Implement or Deploy gates.

Explore, Research, and Plan require a real operator choice in dialog-capable Pi
UI (TUI or supported RPC) for every call. The choice approves automatic routing
(including requested Eco) or selects any valid `-explore` alias. The gate runs
before runner/session creation, so decline, escape/cancel, an already-aborted
signal, and contexts without such UI launch nothing. Automated CI coverage can
opt in only by setting both `CI=true` and
`ARC_PI_READ_ONLY_APPROVAL_BYPASS=1`; no tool parameter lets the model authorize
itself.

## Authorization lifecycle

Implement requires:

1. an exact bounded contract;
2. one canonical `workload_class`;
3. explicit operator approval of both; and
4. `implement_authorized: true` on the approved call.

The only workload classes are:

`hard-heavy`, `hard-medium`, `hard-light`, `medium-heavy`, `medium-medium`,
`medium-light`, `easy-heavy`, `easy-medium`, and `easy-light`.

All legacy names and obsolete aliases are rejected. After Implement, Verify
with the relevant tests and review. Verification failure is terminal and any
further implementation requires a revised contract plus a new approval.
Optional Code Review is separate from Verify and skips the resolved
implementation model.

Deploy authorization is unchanged: `phase: deploy` requires
`deploy_authorized: true` only after the operator approves the exact deployment
action. Implement authorization does not imply Deploy authorization.

## Routing policy

Normal automatic worker calls use argv equivalent to:

```sh
arc-orchestrator run \
  --mode <analyze|implement|review> \
  --phase <explore|research|plan|implement|verify|deploy> \
  --routing-policy runner-routing-v4 \
  [--task-slug <explicit-slug>] \
  --task '<bounded contract>' \
  --cwd "$PWD" \
  --label <safe-label>
```

Implement also includes `--workload-class <canonical-class>`. Deploy includes
`--deploy-authorized true`. Automatic calls do not include `--backend`,
`--route`, `--worker-model`, or the legacy `--fallback` flag. The v4 marker
causes old runners to fail closed before worker invocation and ARC Pi adds an
actionable upgrade message.

`--task-slug` appears only on analyze-mode Explore, Research, and Plan calls
with a validated explicit slug. It is never embedded in `--task`; Implement and
Verify artifacts remain harness-written, and Deploy rejects a slug. For
Explore, Research, and Plan, this argv is constructed only after the
operator selects the automatic option. If the operator instead chooses a
worker-analysis alias, ARC Pi emits that explicit `--route` with no automatic
marker.

The ordered rungs and shared emergency tail are documented in the
[ARC Delegate v4 model matrix](arc-delegate.md). Terra is excluded. Cursor Kimi
and Grok use fixed high model profiles, MiniMax uses high effort, and Composer
has no effort value; ARC never invents a generic effort flag for transports
that do not expose one.

Automatic traversal is availability-only. Provider unavailability,
authentication/rate limits, and response timeouts can advance to the next rung.
Task failure, malformed output, and verification failure stop immediately.

`/arc-report` reads `listSessionRuns` for the current session and renders a
Stage | Model | Result table (status glyphs ✓ / ✗ / ⏱ / ⊘ / ●). When the
session-runs registry is empty, it transparently falls back to
`arc-orchestrator report` so behavior matches the pre-existing shell command
on sessions that never registered a delegation.

## Explicit routes and exhaustion

An explicit route pins one candidate and inherits no fallback. The allowlist is
the Cartesian product of the following 30 bases and the `-explore`,
`-implement`, and `-check` suffixes: exactly 90 executable aliases.

| Stable base | Versioned base | Current resolution             | Backend  |
| ----------- | -------------- | ------------------------------ | -------- |
| `fable`     | `fable-5.1`    | Fable 5.1 (`claude-fable-5-1`) | Claude   |
| `sol`       | `gpt-5.6-sol`  | Sol 5.6 (`gpt-5.6-sol`)        | Codex    |
| `luna`      | `gpt-5.6-luna` | Luna 5.6 Max (`gpt-5.6-luna`)  | Codex    |
| `gpt-5.5`   | `gpt-5.5`      | GPT 5.5                        | Codex    |
| `opus`      | `opus-5`       | Opus 5 (`claude-opus-5`)       | Claude   |
| `opus-4.8`  | `opus-4.8`     | Opus 4.8 (`claude-opus-4-8`)   | Claude   |
| `grok`      | `grok-4.6`     | Cursor Grok 4.6 High           | Composer |
| `kimi`      | `kimi-k3`      | Cursor Kimi K3 (`kimi-k3`)     | Composer |
| `minimax`   | `minimax-m3`   | MiniMax M3                     | MiniMax  |
| `composer`  | `composer-2.5` | Composer 2.5                   | Composer |

The identical stable/versioned cells above are a single accepted base, not a
duplicate alias. The OpenCode Go bases below are single provider-qualified
bases on the `opencode` transport; each pins the `opencode-go/<model>`
identity whose stable id mirrors it, and none exposes an effort control (every
route runs at `@none`). Bases that would collide with an existing Cursor or
Codex alias carry a `go-` prefix so `kimi-k3`, `grok-4.6`, and `luna` keep
their current transports.

| OpenCode Go base    | Current resolution                                                    | Backend  |
| ------------------- | --------------------------------------------------------------------- | -------- |
| `glm-5.3-flash`     | OpenCode Go GLM 5.3 Flash (`opencode-go/glm-5.3-flash`)               | OpenCode |
| `glm-5.3`           | OpenCode Go GLM 5.3 (`opencode-go/glm-5.3`)                           | OpenCode |
| `deepseek-v4-pro`   | OpenCode Go DeepSeek V4 Pro (`opencode-go/deepseek-v4-pro`)           | OpenCode |
| `deepseek-v4-flash` | OpenCode Go DeepSeek V4 Flash (`opencode-go/deepseek-v4-flash`)       | OpenCode |
| `go-kimi-k3`        | OpenCode Go Kimi K3 (`opencode-go/kimi-k3`)                           | OpenCode |
| `qwen-3.8-max`      | OpenCode Go Qwen 3.8 Max (`opencode-go/qwen3.8-max`)                  | OpenCode |
| `muse-spark-1.2`    | OpenCode Go Muse Spark 1.2 (`opencode-go/muse-spark-1.2-contributor`) | OpenCode |
| `glm-5.2`           | OpenCode Go GLM 5.2 (`opencode-go/glm-5.2`)                           | OpenCode |
| `kimi-k2.7-code`    | OpenCode Go Kimi K2.7 Code (`opencode-go/kimi-k2.7-code`)             | OpenCode |
| `go-grok-4.6`       | OpenCode Go Grok 4.6 (`opencode-go/grok-4.6`)                         | OpenCode |
| `go-luna`           | OpenCode Go Luna 5.6 (`opencode-go/gpt-5.6-luna`)                     | OpenCode |

`opus-review` remains a separate taste-review surface and is
not one of the 87 runner routes. Terra, Grok 4.5, Cursor Fable, `opencode-kimi-*`,
`codex-*`, mechanical, and other legacy aliases are rejected rather than
redirected. In particular, public `kimi-*` and `kimi-k3-*` routes always use
Composer transport with provider model `kimi-k3`; the OpenCode twin is
`go-kimi-k3-*`.

After the automatic availability stack is exhausted, ask the operator to choose
any accepted explicit route and recommend the matching Composer route:
`composer-explore`, `composer-implement`, or `composer-check`. Do not silently
retry terminal failures on another model.

Eco remains opt-in. When the operator requests it, set `orchestrator: "eco"` on
an automatic call and omit `route`; ARC Pi selects Eco through the child
environment. Normal calls always emit `runner-routing-v4`.

## Example Implement approval and call

Before calling the worker, present the exact contract and proposed class to the
operator. After approval:

```json
{
  "outcome": "Add request validation and focused tests",
  "scope": "src/api/validate.ts and test/api/validate.test.ts only",
  "preserved_behavior": "Keep successful response payloads unchanged",
  "verification": "Run the focused validation test file",
  "prohibitions": "No dependency upgrades or unrelated refactors",
  "phase": "implement",
  "workload_class": "medium-medium",
  "implement_authorized": true,
  "task_slug": "request-validation",
  "label": "request-validation"
}
```

An explicit Verify recovery route is pinned:

```json
{
  "outcome": "Verify the approved request validation change",
  "scope": "The approved implementation diff and focused tests",
  "preserved_behavior": "Make no changes",
  "verification": "Return compact verification evidence",
  "prohibitions": "No writes or external mutations",
  "phase": "verify",
  "route": "composer-check",
  "label": "request-validation-check"
}
```

## Parent fallbacks

Worker routing is independent of parent-provider recovery.
`ARC_PI_PARENT_FALLBACK` controls the configurable usage-limit fallback. The
default chain is `minimax/MiniMax-M3,opencode-go/minimax-m3`. MiniMax HTTP 402
insufficient-balance errors count as a provider outage, so a pay-as-you-go
MiniMax key with no credits can continue on OpenCode Go MiniMax. The
expensive-parent token budget uses `ARC_PI_BUDGET_FALLBACK`, which defaults to
`cursor/grok-4.6` and can be set to another `provider/model` or `off`.

## Session-scoped parallel subagents

`subagent_spawn` is a separate, nonblocking surface for work that is already
split into disjoint, self-contained story or worktree tasks. Start at most four
children, record every returned `arc-sub-…` ID, and use one `subagent_wait` call
for the relevant IDs before accepting their work. A successful, non-cancelled
wait claims those results and prevents duplicate automatic follow-ups; a
cancelled wait leaves the one automatic completion follow-up available. Use
`subagent_check`, `subagent_list`, `/subagents` (or `/sub`), and
`subagent_cancel` for bounded inspection and control. In TUI mode the commands
open a selectable dashboard and per-child takeover view. The view shows only
normalized, bounded transcript, thinking, and tool activity; it can steer or
abort an active child, while settled children are read-only. Takeover uses `s`
to steer and `x` to abort. Non-TUI mode retains list/detail notifications.

Each child is an isolated in-process Pi session with an independently resolved
cwd and model context. A requested cwd must already exist inside the current
project real path; start ARC Pi from the intended worktree when worktrees are
used. Children receive an explicit built-in tool allowlist and no extension
resources or tools, so they do not receive nested subagent, ARC delegation,
background-terminal, decision, ask-user, or monitor tools. This is not an OS
sandbox: the allowlisted local bash tool is trusted-host execution, and prompt
prohibitions on commits, pushes, deploys, GitHub mutation, secrets access,
external workers, and scope expansion are policy guidance rather than OS-level
enforcement.

This surface does not replace `arc_delegate`, alter runner routing or
authorization, or make Deploy implicit. Do not use it to fan out phases of one
ARC lifecycle that require ordered parent judgment. Child state is intentionally
session-local, result/history/activity data is bounded, unclaimed settlement
produces at most one follow-up, and parent-session shutdown cancels active
children. The TUI takeover is a session-scoped view and steering surface, not a
terminal or cross-session reattachment mechanism.

## Safety and evidence

The extension preserves cancellation, timeouts, output caps, trace redaction,
and per-project write serialization. Workers may not commit, push, merge,
deploy, mutate GitHub, access secrets, invoke nested workers, or broaden scope.
Deploy is the sole exception and only for its exact separately authorized
action.

`arc_delegate` returns compact structured evidence. Raw task text, absolute
paths, secrets, provider transcripts, and chain-of-thought are not exposed in
traces or progress output. Treat worker output as advisory until the parent
inspects the diff and verifies the result.

With an explicit `task_slug`, capable Explore, Research, and Plan workers may
author `docs/<task_slug>/<phase>.md`. ARC Pi snapshots before launch, restores
every non-completed outcome, and on exact completion keeps only sanitized
regular analysis-phase files of at most 32 KiB before appending compact harness
evidence as an audit footer. Implement and Verify remain harness-written. Calls
without a slug preserve the default of no artifact writes.
`arc_task_artifact` records parent-local Analyze and manual summaries for those
same non-Deploy phases under the active cwd. Both paths are bounded and
append-only; unsafe slugs fail before any worker or file write. Deploy artifacts
are never created. Persistence is evidence-only: raw prompts, contracts,
provider transcripts, hidden reasoning, secrets, and absolute paths are omitted
or redacted, including short assignments to quoted secret-like keys containing
dots, spaces, underscores, or hyphens.
