# Usage reference

This is the complete operator reference. If you are installing the package or
starting your first run, begin with the README's
[quick start](../README.md#quick-start). Existing users upgrading to `0.12.0`
should read the [0.12.0 upgrade guide](../README.md#upgrade-to-0120) and its
[versioned migration notes](../releases/v0.12.0.md).

Use this reference when you need profiles, exact project mappings, model and
budget precedence, CLI flags, retained state, recovery, or controller details.
Wire-protocol and ACL details live separately in
[coordination protocol v1](protocol-v1.md).

## Commands

The Pi extension intentionally registers only `/or-dashboard`, `/or-models`,
`/or-start`, `/or-send`, and `/or-stop`. The dashboard consolidates help, concise
package metadata, running-session list/status, on-demand doctor, attach/watch,
and confirmed stop. Duplicate `/orchestrator-*` and read-only helper slash
commands are not registered. A user may start explicitly with `/or-start [task]`
or ask Pi naturally, for example: `Describe the change. Use the orchestrator.`
The natural-language path uses the `tmux_orchestrator` model tool and preserves
the same preview, trust, and confirmation boundaries. The standalone CLI and
model tool retain their full command/action surfaces.

### Explicit task intent

Start accepts exactly `change`, `investigation`, `review`, or `advisory` through
model-tool `taskIntent`, terminal `--task-intent`, and the `/or-start` selector.
Select operator intent, not a model-inferred label. For example:

```sh
pi-tmux-agents start --task-intent investigation --task 'Synthetic read-only question.'
pi-tmux-agents start --project "$PWD" --task-intent change --task-file /tmp/task.md --dry-run
```

`change` uses the existing one-implementer writer and mandatory reviewer. The
other values describe work without repository edits. Stage 1 does not launch a
separate read-only workflow: Pi shows why coding orchestration may be unnecessary
and asks **Answer directly in parent?** Yes returns `disposition=direct-parent`;
No returns `disposition=cancelled`. Both return `launched=false`, create no
orchestration resources, and submit no implementation/change claims. Slash
intent-selection cancellation stops before preview. CLI non-change starts print
the same warning and return `direct-parent` immediately, even with `--yes`,
`--approve-project`, `--dynamic-plan`, or `--rpc-workers`. They do not resolve
launch configuration or call a planner. A new explicit `change` request is
required for coding; there is no proceed-anyway override and no automatic parent
prompt injection. The normal model-tool start still requires TUI confirmation;
the internal terminal dynamic adapter uses confirmed RPC, and both worker
presentation modes share unchanged coding authority.

Intent omission preserves ordinary static change tasks. Static starts make no
classification provider call. The existing separately authorized dynamic call
includes one bounded `task_intent` choice alongside topology/model/thinking
questions, even for topology-only planning; this is a recommendation, not an
additional planning axis or authority. Explicit intent wins. With omitted intent,
a non-change recommendation offers direct-parent/cancel before CLI launch preview,
trust bypass, or worker creation. Terminal dynamic redirection declines the
parent-answer confirmation by default and returns `cancelled` with a notice;
`--yes` confirms coding launch only. Dynamic `--dry-run` shows the non-change
redirection without creating a run. Explicit `change` retains a conflicting
recommendation in final confirmation and proceeds only with launch approval.
Malformed choices fail closed, and the decision/preview/config bindings cover
intent metadata and explicit-versus-omitted selection. A changed or tampered
accepted preview cannot launch. Only `{version, operator, recommendation,
effective, source}` metadata is retained; no task, rationale, or provider bodies.

Use the parent directly for explanations or focused read-only work where multiple
agents add little value. Phased inspect/plan is still a coding precursor that
automatically advances to implementation, not an investigation/advisory escape
hatch. No role, tool ACL, report schema, or mandatory-review rule is weakened.

### Model-tool recovery controls

`tmux_orchestrator` has `stop`, `restart`, and `abort` actions, with no
new slash commands. These are thin adapters to the canonical CLI controls, not a
second workflow engine. For example, use synthetic identities like:

```json
{"action":"restart","session":"pi-example-agents","role":"implementer","run":"exact-run-id","commandId":"0123456789abcdef0123456789abcdef"}
```

- `stop`: exact orchestration session only. Separate interactive TUI/RPC approval
  names the run and retains coordination/Pi history. Missing/disconnected UI,
  cancellation, or decline cannot pass `--yes`.
- `restart`: exact enabled role only (including a selected trusted custom identity).
  Separate interactive approval respawns the worker using retained launch settings;
  mandatory broker generation/resource checks still apply. Duplicate accepted IDs
  never repeat the tmux respawn. After inspecting a stuck handover, a **new ID and
  separate confirmation** authorize a fresh recovery even in `restarting`,
  `recovering`, or `uncertain`. Restart needs the broker's in-memory baseline,
  not a still-connected old worker; revoked resources still block recovery.
- `abort`: exact enabled role only, requesting broker cancellation without a
  destructive confirmation. An uncertain role state does not block abort to a
  connected worker; a missing connection still fails uncertain. `acknowledged` means accepted delivery, **not terminal
  operation or task completion**. Existing `aborted` is a request flag, not evidence
  of terminal completion; `completion=not_observed` makes this explicit.

The adapters read the exact live/retained run before controlling it and pass
`--run` so approval cannot silently select a new same-name run. Optional `run`
selects an exact retained record but never supplies live-control authority.
`commandId` is optional 32-character lowercase hex; if omitted, recovery generates
one and exposes it on failures/success. Preserve that ID **and exact run** on a
retry. Stop receipts are private, bounded metadata-only files in the retained run:
`completion=completed` can replay after stop. An interrupted claim stays uncertain
until an explicitly confirmed same-ID retry reconciles it under a nonblocking
local lock: stop only the original live run, or complete from a successful tmux
observation of absence. A same-name replacement is never targeted; an unavailable
server is not evidence of absence. The kill uses an immutable tmux session ID,
so a replacement between observation and kill cannot be stopped. Concurrent
claims fail uncertain without waiting and can be retried. `stop_attempted`
distinguishes a reconciled kill from a receipt replay/verified absence.
Restart `completion=respawned` means only that tmux accepted the pane respawn,
not completed recovery. A duplicate restart reports `completion=uncertain` and
`restarted=false`; inspect status, then issue a fresh separately confirmed ID if
recovery is needed. Error metadata preserves validated `duplicate`,
`command_status`, `completion`, and `retry` (`same_command_id`, `new_command_id`,
or `inspect_exact_run`), never raw errors. Unknown broker delivery should first
be resolved with the same ID; a stored uncertain refusal needs a fresh ID after
the blocker is resolved. Missing broker before connection is `broker_not_ready`;
a timeout or transport loss after connection is `broker_uncertain`. Neither is success.

Start accepts optional exact `session`, sharing CLI validation: 1–128 ASCII
letters/digits/underscores/dots/hyphens, without trimming or fuzzy matching (`.`/`..` are reserved). CLI
controls retain existing defaults/confirmation flags and add `--run` and
`--command-id` to restart/stop; idempotent stop requires `--run`, and idempotent
restart requires a brokered run and retained launch settings (no model overrides). Model-tool restart does not expose model changes;
use the separately confirmed existing CLI path for those.

On collision, schema-v1 returns `success=false`, `error.code=session_collision`,
and bounded `data.collision` with exact session, orchestrator-marker validity,
optional run ID, safely available retained workflow (`state`, `round`, flow),
role (`role`, `state`, `generation`) metadata, and `next_actions`. State provenance
is explicitly not liveness. A valid marked run offers `status`, `attach` (interactive
TUI/tmux and broker-capable run only), `stop` (separate confirmation), or `start` with a different exact
name. Unknown/invalid/non-orchestrator metadata offers only a different name, not
a destructive action. Unavailable state remains null/unknown; raw exceptions,
private bodies, resource/provider payloads, and paths are omitted. Dashboard `x`
and `/or-stop` share the same confirmation/run-binding handler. Nothing
**automatically stops, replaces, renames, or reuses** a session.

A regular interactive Pi session checks the public npm package metadata once at
startup and shows a non-blocking warning only when a newer release is available.
The dashboard's Tasklight-style About footer reuses cached update metadata and
never starts another network check. Update with `pi update npm:pi-tmux-orchestrator`, or set
`PI_TMUX_ORCHESTRATOR_DISABLE_UPDATE_NOTICE=1` to disable the startup check.
Worker and controller sessions never perform this check.

### Profiles and exact project policy

Execution profiles are deterministic thinking-level maps for the five built-in
roles. They do not change models, tools, role authority, required review,
workflow routing, result caps, or budget behavior. Select a packaged/custom
profile explicitly for one run with:

```bash
pi-tmux-agents start \
  --project /absolute/path/to/project \
  --task "Describe the requested change" \
  --profile economy \
  --dry-run
```

The strict user-global file `~/.pi/agent/tmux-orchestrator.json` supports global
profiles and exact per-project orchestration defaults. Obtain every directory
with `pwd -P`; all mapped directories must already exist when the file is read.
A complete multi-project setup can look like this:

```json
{
  "version": 4,
  "defaultProfile": "balanced",
  "profiles": {
    "review-heavy": {
      "implementer": "medium",
      "reviewer": "high",
      "probe": "low",
      "playwright": "medium",
      "django": "medium"
    }
  },
  "projects": [
    {
      "directory": "/Users/alice/Work/storefront",
      "profile": "balanced",
      "implementationFlow": "phased",
      "specialists": ["playwright"],
      "workspaceCapsule": false
    },
    {
      "directory": "/Users/alice/Work/payments-api",
      "profile": "review-heavy",
      "roles": {
        "reviewer": { "thinking": "xhigh" }
      },
      "implementationFlow": "phased",
      "specialists": ["probe", "django"],
      "workspaceCapsule": false
    },
    {
      "directory": "/Users/alice/Work/docs-site",
      "profile": "economy",
      "implementationFlow": "single",
      "specialists": [],
      "workspaceCapsule": false
    }
  ]
}
```

| Match | Resolved project policy |
|---|---|
| exact `storefront` directory | packaged `balanced`; phased flow; Playwright configured |
| exact `payments-api` directory | custom `review-heavy`; reviewer `xhigh`; phased flow; probe and Django configured |
| exact `docs-site` directory | packaged `economy`; single flow; specialists explicitly disabled |
| no exact match | user-global `balanced`; packaged flow/specialist/workspace defaults |

Configured specialists are still selected or skipped by the deterministic
activation policy; listing one does not force it. Explicit run options override
the exact project entry. Project `defaults` and `roles` may additionally select
exact provider/model IDs from `/or-models`; omit them when no project-specific
model override is needed. The README has a separate
[model-override recipe](../README.md#4-override-models-only-when-needed).

The file is relative to `PI_CODING_AGENT_DIR`; an absolute
`PI_TMUX_ORCHESTRATOR_CONFIG` overrides its location. Legacy versions 1 and 2
remain accepted. Version 2 may select one default profile and define at most 16
custom thinking mappings. Version 3 adds at most 64 exact project mappings.
Version 4 may additionally bind at most eight registered `customRoles` on an
exact project, each with an exact provider, model, and thinking level.
Names match `[a-z][a-z0-9-]{0,31}`; packaged names cannot be replaced. Every
custom map must contain implementer, reviewer, probe, Playwright, and Django
exactly once and may additionally contain at most eight canonical `custom-*`
identities. Unknown fields/roles, partial built-in mappings, unsupported levels,
credentials, and configuration paths inside the target project fail closed.
A profile mapping is inert unless that registered identity is selected for the
run; it does not supply a provider/model or activate a worker.

A project mapping uses one existing canonical absolute `directory`. Matching is
exact: there are no globs, prefixes, implicit parent matches, repository-name
matches, or project-local policy files. Duplicate, relative, missing,
non-directory, and symlinked entries fail closed. A mapping may select a profile,
model defaults/role overrides, implementation flow, enabled built-in specialists,
the workspace-capsule default, and version-4 exact-project custom specialists.
It cannot configure trust bypass, forced specialists, prompts, skills, tools,
writers, or reviewer authority. `customRoles` thinking must be an explicit
supported level, not `profile`.

Packaged thinking mappings are:

| Profile | Implementer | Reviewer | Probe | Playwright | Django |
|---|---|---|---|---|---|
| `economy` | `medium` | `medium` | `low` | `medium` | `medium` |
| `balanced` | `high` | `high` | `medium` | `medium` | `medium` |
| `thorough` | `xhigh` | `high` | `high` | `high` | `high` |

`thorough` is the compatibility default and preserves the old packaged values.
The checked simple/medium/multi-round profile baseline explicitly records
comparative provider usage and quality as unavailable, so it supports no
savings, equivalence, billing, recommended-default, or production claim. Run
`node scripts/execution-profile-baseline.mjs --check` to validate that evidence
availability record. Profiles change only thinking levels. They do not
select models, add/remove roles, change tool authority, skip required review,
alter result caps, or route workflow. For an explicitly selected custom role,
`THINKING=profile` opts into that identity's mapping in a user-global custom
profile. An explicit thinking level wins. Packaged profiles have no custom
mappings, and an exact project profile selection cannot configure a custom role.

Select a profile with `--profile NAME` or model-tool `profile`. Selection
precedence is per-run profile, exact project mapping, user-global
`defaultProfile`, then packaged compatibility default. Thinking and model
precedence is explicit per-role/all-role override, exact-project role override,
exact-project defaults, user-global role configuration, user-global defaults,
then the selected profile/package fallback. Explicit flow, specialist, and
workspace-capsule options override their project defaults. Dry-run, confirmation,
manifest v5, status, list, and Supervisor reads expose the external config path,
matched canonical directory, bounded profile metadata, and effective role
levels. Manifest v4 retains profile metadata; older project-mapping metadata is
reported unavailable.

The model tool's `models` action and `/or-models [query]` expose a maximum of 100
available model metadata rows from the current Pi registry, respecting scoped
models and never exposing authentication. Natural-language requests can use
`useParentModel` for the current Pi provider/model/thinking or exact `all` and
per-role `modelOverrides` after resolving ambiguous IDs with `models`.

### Model-guided preflight planning (opt in)

Use `/or-start --plan TASK`, model-tool `dynamicPlan=true`, or terminal
`start --dynamic-plan --authorize-planning --yes` to request one bounded model
decision before the ordinary dry-run preview. Terminal planning runs a private
one-request Pi RPC control adapter with no tools; task/context travel in a
mode-0600 request file, never argv. Planning authorization and launch
authorization are separate: `--authorize-planning` permits the provider call and
`--yes` permits launch. Omission of either fails before any call. A missing
`--authorize-planning` is rejected before Pi starts, so the terminal path shows
no candidate view. When the flag is already supplied, terminal human output
prints the exact accessible/scoped worker candidate set immediately before the
already-authorized call. That print is not another opportunity to decline.
Interactive confirmation remains the decline gate and shows the exact decision
service, selection source, candidate count, and bounded payload categories, then
the same candidate set. That set lists each provider/model and its
model-supported thinking levels, plus the candidate-set digest shared by direct
Jev and Pi fallback. It is not the decision-service identity and not an operator,
project, or global role lock. The printed section does not include task text,
guidance, credential values, or endpoints. Catalog identifier spelling is shown
as-is and is not treated as a credential. The `models` action remains the broader
available/scoped catalog. A second confirmation after validation shows selected
identities, locked custom contracts, exact model/thinking values, bounded
decision reasons, and operator constraints. Declining either interactive
confirmation, omitting either terminal flag, cancellation, malformed/oversized
policy or output, unavailable models, unsupported thinking, ambiguity, or
conflicting explicit constraints starts nothing.

### Independent planning scopes

`planningScopes` is a strict nonempty unique array drawn from `topology`,
`models`, and `thinking`, and requires `dynamicPlan=true`. All seven nonempty
combinations are supported. No static or planning default changes: **omitting
`planningScopes` with explicit `dynamicPlan=true` retains all three axes**,
including the existing approved exact candidate-pool boundary. An empty array
is invalid; use an ordinary static start to make no planning call.

- `topology`: choose optional built-in and allowlisted custom specialists only.
  Without it, the ordinary exact-project/per-run roster is fixed, including
  configured custom roles (or an explicit selected subset); mandatory writer
  and reviewer authority never changes.
- `models`: choose exact worker provider/model identities only inside that role's
  approved pool, unless an authoritative exact lock already resolves it.
  Without it, identities resolve deterministically for every eligible role,
  including specialists the topology planner may later omit.
- `thinking`: choose supported worker thinking levels only where policy or
  explicit overrides do not already lock them. Without it, effective thinking
  is fixed; incompatible model/thinking tuples fail rather than relaxing a lock.

Fixed values resolve in ordinary precedence order: per-run role, per-run all-role,
exact-project role/default, user-global role/default, profile thinking, then
packaged defaults. Explicit project/global/profile constraints also remain locks
on authorized axes. Packaged defaults **do not** silently restrict legacy
all-axis planning or enlarge its approved pool. When model planning is disabled,
those deterministic identities are authoritative fixed-axis locks, not model
candidates the service may change. Custom bindings always lock identity,
contract, and thinking. Role inclusion overrides and specialist tasks win over
policy; disabled-versus-required conflicts fail before the call.

Examples (task text still travels through private files):

```sh
# Topology only: policy models and thinking cannot change.
pi-tmux-agents start --task-file /private/task.txt --dynamic-plan \
  --planning-scope topology --authorize-planning --yes
# Topology plus thinking, with exact worker identities fixed.
pi-tmux-agents start --task-file /private/task.txt --dynamic-plan \
  --planning-scope topology --planning-scope thinking --authorize-planning --dry-run
```

Model tool: `dynamicPlan: true, planningScopes: ["topology", "thinking"]`.
TUI: `/or-start --plan=topology,thinking TASK`, or `/or-start --plan-scopes TASK`
for the seven-choice form. Cancelling the form starts nothing. Existing
`/or-start --plan TASK` remains the all-axis compatibility path.

Direct TypeSafe Jev and Pi fallback receive equivalent bounded axis-selection
questions only for authorized, unlocked axes. Fully locked assignments generate
no model or thinking questions; a fully locked roster gets one `locked_plan`
suitability question plus the `task_intent` recommendation question included in
every dynamic request. Both questions share the same single separately authorized
provider call with no retry/failover call; final launch confirmation remains a
separate step. Preflight authorization, immediate acknowledgement, preview, final
confirmation, terminal output, and retained reads
identify scopes, authoritative operator/policy locks, and decision source.
Planning v4 retains only bounded task-intent and scope/lock metadata, exact
assignments, bounded pool counts, usage, and binding digests, never
task/context/config/provider bodies. Its decision and start bindings include
intent, scopes, and locks; stale policy, catalog, preview, or intent/scope/lock
changes reject launch. Planning v1/v2 remain readable; retained reads label their
absent scopes and locks as unavailable (legacy record), never inferred planner
authority. This display does not change v2 admission's historical all-axis meaning.
Planning v3 remains readable and admissible with unavailable intent in that
record; fresh previews emit v4.

Decision-service precedence is:

1. direct TypeSafe `jev-latest` when authentication is configured through
   `/login typesafe` or the `TYPESAFE_API_KEY` environment fallback;
2. exact model-tool `decisionModel: {provider, model, thinking?}` selects a Pi
   chat model when TypeSafe authentication is absent;
3. exact `preferred` Pi identity from the strict user-global planner policy;
4. the first eligible Pi identity in the policy's ordered `fallbacks` array;
5. configured `noEligible: "static"` with explicit confirmation, or cancellation.

This is selection precedence, not automatic request-error failover. Once a
service is selected, authentication, transport, timeout, malformed-response, or
provider failures stop before launch and never trigger a second provider call.

The planner policy is stored in the `planner` member of the same authoritative
user-global `~/.pi/agent/tmux-orchestrator.json` model/profile configuration.
The planner member remains optional in version-4 and version-5 files.
Version 5 adds the separate strict `workerCandidates` policy described below;
broker-v1 is unchanged; new starts retain intent in manifest v10/v11 (legacy
v8/v9 remain readable). Existing configuration versions 1–4 remain valid
for ordinary starts and fully locked dynamic starts. A
separate legacy `~/.pi/agent/tmux-orchestrator-planner.json` file (or a configured
`PI_TMUX_ORCHESTRATOR_PLANNER_CONFIG` path) is no longer read as active policy:
while that file exists, dynamic planning fails closed with migration guidance,
regardless of whether the unified file has a planner member. Likewise, the retired
environment override fails closed. This deliberate stop prevents silent merging
or precedence selection when values conflict. Explicitly migrate desired values
into `planner` in the one authoritative file and remove the old file/override;
rename legacy `jevGuidance` to `dynamicGuidance` if needed. The unified
configuration combines existing model defaults with planner settings:

```json
{
  "version": 5,
  "defaults": {},
  "roles": {},
  "workerCandidates": {
    "version": 1,
    "all": [{ "provider": "provider-a", "model": "exact-worker-a" }],
    "roles": {
      "reviewer": [{ "provider": "provider-b", "model": "exact-review-worker" }]
    }
  },
  "planner": {
    "preferred": {
      "provider": "provider-a",
      "model": "exact-model-a",
      "thinking": "medium"
    },
    "fallbacks": [
      { "provider": "provider-b", "model": "exact-model-b", "thinking": "low" },
      { "provider": "provider-c", "model": "exact-model-c", "thinking": "medium" }
    ],
    "noEligible": "cancel",
    "dynamicGuidance": "Prefer the smallest useful roster. Balance declared token and cost efficiency against outcome risk: choose the least resource-intensive exact candidate whose listed capabilities are clearly sufficient for a correct, complete outcome, and avoid lightweight variants when their capability margin is uncertain. When authoritative catalog facts establish recency and otherwise-sufficient candidates show no clear advantage for an older option, prefer the more recent candidate; never infer recency, quality, coding skill, latency, or reliability from model names. Use deeper thinking only for ambiguous, security-sensitive, or high-risk work."
  }
}
```

### Approved exact worker-model pools

`workerCandidates` is an operator policy, not planner guidance or a ranking.
It is allowed only in root configuration **version 5**, with nested policy
**version 1**. `all` is required and nonempty. Optional `roles` accepts only
`implementer`, `reviewer`, `probe`, `playwright`, and `django`; a role pool
**replaces**, rather than extends, `all` for that role. Each pool contains 1–32
objects with exactly `provider` and `model`, each a nonempty whitespace/control-free
identifier of at most 256 characters. No globs, aliases, fuzzy matching,
thinking levels, names, credentials, endpoints, ranking, or extra fields are
accepted. Duplicate identities within a pool fail; reuse across pools is allowed.
There are at most 100 distinct configured identities, within the existing
64 KiB external-file bound. The resolved effective union, including locks and
custom bindings, is also bounded to 100 candidates.

Resolve precedence per eligible role: exact per-run role override (or explicit
all-role override), exact-project role/default lock, user-global role/default
lock, then that built-in role's pool or `all`. Thinking-only overrides do not
constitute exact provider/model locks. Packaged model defaults are not approval.
Custom roles retain their exact trusted bindings and cannot acquire a pool.
Exact locks may select an available identity outside a pool. Every configured
pool identity is checked against Pi's current available/nonempty scoped catalog,
even if a lock overrides its pool or a role is not selected; unavailable or
ambiguous identities reject planning before either provider call. A valid pool
with no combination compatible with a role's thinking constraint also fails
before planning. The decision model is looked up independently: it need not be
approved as a worker, and its identity does not expand the worker scope.

If `workerCandidates` is absent, every planner-eligible built-in role must have
an authoritative exact provider/model lock. Candidates are derived only from
those locks and eligible custom fixed bindings. An optional role still counts
if the planner could select it; disable it explicitly or lock it as well. If any
role is unlocked, the start fails before planning with the fixed
`approved_worker_pool_required` diagnostic and guidance to configure version-5
`workerCandidates` in the external `tmux-orchestrator.json` or exact
provider/model overrides for every eligible role. The model tool, `/or-start`,
and terminal start all preserve this guidance without exposing configuration
or provider bodies. It never silently exposes the full catalog. An
explicitly configured static/manual decision-policy fallback remains a separate
confirmed no-planning path, not a catalog fallback.

Both direct Jev typed choices and Pi fallback choices enforce the same
per-role membership; an identity approved only for reviewer cannot be selected
for implementer. Canonical thinking/capability/cost hints are projected only for
the resolved worker union. No recency, quality, or orchestration reliability is
inferred from names. Natural-language guidance cannot create or expand approval.
Planning-call confirmation shows bounded pool source/count per eligible role;
final confirmation and the immediate start acknowledgement show exact selected
provider/model/thinking assignments. Retained planning v4 adds bounded intent
metadata to selected scopes, authoritative locks, bounded pool source/count
metadata, exact assignments, and digests, not pool/configuration bodies. The
private topology v3 projection supplies the exact policy to preflight; do not
copy that configuration projection into status or handoffs.

**Migration:** retain existing fields, change the root version to 5, and add
reviewed exact pools using `/or-models` identities. Existing version-4 custom
bindings remain supported. Alternatively, keep versions 1–4 and supply exact
locks for every eligible role. Static/manual starts require no pool and retain
their existing precedence. Retained planning v1 in manifests v8/v9 stays readable;
it is not accepted as input for a new launch. Generate a fresh v4 preview.
Revalidation uses the original operator inputs, never planner-generated overrides
as approval, and rejects changes to pool policy/source, role membership, approved
availability, canonical capabilities, or resolved configuration after preview.
Changes to unrelated unapproved catalog entries do not expand eligibility.

`dynamicGuidance` is optional natural-language text in this same planner policy
object; it may also be `null`. Legacy `jevGuidance` is accepted only when the
canonical field is absent; explicitly migrate by renaming it, and never configure both.
Guidance expresses preferences such as roster economy, specialist thresholds,
model-cost posture, or thinking depth. Write these in terms of listed
capabilities, declared catalog cost hints, task risk, and outcome sufficiency.
Guidance is not a model allow/deny list: do not write “never use model X” or
“prefer model Y.” Apply hard model exclusions through exact approved
`workerCandidates` pools or Pi's authoritative model scope, or use exact per-run
role overrides. The current canonical capability
projection has no recency field, so planners must not infer model age from
names; a recency preference applies only when authoritative catalog facts
establish it. Both direct TypeSafe Jev and the Pi-chat fallback receive the
same bounded question/state projection, with guidance once in
`state.dynamic_behavior_guidance` under fixed subordinate hard-rule framing.
This also applies to omitted-scope all-axis compatibility requests. It cannot add roles/models, create an operator
model allowlist, direct selection by model name, alter authority, weaken locked
constraints, grant write access, remove review, or override validation. The
planning confirmation shows configured/default status and a short digest;
accepted planning provenance binds the full digest without retaining or
displaying the text. Missing or `null` guidance uses the packaged behavior.

Guidance is limited to 16 KiB within the existing 64 KiB unified
configuration-file limit.
Empty, whitespace-padded, control-character-bearing, or oversized guidance fails
before the planning call. The planner policy's existing external-path,
regular-file, non-symlink, UTF-8, and target-project exclusion rules protect the
whole file, including this field.

The Pi-chat planner's system prompt defines the exact question-answer response
contract and treats guidance in request state as subordinate preference; it does
not ask for worker role objects or repeat the guidance body. The common serialized
question/state projection remains under the existing 96 KiB UTF-8 limit;
overflow fails before either provider call rather than truncating candidate data.

`preferred` may be `null`; at most 16 fallbacks are accepted. The ordered list
may span enabled providers—for example exact Grok and OpenAI identities resolved
from `/or-models`—without constraining worker roles to that provider. Every candidate
must contain exactly a canonical provider, canonical model, and explicit `off`,
`minimal`, `low`, `medium`, `high`, `xhigh`, or `max` thinking level supported by
that model. Identities must be unique across preferred and fallback entries.
Unknown/duplicate fields, duplicate identities, partial entries, unsupported
thinking, non-regular/symlinked/oversized files, and
configuration files inside the target project fail closed. A missing planner
policy is the versioned empty `cancel` policy. `pi-tmux-agents --json planner-policy --project
/absolute/project` validates and projects the path, configured flag, bounded
identity policy, and dynamic guidance projection used by the parent extension;
it does not expose auth or endpoint data. Retained manifests, previews, status,
and dashboard output never contain the guidance body.

The policy's preferred/fallback identities configure only the Pi fallback path.
At runtime each configured Pi identity is matched exactly against Pi's bounded
available/scoped catalog and
its model-specific thinking support. An unavailable or unsupported configured
candidate is ineligible and the next configured entry is considered. Duplicate
catalog identities are ambiguous and reject the whole start. `noEligible:
"cancel"` rejects before a provider or orchestration call; `"static"` offers an
explicit no-provider-call fallback to the ordinary static/manual preview and
final confirmation. An unavailable or unsupported exact per-run override fails
immediately and never falls through to configured entries. Jev has already been
excluded at that point because TypeSafe authentication is absent. Pi decision-call thinking remains governed by the decision-model policy. Worker
thinking independently uses each exact catalog model's supported levels through
`max` where available; an explicit/project/global lock unsupported by that model
fails before the planning call.

Jev is not registered as a Pi chat model and needs no `models.json` entry or
additional package. The extension registers an auth-only provider so the key can
use Pi's native credential flow, while the bundled dependency-free adapter posts
one request directly to the fixed `https://api.typesafe.ai/v1/systemone`
endpoint with model alias `jev-latest`.
It expresses optional-role inclusion and exact worker model/thinking assignments
as bounded TypeSafe Choice questions. Rectangular unlocked roles keep independent
`model_` and `thinking_` Choices. Heterogeneous unlocked support uses one `tuple_`
Choice over exactly the eligible pairs; illegal pairs are not options and are not
recombined after the call. There is no 100×7 or 700-tuple product. Each Choice has
at most 255 options. That 255 is the generic TypeSafe Choice cap, not the approved-pool
pair ceiling. An approved pool has at most 32 identities, and current worker thinking
has seven levels, so the reachable eligible-pair ceiling is 224. The full 32×7 product
is rectangular and stays `model_` / `thinking_`; joint `tuple_` is only a non-rectangle,
at most 223 options. Each request has at most 255 questions, and the complete
request is at most 96 KiB serialized UTF-8 bytes. Approved pools remain 1–32
identities per pool and at most 100 distinct identities. Retained evidence is at
most 224 KiB, a byte cap distinct from the 224-pair ceiling. Planning measures an upper bound of that retained encoding and fails before HTTP,
without a provider call, retry, or omitted tuple, when the request cannot fit or
the reachable evidence cannot fit. The bound includes maximum-width Choice
probabilities and the largest derived support object across common providers,
references, and optional-role omissions. A five-role joint pool or a legal
multi-provider pool can therefore be unselectable even though every Choice is
within 255 options, the request fits in 96 KiB, and a one-hot answer would fit. Capability metadata is included once, canonicalized, and digest-bound.
Canonical capability objects and declared catalog cost hints are sent once as
`state.candidate_model_capabilities`. Instructions tell Jev to use that state,
choose the smallest sufficient listed combination, and never infer recency,
quality, coding skill, latency, or reliability from model names. The adapter
validates every returned answer and constructs the ordinary version-1 planner
decision deterministically. Direct TypeSafe Jev and the Pi fallback receive the
same operator-approved per-role candidate scope and canonical bounded capability
projection; neither transport can expand it.
The versioned Jev model returned by TypeSafe is retained as provenance;
`thinking: "off"` is the compatibility value because System One has no Pi
thinking level.
TypeSafe reports input/output tokens but not a monetary cost in this API, so
retained cost remains unavailable rather than estimated.

Configure the credential once through Pi's masked native prompt:

```text
/login typesafe
```

Pi persists it in the normal user-global credential store. Use `/logout` and
select `TypeSafe Jev Planner` to remove it. The orchestrator does not read the
auth file; it resolves the key through Pi's model registry only for a confirmed
planning call. For automation,
`TYPESAFE_API_KEY` remains an optional environment override and takes precedence
over the stored key.

The adapter trims and validates the resolved key, sends it only in the in-memory
Bearer header after explicit planning confirmation, follows no redirects,
performs no retry, bounds request/response bodies, and never includes provider
error bodies in surfaced failures. The key is never accepted in orchestrator
CLI/configuration, copied into orchestration state, logged, displayed, or
forwarded into broker or worker tmux environments. The endpoint and model alias
are not environment-overridable. Log out and unset the environment fallback to
exercise the configured Pi fallback path.

Before the provider call, the authoritative `planner-topology` boundary resolves
strict external model/profile/project configuration and freshly validates any
exact-project custom-role registry descriptors and pinned resources. The planner
state contains the bounded task, optional structured parent capsule, optional
bounded dynamic guidance, project identity, fixed
role/contract/authority descriptors, exact candidate
model/thinking/capability metadata, declared catalog cost hints, and explicit
constraints. Capability fields are identity, reasoning and supported thinking
levels, text/image input support, context window, max output tokens, declared
input/output/cache-read/cache-write rates and tiers, and prompt-cache retention
presence. Missing, zero, or malformed catalog numbers are explicit
`missing`/`zero`/`unavailable` values and are never coerced. It contains no
resource paths or bodies, credentials, endpoints, `baseUrl`, headers,
compatibility internals, unrelated custom configuration bodies, tools, or
configuration mutation surface. Declared rates are catalog hints, not billing,
observed spend,
quality, or runtime eligibility. Planners must choose the smallest sufficient
model from those technical facts and must not infer quality, coding skill,
latency, or reliability from model names. The Pi
fallback gets no tools and must return one strict JSON object in one bounded
attempt; Jev receives only typed questions and bounded state.

The decision must retain exactly one built-in implementer and the mandatory
built-in reviewer. It may add unique eligible probe, Playwright, and Django roles
and up to eight exact trusted custom specialists. Custom roles retain their fixed
probe/Playwright/Django contract and read-only policy. Registry presence alone
never makes a role eligible: it must also be allowlisted by the exact-project
`customRoles` map and pass fresh resource verification. `projectCustomRoles=false`
omits all such candidates; explicit `true` requires every eligible configured
identity, while omission lets the planner select a subset.

Every role must choose an exact available provider/model/thinking combination.
The candidate set may span multiple Pi-enabled providers, and each role may use a
different tuple. Precedence is explicit per-run role/model choices, exact-project
constraints, user-global constraints/defaults, accepted planner values, then
packaged fallback. Explicit enabled/disabled roles, forced selections, profiles,
and model/thinking constraints win. Unsupported, unavailable, duplicate,
over-cap, stale, or ambiguous choices fail before the provider call or before
launch; unsafe optional candidates are omitted without weakening mandatory
review. The accepted topology is fed through CLI dry-run, custom resource
revalidation, exact preview matching, and final model availability checks.
Before launch, the adapter rereads policy/topology configuration, recomputes the
eligible catalog and thinking support, and compares SHA-256 bindings for the
private task/context, canonical project, complete resolved start configuration,
planner policy, topology policy, and resolved candidate scope/source/role membership,
including digest-bound canonical capability metadata. Any changed task, config,
registry resource, catalog availability, capability/cost-hint metadata, selected
tuple, or preview projection
fails with no launch. The accepted record has a bounded request ID and cannot
admit duplicate tmux sessions; interrupted pre-launch requests retain no run
state. Temporary request/decision files are owner-only and removed on every
exit path. Cancellation, malformed output, and interruption before final launch
admission are preflight failures and therefore have no run directory to roll
back or retain; their operation result is cancelled/failed rather than accepted.
After final admission, the existing partial-start rollback kills only the exact
new tmux session, marks the retained startup failed, and does not rewrite the
accepted planning record.

New manifest schemas v10/v11 retain bounded task-intent metadata for admitted
change work and only body-free planning provenance: dynamic mode, accepted
status, decision model identity/thinking/source, selected exact role/model/thinking
tuples and fixed custom contracts, timestamps, request ID, and binding digests.
Legacy v8/v9 manifests remain readable with unavailable intent, not inferred
intent evidence. Supervisor run/session reads expose top-level `task_intent`
for new manifests in both static and dynamic modes; legacy intent is null/unavailable.
`list` and `status` JSON expose intent only within accepted planning-v4/v5/v6 metadata
for dynamic runs, not for static/manual or legacy planning records. Human
`list`/`status` output and the dashboard do not display task intent. These read
surfaces never retain or return the task, context capsule, planner prompt/reasoning,
provider response body, credentials, endpoints, or custom resource paths/bodies.
Static manifests report static/manual planning provenance; legacy dynamic
records remain dynamic with missing authority/evidence explicitly unavailable.

### Single-provider support gate

The same one separately confirmed dynamic call adds one `provider_support`
Choice (Pi fallback: the identical strict answer string), only if request-wide
single and mixed are feasible. Choose `none` for mixed or final locked/fixed
assignments. Otherwise choose exactly one canonical selector: `reasoning`,
`image`, `context_window`, `max_output_tokens`, `thinking`, `cache_short`,
`cache_long`, or `declared_cost`. This is a **planner applicability claim** that
the task and EVERY final role contract materially benefit, not reasoning or
model-free proof of task intent. No free text, name-based inference, unsupplied
facts, provider reputation, latency, recency, billing, or diversity benefit is
allowed. Operator intent still wins; non-change work redirects to the parent.

The deterministic gate requires a homogeneous assignment to select
`single_provider`, and derives the following conservative comparison against
**every eligible other-provider tuple for each selected role**, after all locks:

- Reasoning/image/cache presence: selected explicitly true versus alternative
  explicitly false. Cache missing means absent; unavailable means unknown.
- Positive declared context/output limit: selected at least **25% larger**.
- Thinking: selected level strictly above all alternative supported levels.
- Declared cost hints: positive declared input **and** output base rates at least
  **20% lower**, with no tiers on either side and no cache-rate tradeoff. Zero,
  unavailable, tier-dependent, or ambiguous cost comparisons do not qualify;
  no billing or observed-savings claim is made.

These are conservative admission thresholds, not empirical quality benchmarks.
A generic difference without the typed task-specific applicability claim is
insufficient. One common selector must cover all roles; no vacuous coverage of a
locked/custom role, omitted-role support, or role-local claim is accepted.
Mixed accepts `mixed_provider` or neutral and requires `none`; homogeneous
neutral fails closed. If only one composition remains possible for the final
roster due to exact locks/eligibility, support is `none`, **derived locked/fixed**,
not a planner justification (optional roster choices remain recorded as choices).

Planning v7/evidence v3 binds the support selector/applicability, exact
selected/alternative facts and thinking, composition, eligibility, catalog,
scopes/locks, assignments/contracts, and digests. Current catalog revalidation
happens after preview and before immutable launch validation. Full status and
snapshots expose the bounded references; list/Supervisor/dashboard/parent
projections distinguish derived support from selected Choice/confidence.
Unsupported support fails before preview/launch with an actionable bounded
reason: revise constraints, use exact overrides, explicitly choose static/manual
planning, or cancel. Model-tool, slash/TUI, and terminal/RPC starts preserve this
same safe guidance; tool and terminal errors identify `unsupported_provider_support`.
Only exact internal admission reasons receive this projection, never raw provider
errors or private support bodies. There is no second call, retry, implicit fallback,
or plan substitution. Legacy planning v1–v6 stays readable under its original contract;
legacy support is unavailable, not invented. No live call is authorized by these
model-free contract tests.

### Accepted-plan evidence

Fresh accepted previews use planning v7/evidence v3, compatible with manifest v10/v11. The
versioned evidence projection retains only canonical supplied metadata. Exact
preview/launch confirmation, persisted/reopened records, CLI JSON/human `status`,
Supervisor snapshots, and parent final updates expose selected confidence,
selected probability, and up to **three nonselected alternatives** for every
existing question. Dashboard rows and JSON `list` / Supervisor collection reads
use small digest-bound availability/source/provider-comparison and selected
provider-composition/confidence/alternative summaries; use
exact `status` or a Supervisor snapshot for full options and facts.

Direct TypeSafe Choice confidence is retained separately from the selected
option's probability; neither is treated as a calibrated success rate. All
validated option probabilities are retained as metadata to audit normalization
and top-k completeness. Alternatives sort by probability descending, then exact
canonical identity ascending (role/provider/model for model options; role/thinking
for thinking options; role/include-or-omit, intent, or suitability for other
axes). The sum must be within `1e-6` of one; values are finite and in `[0,1]`, and
are not renormalized. The chosen option need not be the highest-probability option.

Model and thinking questions are **independent marginal axes**, not a joint model/
thinking score, when the eligible set is a rectangle (every eligible model supports
the same unlocked thinking levels) or either axis is locked or singular. Model
options have `thinking: null`; thinking options identify every exact eligible
supporting provider/model and its fact digest, not an invented conditional score
for the selected model. The final selected tuple is validated separately.

When both axes are unlocked and thinking support is not a rectangle, that role
instead gets one `tuple_` Choice. Each option key is `m{base36 catalog index}_{thinking}`
and is exactly one eligible pair. Illegal pairs are not options. There is no second
call and no truncation: more than 255 eligible pairs, more than 255 questions, a
request that cannot fit in 96 KiB UTF-8 JSON, or retained evidence that cannot fit
in 224 KiB all fail before HTTP. The 255 Choice cap is generic. The reachable approved-pool
ceiling is 224 eligible pairs (32 identities × 7 thinking levels); that rectangle is not a
`tuple_` Choice, and the largest approved-pool joint Choice is 223 options. The 224 KiB
figure is the evidence byte cap, not a tuple count. The evidence measurement is an upper bound over
reachable maximum-width probabilities and derived support objects, not a flat pad.
That failure is legitimate even for a legal Choice set, including a multi-provider
pool whose one-hot answer would fit; planning does not drop pairs to squeeze under the cap. Approved pools remain
1–32 identities and at most 100 distinct identities; worker thinking policy is
unchanged. Capability objects are sent once. `compact-v1` replaces duplicated
composition candidate bodies with `candidate_indexes` into that copy only when the
canonical request exceeds 96 KiB and the projection still fits. It is a local wire
encoding, not a retry, a second digest, a provider call, or production wire
acceptance. Joint `tuple_` answers are planning v8 /
evidence v4. Rectangular and single-axis plans stay planning v7 / evidence v3.
A v7 record is never treated as joint confidence. v4 tuple probabilities are the
Choice distribution over eligible pairs, not a synthesized conditional probability
or a calibrated outcome probability. Decisions for an omitted eligible specialist
document questions answered, not an assignment or authority to launch that role.

Operator/policy locks and sole eligible options have `authority: fixed`, null
confidence/probability, and no alternatives; original scopes/locks show whether
the value was locked or deterministic singleton. `source: pi_selection` retains
Pi fallback choices but no confidence, probabilities, or fabricated one-hot
alternatives. Task intent records the recommendation separately from effective
operator authority. Fully locked requests retain the actual `composition`
suitability question when present. This legacy `composition` axis is distinct
from `provider_composition`.

The **same one authorized planning call** asks a strict orchestration-wide
`provider_composition` Choice only when both physical compositions are feasible:

- `single_provider`: exactly one provider across all finally assigned workers.
- `mixed_provider`: at least two providers across finally assigned workers.
- `no_material_preference`: no material preference between feasible single/mixed;
  permits mixed when both final compositions are feasible, not homogeneous support.

Feasibility uses per-role eligible model/thinking tuples **after locks**, mandatory
implementer/reviewer, optional built-in inclusion, and trusted fixed custom
bindings. A single-provider plan needs a common provider across required roles;
optional roles can be omitted. An eligible optional/custom specialist may make
mixed possible even when mandatory models are locked. When only one composition
is possible, no composition question is asked: evidence records that deterministic
fixed/locked selection with null probabilities, not fabricated planner confidence.
Catalog provider count alone is not authority. Questions/answers for omitted
roles never count as assigned providers. Mixed cannot be manufactured by including
an otherwise unnecessary specialist or by overriding a lock. Final roster and
exact tuples are validated jointly with composition **before preview** and launch.

Both TypeSafe Choice and Pi fallback use the same field, facts, and semantics.
Pi selections have unavailable probabilities. The provider/model-name-neutral
question permits only canonical supplied capabilities, declared catalog cost
hints, task/context constraints, role contracts, and locks. It never infers quality,
reliability, recency, latency, or billing from names or assumes diversity improves
outcomes. Strict canonical feasible-option facts, capability digests, selected
composition, confidence, and alternatives are retained and stale-bound. These
are bound with the required same-call support Choice and independently derived
comparisons below; no private rationale is retained.

`provider_comparison` identifies `homogeneous` or `mixed`, with explicit
`rationale: rationale_unavailable` in both cases. This is **not Jev reasoning**
and does not claim causal preference, coding quality, reliability, latency,
measured cost, or savings. Capability/cost facts are the exact bounded non-secret
projection supplied to the planner, not billing or observed runtime evidence.

Evidence is capped at 224 KiB, 100 catalog candidates, 13 eligible roles, 43
decisions, and three displayed alternatives per probabilistic decision. A joint or multi-provider
plan whose measured reachable evidence exceeds 224 KiB fails before HTTP and is
not selectable, even when a one-hot answer would fit; there is no truncation or second call. Planning
files are capped at 256 KiB; manifests containing planning v5/v6/v7/v8 use the bounded
1 MiB serialized-manifest ceiling (older/static manifest limits are unchanged).
Canonical fact digests use a domain-separated binary64 numeric encoding so
JavaScript/Python formatting differences do not change declared cost bindings.
Candidate-set, decision, and accepted-start digests bind evidence to exact facts,
eligibility, scopes/locks, selected assignments, input/config, and confirmation.
Digests provide integrity/staleness checks, **not provider signatures or proof of
hidden reasoning**. Invalid fields, duplicate keys/options, noncanonical ordering,
non-normalized maps, oversized records, mismatched facts, or stale evidence fail
closed before tmux/worker launch.

Planning v1–v4 and older manifests remain readable with evidence explicitly
unavailable. Planning v5/evidence v1 remains readable with its existing suitability
axis but provider-composition decision authority unavailable, not reconstructed
from launch providers. Existing admission compatibility is preserved. Planning v6/evidence v2 remains readable with support unavailable. New v7
records require evidence v3, composition decision/facts and support metadata; mismatched version
pairs or omitted composition evidence are invalid. New v8 records require evidence v4 and are
used only when a joint tuple axis is present; v7/v3 remains valid and is not a joint-confidence
record. Limits: 100 catalog candidates, 32 identities per approved pool, 255 generic Choice options,
255 questions, 96 KiB request JSON, 224 KiB evidence, and 256 KiB planning records.
The reachable approved-pool pair ceiling is 224 (32 × 7 thinking levels) and is rectangular;
joint `tuple_` from that pool is at most 223 options. 224 pairs and 224 KiB are different caps.
Choice, question, request, and evidence overflows all fail before HTTP. Planning v8
manifests use the same 1 MiB ceiling as v5/v6/v7. Static runs never
fabricate planner evidence. No task, prompt, context, guidance, endpoint,
credential, raw response, provider error body, or hidden reasoning is retained.
The stopped #174 attempt yielded no accepted plan: this feature cannot recover or
diagnose its absent response. No new live planner call is authorized here.

Dry-run previews return accepted metadata but write no coordination state.

Deterministic specialist activation remains authoritative after launch; the
planner cannot force it. The model tool reports nested planner usage to Pi's
tool-result accounting. No provider-cost, latency, role-selection, or quality
benefit is claimed without the separately reviewed evaluation in #174.

### Budget policy

The strict version-1 user-global file
`~/.pi/agent/tmux-orchestrator-budgets.json` has this shape:

```json
{
  "version": 1,
  "enforcement": "warn-only",
  "warning": {
    "run": { "operational_tokens": 600000 },
    "role": { "operational_tokens": 200000 },
    "assignment": {}
  },
  "hard": {
    "run": {},
    "role": {},
    "assignment": {}
  }
}
```

`PI_TMUX_ORCHESTRATOR_BUDGET_CONFIG` may select another absolute path outside
the target project. The scopes are run, role, and assignment. Allowed metrics
are `provider_calls`, `input_tokens`, `output_tokens`, `cache_read_tokens`,
`cache_write_tokens`, `reasoning_tokens`, `operational_tokens`, `cost_total`,
`context_tokens`, and `context_percent`. Integer thresholds are 1 through
1,000,000,000,000; cost is at most 1,000,000,000; context percentage is at most
100. Values must be positive and finite. Unknown/duplicate fields, credential or
endpoint fields, unsafe files, and warning thresholds above matching hard
thresholds fail closed. `null` disables an inherited file threshold.

Precedence is per-run CLI/model-tool override, user-global file, then packaged
warn-only defaults. CLI starts use `--budget-enforcement warn-only|hard` and
repeatable `--budget-override LEVEL.SCOPE.METRIC=VALUE`; `=off` disables one
inherited threshold. Overrides cannot repeat a threshold and are bounded by the
60 possible level/scope/metric combinations. The Pi tool uses a native
`budgetOverrides` object. Dry-run
and confirmation metadata show the fully effective policy without payloads.
New broker databases retain that numeric/enum policy. Both `warn-only` and the
compatibility `hard` mode are observational: no configured threshold changes
workflow routing, blocks a tool, or interrupts a provider response. Missing
provider values remain unavailable and never produce invented threshold facts.

The worker bridge observes assignment-scope `provider_calls`, `context_tokens`,
and `context_percent` at supported Pi tool boundaries. Provider calls are
counted from the accepted assignment baseline. The first proven warning adds one
bounded instruction to the next non-report tool result. A crossed hard threshold
records a higher-severity fact but leaves every sequential or parallel tool,
including `orchestrator_report`, available. Facts are immutable assignment-local
numeric metadata visible in status, the dashboard (`G~` warning or `G!` hard),
and Supervisor snapshots.

Direct native-TUI steering and authenticated `send` remain normal operator
choices; neither needs to bypass a budget. The operator decides whether to ask
for a report, continue, restart, or stop. There is no live budget-resume command
because thresholds never pause work. A worker restart restores warning/hard
markers from its exact Pi session and cannot silently reset the assignment
provider-call count.

### Repair-round continuation limit (opt-in)

`start --max-repair-rounds N` caps additional implementation rounds across the
whole run. Omission disables the cap; `0` permits the initial implementation and
mandatory review but pauses before the first repair. A round counts when its
implementation assignment is created, including uncertain/failed delivery.
Phased plan/implementation within round 1 counts as the initial work; specialist
and review assignments are not repairs. Post-ready operator follow-ups also count
as additional implementation rounds. Counts never reset on worker restart.

This is separate from observational warning/hard budgets. It does not bound an
in-flight assignment, provider calls, tool calls, or exact token expenditure.
The supported range 0–1000000 is a validation bound, not a recommended allowance.
No numerical execution limit is enabled by default.

At the cap the broker retains `pending_repair_round`, emits
`continuation_paused`, and enters `needs_attention` without starting the repair.
The result is incomplete, not approved. `status` and Supervisor snapshots expose
`workflow.continuation`; the dashboard labels the repair limit. Parent observers
receive the existing attention event; inspect status for the specific reason.
Ordinary `send` cannot resume this idle, unassigned worker.

To explicitly authorize **one** additional repair round:

```sh
pi-tmux-agents continue SESSION --yes --command-id YOUR_32_LOWERCASE_HEX_ID
```

Choose a new idempotency key for each new approval; reuse the exact key on retries.
The broker persists approval and command identity before assignment delivery.
Duplicate approvals do not extend the cap again. The existing run-wide count is
preserved and the cap increases by one; required independent review still follows.
Acknowledgement is not completion. A crash during delivery becomes uncertain and
must not be blindly replayed. Whole-broker restart loses in-memory evidence;
continuation without the retained in-process worker baseline fails closed rather
than reconstructing private report bodies from metadata. Inspect status/recovery
before deciding whether to stop and start a newly authorized run.

The Pi `/or-start` form also accepts the cap as a decimal integer: blank disables
it, and Escape cancels the start. This input is independent of the project-default
override selection. Model-tool starts accept optional integer `maxRepairRounds`
(not a string or null). Both paths forward the same cap through CLI preview and
launch; the start confirmation shows the CLI-resolved policy.

Continuation approval remains terminal-CLI-only; there is no model-tool action
or slash command to approve it. These controls do not alter installed defaults
or authorize an agent to approve its own continuation.

### Worker context retention (opt-in)

`start --worker-context reviewer=retain` keeps that role's prior assignment
instructions and assistant/tool history in provider context, to allow related
investigation to be reused. Repeat the flag for different enabled roles.
`ROLE=prune` explicitly selects the existing behavior; unmentioned roles default
to `prune`. Unknown/disabled roles, duplicate selections, and modes other than
`retain`/`prune` are rejected. There is no project/global setting or automatic
relevance classifier in this slice.

Both modes keep current-assignment turns, direct user/operator guidance, and
unknown custom messages. Both replace superseded baseline/run-state capsules.
Retain keeps complete historical assistant/tool exchanges rather than selecting
individual results that could lose call/result pairing. It can increase context
size and cost; no savings are established. Prior checks and approval are historical
evidence, not current approval: changed code or requirements require fresh checks
and every implementation still goes through mandatory independent review.

The CLI preview and `status` expose metadata-only `worker_context_policy`
(version 1, explicit per-role `overrides`; omitted roles mean default prune).
The broker stores it before launch. Both native TUI and RPC launchers restore it
on restart, overriding any ambient context-mode environment value. Missing policy
in schema 10 or malformed retained policy fails closed; schema 9 and older retain
the existing prune behavior. The shared bridge applies its launch selection on
every provider request without rewriting Pi history or changing run accounting.

Pi tool starts accept `workerContext: { reviewer: "retain", implementer: "prune" }`.
The `/or-start` form accepts comma-separated overrides such as
`reviewer=retain, implementer=prune`; blank keeps default pruning and Escape cancels
the start. Selections do not enable optional roles: the CLI rejects disabled roles.
Both paths forward identical selections through preview and launch. Confirmation
shows CLI-resolved overrides plus the cost/verification warning; an explicit choice
that is missing or mismatched in preview blocks launch.

The selection is fixed for that role for the run. Live switching, bounded batch
selection, semantic check-result reuse, and compact/fresh worker sessions remain
follow-up slices. No checkpoint, summary, provider call, extra assignment, or
session rotation is generated by this control.

### Bounded investigation-reuse hints

Explicit `retain` roles receive an advisory reuse section in their rolling
run-state capsule. The broker keeps at most one in-memory observation per known
role alongside the existing latest reports; it does not create another report
history or persist receipts, worktree inventories, or bodies. Default `prune`
runs do not run these observations or receive new hints.

At report acceptance and again before delivering a retained role's next assignment
(or handover), the broker compares Git HEAD/index and tracked/nonignored file
metadata: identity, mode, size, and nanosecond modification/change timestamps.
Two matching inventories are required for an observation. File bodies are never
read for this feature. Inventory output is capped while reading (256 KiB per Git
command), at most 4096 files are observed, and both inventories share a two-second
observation deadline (filesystem system calls themselves cannot be interrupted).
Missing Git/HEAD, non-root projects, submodules, symlinks, detected races, or excess
size yield `unavailable`, not a guessed fresh result. Ambient Git overrides cannot
redirect the inventory.

The section labels each latest role report as `metadata_unchanged`,
`worktree_changed`, `guidance_changed`, or `unavailable`. Authenticated broker
operator sends invalidate all earlier observations before delivery. Whole-broker
restart loses observations and cannot reconstruct them from durable metadata;
worker handover rechecks the tree rather than replaying an old reuse hint.

**These are not content digests or proof that a check remains valid.** Ignored
files, external services/dependencies, tool versions, and guidance entered directly
in a worker pane are unobserved. Even unchanged metadata only makes investigation
a candidate for reuse after checking its scope; historical passes/approval never
substitute for required checks or independent review. Revalidate observations before
relying on them. Changes/unavailable evidence require reinspection.

Hints are appended after required report evidence within the existing 16 KiB
capsule limit; if they do not fit, absence does not authorize reuse. No classifier,
hidden summarizer, skipped role, approval shortcut, or fresh-session action is
introduced. Provider savings and semantic verification reuse remain unproven.

### `start`

Creates a detached tmux grid with an implementer, reviewer, broker/status
monitor, and optional probe, Playwright, and Django roles. The monitor is an
in-place, event-driven dashboard with full, compact, and narrow layouts. A NOW
flow line names the active worker, a bouncing `LIVE` activity bar (not
completion), and the waiting next role. Worker turn, stream, tool, and report
events update the authoritative phase marker; phase *changes* also appear on
the metadata event rail. During loading or active work in an interactive pane, a
bounded 250ms local ticker animates the presentation marker from cached metadata
without polling the broker or changing phase, reports, usage, or event history.
Starting, connecting, and initializing show a `LOADING` spinner before worker
streaming begins. Static states and non-TTY output suppress animation. The monitor
does not tail worker output or wait for a handoff.

Required:

- `--task TEXT` or `--task-file PATH`

Common options:

- `--project PATH`
- `--session NAME`
- `--implementation-flow single|phased`: override the exact-project compatibility/simple or bounded inspect/plan default
- `--profile NAME`: packaged or strict user-global execution profile; overrides an exact-project selection
- `--context-capsule TEXT` or `--context-capsule-file PATH`: optional bounded parent recap
- `--workspace-capsule` / `--no-workspace-capsule`: override the exact-project cold-assignment experiment default
- repeatable `--workspace-relevant-path PROJECT_RELATIVE_PATH`: bounded existing parent-supplied hint; requires the experiment
- `--approve-project`: separately confirmed Pi trust bypass for inspected projects
- repeatable `--worker-skill ROLE=/absolute/path/SKILL.md`: explicit reviewed per-role skill opt-in
- `--with-probe` / `--without-probe` and optional `--probe-task[-file]`
- repeatable `--force-specialist ROLE` for an enabled built-in or selected canonical custom specialist
- `--with-playwright` / `--without-playwright` and optional `--playwright-task[-file]`
- `--with-django-expert` / `--without-django-expert` and optional `--django-task[-file]`
- `--rpc-workers`: headless RPC event panes instead of interactive TUI panes
- `--attach`
- `--dry-run`
- `--skip-model-check`
- `--dynamic-plan`: opt into the shared bounded planner before preview
- `--planning-scope topology|models|thinking`: repeat to authorize a nonempty unique combination; omission retains all three axes
- `--authorize-planning`: authorize that one additional provider call (required with `--dynamic-plan`). A missing flag is rejected before Pi starts and shows no candidate set. When supplied, the set prints immediately before the already-authorized call and is not a second decline gate
- `--yes`: separately authorize launch after the validated dynamic preview (required with `--dynamic-plan`)
- `--decision-provider`, `--decision-model`, and `--decision-thinking`: exact per-run decision identity override; provider and model must be supplied together
- `--allow-static-fallback`: permit only the configured `noEligible: "static"` no-provider fallback
- `--budget-enforcement warn-only|hard`
- repeatable `--budget-override LEVEL.SCOPE.METRIC=VALUE` (`=off` disables one)

Model arguments use `--ROLE-provider`, `--ROLE-model`, and `--ROLE-thinking`.
Thinking levels are `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, and
`max`.

The model tool accepts a structured `contextCapsule` with optional current
state, settled decisions, constraints, acceptance criteria, relevant paths,
known evidence, open questions, and out-of-scope arrays. The invoking parent
synthesizes it from context already present in that Pi turn; no summarizer agent
or additional model request is used. The rendered capsule is at most 12 KiB.
Do not copy a transcript, prompts, provider bodies, credentials, logs, or diffs.
CLI callers may provide equivalent reviewed Markdown with the capsule options.
The start confirmation shows only presence and character count.

#### Experimental workspace capsule

The disabled-by-default CLI flag above and model-tool `workspaceCapsule: true`
select the same behavior for native TUI and headless RPC workers. The tool's
`workspaceRelevantPaths` and repeatable CLI option accept at most 16 unique,
normalized, existing project-relative paths of at most 256 UTF-8 bytes each.
Paths without the opt-in flag are rejected. The slash-command TUI asks the same
explicit experiment question and optionally accepts one path per line.

Construction requires the supplied project to resolve to a canonical,
non-symlink Git worktree root with an existing HEAD. The 8 KiB schema contains
exactly:

- schema version 1 and a SHA-256 identity of the canonical root;
- initial Git HEAD and a `clean|dirty` observation; no diff, untracked-file
  content, or complete tree is copied into the capsule;
- at most 16 project-relative governing instruction paths and SHA-256 hashes,
  never instruction contents;
- regular-file names selected from a fixed 16-name top-level build/test marker
  allowlist; and
- the sorted parent-supplied relevant paths.

The constructor directly probes only the allowlist and instruction candidates
at the root and ancestors of supplied relevant paths. It never enumerates or
serializes a complete repository tree; Git may inspect the worktree internally
to produce the clean/dirty observation. Every path component is checked with
non-following metadata; absolute, `..`, missing, duplicate, non-normalized,
unknown, symlinked, count-overflow, byte-overflow, invalid UTF-8, and oversized
instruction files fail closed. Marker and instruction candidates that are
symlinks also reject construction. Canonical-root identity is a trust binding,
not authorization.

Pi context discovery stays enabled: no `--no-context-files` flag is passed.
Capsule paths/hashes supplement the baseline but do not authorize a path or
substitute for workers discovering and reading `AGENTS.override.md`,
`AGENTS.md`, or `CLAUDE.md` and their referenced/scoped instructions through
Pi/project mechanisms. Instruction precedence mirrors Pi's candidate order for
the directories touched by relevant paths.

The CLI rebuilds the capsule on each dry-run and confirmed start. The broker
validates its exact shape and current root/HEAD/instruction/marker/relevant-path
identity when reading the transient startup payload, immediately before initial
baseline delivery, and before any live in-memory baseline replay. Mismatch is
rejected as stale. Clean/dirty is explicitly an initial observation rather than
an invalidation key: normal implementation edits do not break late delivery or
restart replay while HEAD and discovery hints still match. A changed HEAD,
instruction identity, marker set, missing path, or new symlink makes a restart
handover/workflow `uncertain` instead of replaying stale hints. Broker-process
recovery after startup deletion has no capsule cache to reconstruct or trust.

The capsule exists only in the mode-`0600` transient startup payload, live broker
memory, and worker baseline/Pi session context. Initial routing deletes the
startup copy. It never enters the retained manifest, SQLite, status, dashboard,
Supervisor API, RPC registry/journal, project files, or any cross-run cache.
Adding cross-run persistence would require a separately reviewed explicit
privacy, retention, and invalidation policy. Public dry-run/confirmation output
is limited to enabled/disabled, schema, validation, counts, bytes, and digest;
no capsule path list or body is exposed. Existing manifest v1-v4 readers remain
compatible.

A new baseline body may alter a provider's cache prefix, and provider-specific
serialization/cache boundaries can outweigh local byte proxies. The checked
synthetic Python and Node fixtures report exactly 733 and 886 UTF-8 workspace-hint
bytes added by the capsule; disabled runs add zero. Conceptual worker discovery
operation proxies change 4→2, while capsule construction is reported separately
as 39/53 operations. Serialized worker discovery-result bytes remain unavailable
because the fixture does not fabricate tool/model transcripts or use a complete
repository-tree baseline. Provider calls, provider tokens/cost, reviewer findings,
checks, revisions, and correctness are also explicitly unavailable. The fixture
therefore proves neither savings, provider-call reduction, nor correctness
equivalence and cannot justify a default change or progression beyond the opt-in
experiment:

```bash
python3 scripts/workspace-capsule-baseline.py --check
```

Worker skill discovery is disabled by default for both TUI and RPC starts. The
CLI option above and the model tool's `workerSkills` object are the only new-run
skill opt-in surfaces. A selected role must be enabled; each Markdown file must
be a non-symlink readable UTF-8 file no larger than 256 KiB, with at most eight
skills per role. The start preview lists exact paths and private manifest
metadata binds each path to its reviewed SHA-256 digest. Worker launch and
restart fail closed if a selected file disappears or changes. Skills cannot
expand a role's tool allowlist, so read-only roles stay without `edit`/`write`.

Workers replace Pi's general coding prompt plus appended role prompt with one
lean role prompt (`--system-prompt`, not `--append-system-prompt`). The stable
common prefix contains active-tool guidance before role/project-specific
authority and safety rules. Pi still appends governing `AGENTS.md`/`CLAUDE.md`
context and any explicitly selected skill. Pi 0.87.1 normalizes a missing
append to an empty string; the live check treats that as absent rather than as
appended role guidance. The equality gate is that lean-prompt contract plus the
orchestrator-owned reviewer prompt size. Pi's default coding-prompt size is
owned by Pi and is recorded only as a last observation: on 0.87.1 the
model-free built prompt measured 5,046 before and 2,482 after normalized
reviewer characters (50.8%). Those figures are serialized prompt-size proxies,
not provider tokens, cost, cache efficiency, or production acceptance, and they
must not be used to silence a semantic contract failure.

Workers inherit the user-global Pi `cacheWarming` setting. The Pi default is
`streaming` during active runs; `idle` warming between runs is not the default.
Cache-warm usage is a non-context session entry and is not counted as a worker
provider call. Waiting workers can refresh eligible caches only if idle warming
is enabled globally.

#### Implementer inspect/plan reports

A broker assignment whose retained role/kind is `implementer`/`plan` switches the
shared worker bridge to `read,bash,grep,find,ls,orchestrator_report`. Edit, write,
and any other non-plan tool call are removed and blocked until the terminating
plan is accepted; restart reapplies this policy from the retained assignment.
`bash` remains available for bounded inspection and is not an OS sandbox, so the
worker is also explicitly instructed not to modify the worktree.

The report requires exactly `kind`, `summary`, `relevant_paths`,
`relevant_symbols`, `intended_changes`, `required_checks`, `risks`, and
`open_questions`. Summary is at most 1,000 characters; each array has at most 12
strings of at most 300 characters; paths are relative; the canonical result
remains at most 32 KiB. Changed paths, executed checks, findings, limitations,
approval, and verdict fields are invalid. The broker also verifies that report
kind matches the active assignment before atomically accepting one report.

The latest plan is projected into the rolling run-state capsule. Only existing
kind/count/usage metadata enters SQLite or Supervisor/status output; the plan
body remains ephemeral/Pi-session state.

`--implementation-flow phased` and model-tool `implementationFlow: "phased"`
select this path for complex tasks. Plan acceptance first delivers the latest
bounded run state, then creates a distinct same-round `implementation`
assignment. The worker bridge retains a newer assignment that arrives while the
terminating plan tool awaits its broker response, so no acknowledgement-only
provider turn is needed. At the next provider request, inspection assistant/tool
turns are pruned; baseline, accepted plan, direct steering, and current
implementation turns remain. `single` is the compatibility default and starts
directly with implementation. Reviewer-requested repair rounds also start
directly with implementation and receive the latest reviewer/specialist state.

The fixed six-read synthetic fixture reports 49,462 to 671 serialized
characters at the first implementation request, a 98.6% context-size proxy
reduction. It explicitly records provider calls, provider tokens/cost, failed
checks, and missed findings as unavailable and makes no savings or quality
claim. Validate it with
`node scripts/phased-implementation-baseline.mjs --check`.

#### Specialist activation gates

Enabling a specialist configures it; it does not mean every deterministic skip
predicate must wake it. The broker uses no extra model call and stores no task or
path body in its decision state. Rules are fixed and versioned:

| Role | Run | Skip |
|---|---|---|
| probe | forced; initial high-risk task terms; ambiguous task/path evidence; non-documentation repair paths | clear initial docs/typo task or docs-only repair paths |
| playwright | forced; browser/frontend suffix; empty or ambiguous non-documentation paths | docs-only changed paths |
| django | forced; Django file/directory marker; empty or ambiguous paths | docs-only or clearly frontend-only changed paths |

Initial probe classification uses the ephemeral task before startup payload
deletion. Later decisions use the bounded implementation `changed_paths` array.
Unknown, empty, or malformed evidence runs the configured role. Repeat
`--force-specialist ROLE` or pass model-tool `forceSpecialists` only for enabled
roles that the operator explicitly requires. Forced roles always produce an
actual report before reviewer assignment; no deterministic skip can satisfy
that requirement.

SQLite activation rows and public projections contain only role, round,
`run|skipped`, versioned identity-prefixed rule ID, forced boolean, and derived
`per-run-force|deterministic-contract-rule` source (`legacy-always-run` only for
retained v6 custom runs). The rolling capsule adds the same bounded
decision and `required|reported|not-required` evidence status. The reviewer
therefore sees which configured roles ran or were skipped without receiving a
classifier prompt or persisted task/path content. Probe and Playwright reports
remain synthetic/local evidence and cannot claim production acceptance. The
checked docs/frontend/Django/empty-path fixture covers the three built-ins plus
one contract-bound custom specialist and selects 11 of 16 configured assignment
opportunities, a 5-assignment proxy reduction. Provider calls,
tokens, cost, and quality are explicitly unavailable; validate the no-claim
fixture with `python3 scripts/specialist-activation-baseline.py --check`.

#### Worker result-volume limits

The worker bridge, and not ordinary Pi, applies these fixed orchestration-only
limits in both TUI and RPC modes before a result reaches the next provider call:

| Tool | Input default/cap | Emitted result cap | Retention/guidance |
|---|---|---|---|
| `read` | `limit=400`; explicit larger limits become 400 | 16 KiB and 400 lines, head | next targeted `offset` and `limit<=400` |
| `grep` | `limit=40`; `context<=2` | 16 KiB and 240 lines, head | refine pattern/path/glob; use `read` for exact lines |
| `bash` | unchanged | 24 KiB and 400 lines, bounded head + failure diagnostics + tail | mode-`0600` full-output file or Pi's existing path; inspect a targeted slice |

The byte cap includes the continuation notice. UTF-8 truncation does not split a
multibyte character. The bash diagnostic excerpt recognizes bounded failure,
error, assertion, fatal, panic, and `not ok` lines so a large successful-looking
prefix or tail does not hide safety-critical test evidence; the command ending
is retained as well.

Private Pi session entries record schema version, assignment ID, tool/direction
enums, truncation/input-cap booleans, and numeric source/emitted line and byte
counts. If the immediately following tool is another read page or a refined
grep, a second metadata entry records only that classification. Paths, search
patterns, commands, result bodies, logs, and full-output contents are not copied
into metadata, SQLite, status, the dashboard, or Supervisor output.

The checked synthetic result-volume baseline reports 144,491 before versus
89,733 after serialized UTF-8 provider-context bytes (37.9% reduction), while
read and grep pagination add two provider calls across the three scenarios:

```bash
node scripts/result-volume-baseline.mjs --check
```

This is a deterministic context-size and call-count proxy, not provider tokens,
billing, quality evidence, or production-wire acceptance. Tune a future policy
only with this benchmark plus retained metadata and real provider/quality
evidence; missing provider data remains unavailable.

All newly started runs use broker protocol v1. `--rpc-workers` does not select a
different coordination protocol. RPC panes are a plain headless automation
view; interactive TUI panes are the default and retain Pi's native highlighting,
tool rendering, and input editor for direct steering.

### `dashboard`

`/or-dashboard` opens a bounded Pi-native overlay containing
every running managed orchestration and a compact local About footer with the
installed version, repository, issues, npm, and contribution details. Opening
and refreshing load the session list but never run doctor. Session rows show
workflow/round, selected profile, linked roles, provider calls, operational
tokens, provider-reported cost when complete, and current context pressure when
available. Unavailable provider fields remain unavailable rather than estimated.

Use arrows or `j`/`k` to select, Enter to watch and attach, `x` to confirm stop,
`r` to refresh sessions, `d` to explicitly run and toggle doctor, `?` for help,
and `q`/Escape to close. Refresh is explicit; the overlay starts no timer or
background poll. Attach requires the invoking Pi to be inside tmux. Pi's current
public overlay API does not route row-click callbacks to extension components,
so true mouse activation is deferred.

### `list`

Lists live tmux sessions marked as Pi Tmux Orchestrator grids. The Pi dashboard
uses this projection directly. Omitting `[SESSION]` from `/or-send` or `/or-stop`
opens a selector populated from the same metadata-only list. Each option shows
the exact session and project; invalid orchestration metadata is excluded.
`/or-send` then reads that exact run's status and offers only its enabled roles,
including retained custom identities. Missing/invalid role metadata fails closed;
it does not fall back to the global role registry or offer disabled specialists.

### `status [SESSION]`

Shows bounded pane metadata, broker workflow state, role lifecycle, actual
provider token totals when available, and context pressure. The live broker
pane presents the same metadata hierarchy with a NOW active→waiting flow line,
exact configured provider/model/thinking values, assignment/generation where
available, assignment-bound live phase and pulse metadata, soft-budget warnings,
assignment guardrail markers, a bounded metadata-event rail including phase
changes, and attach/status/stop help. Healthy/success is green, active is cyan,
attention/budget is yellow,
error/uncertainty is red, and secondary metadata is dim. `NO_COLOR`,
`TERM=dumb`, and non-TTY output remain plain. Neither view prints workflow
payload bodies. See [broker dashboard design](dashboard-design.md) for the
operator hierarchy, wireframe, responsive contract, and omissions.

### `attach [SESSION]`

Switches the existing tmux client when already inside tmux or attaches from
outside. JSON mode is allowed only for the in-tmux `switch-client` path used by
the Pi extension; it never attempts to replace or suspend the invoking Pi
process. Prefix then `L` is the detach/return operation: it switches that exact
client back to the invoking Pi while leaving the worker grid running and without
changing the Pi's original project context. Attach observes future workflow
transitions, but an existing initial `ready`, `uncertain`, or `needs_attention`
state produces only bounded non-triggering progress; historical reports are not
replayed as a new parent task. Use explicit model-tool `watch` when the current
Pi should assess an existing actionable outcome. Reattach with the same `attach`
command.

### `send SESSION --role ROLE --message[-file] ...`

Sends one operator message through the authenticated broker bridge. `steer` and
`follow-up` delivery are supported. A successful response acknowledges
acceptance; completion is observed through lifecycle/events.

Control/event parsers accept canonical custom identities and require exact target
manifest membership. Explicitly selected registered custom roles retain read-only
specialist authority; messages cannot grant writer tools, reviewer acceptance, or
continuation approval.
Retained status/Supervisor custom role records include the specialist contract and
`resource_verification: not_checked`, without reopening resource files or exposing
resource paths/bodies. See [custom role surfaces](custom-roles.md).

If the workflow is already `ready`, an accepted implementer message
conservatively opens exactly one new implementation round: the broker queues the
latest run state and operator message without an unassigned provider turn,
creates the implementation assignment, and requires normal specialist routing
and mandatory review again. Retry of the same command ID does not open another
round. Messages during an active workflow retain normal steering behavior. When
the workflow is `needs_attention`, a send must target a waiting role that still
owns the active assignment; other role sends are rejected so they cannot mask
the unresolved assignment or trigger an unassigned provider turn. The workflow
returns to `active` only when that assigned worker reports lifecycle `active`.

Use `--command-id` with a 32-character lowercase hexadecimal ID for retry-safe
deduplication. Conflicting reuse is rejected. An interrupted unprovable delivery
is `uncertain` and requires explicit retry.

### `abort SESSION --role ROLE`

Requests broker-bridge abort for either TUI or RPC presentation. Abort acceptance
does not prove the provider operation reached a terminal state.

### `restart SESSION --role ROLE ... --yes`

Respawns one role's worker process through a broker-authoritative generation
handover and reopens its exact Pi session ID, preserving the conversation and
complete JSONL history. The live broker replays the bounded baseline and
materializes the latest coalesced run-state capsule, including evidence deferred
while the role was active, before recovering an accepted active assignment. A
local respawn failure, replacement disconnect, broker interruption, or
unprovable assignment remains `uncertain`; it is not blindly replayed.
Explicit worker resources are revalidated before changing the manifest, preparing
handover, or killing a worker; bootstrap verifies again before process launch.
A changed or unavailable reviewed resource therefore leaves the existing worker
untouched during restart preflight. The broker also independently revalidates a
custom role's resources and retained contract before incrementing its generation;
operator authentication alone cannot bypass that check.

### `stop SESSION --yes`

Kills only the selected tmux grid. Pi sessions and metadata-only broker state
remain under `~/.pi/agent/orchestrations/`.

### `planner-policy [--project PATH]`

Validates the external strict planner policy and emits its bounded normalized
identity/thinking and Jev-guidance projection for the parent extension. It does
not inspect credentials, endpoints, tasks, or provider responses and never makes
a provider call. The project defaults to
the current directory and is used only to reject a policy path inside the target
project.

### `planner-topology [--project PATH] [--profile NAME] [--no-project-custom-roles]`

Validates and emits the private version-2 worker-topology policy used by
dynamic planning: fixed built-in constraints, exact-project optional built-ins,
the bounded exact `workerCandidates` policy (one all-role pool and optional
built-in per-role pools), and freshly verified custom identity/contract/model
bindings. It never emits resource paths/bodies, tasks, credentials, endpoints,
or provider responses and never makes a provider call. This is a private preflight
projection, not public status or authorization to launch; do not copy the
pool/configuration body into reports. Selected custom resources are verified
again by dry-run and launch.

### `doctor [--project PATH]`

Checks Pi, Python, tmux, tmux extended-key settings, model and budget
configuration paths, the exact canonical project mapping, effective profile,
and configured model availability without a provider request. This bounded
metadata appears in the dashboard only after the user presses `d`. The CLI
project defaults to the current directory.

### Custom specialist selection

`start --custom-role ID PROVIDER MODEL THINKING` launches one explicitly registered
read-only specialist; repeat at most eight times with unique IDs. Add `--dry-run`
to preview without creating files, workers, or inference requests. All four values
are required. Provider and model are always explicit. `THINKING` is either an
explicit level or `profile`, which opts into that identity's mapping in the selected
user-global custom profile; an explicit level wins. Version-4 exact-project
`customRoles` select the same registered identities for one canonical directory
through the normal start flow; `--no-project-custom-roles` omits them for one run,
`--project-custom-role ID` selects only an exact-project allowlisted subset (and
is used by the bounded planner adapter), and explicit `--custom-role` replaces
the project list. Optional `--role-registry
PATH` selects the user-owned registry; a missing selection with no project or
explicit custom roles means no registry lookup.
Both TUI and `--rpc-workers` preserve the built-in implementer and mandatory
reviewer and expose only bounded custom metadata and skill counts.
`--skip-model-check` skips catalog discovery, not resource verification; use it
only when availability is established separately. Live startup revalidates every
bound resource at bootstrap and reaches `RUNNING` only after all panes and broker
authentication remain stable. Failure rolls back the exact new session to retained
body-free `FAILED` state. See
[selection syntax and limitations](custom-roles.md#start-or-preview-an-explicit-selection).

### `role-registry [--project PATH] [--registry PATH]`

Read-only validation of user-global custom specialist definitions and reviewed
prompt/skill digests. Supports the standard `--json` envelope and returns metadata
only. A missing default registry means no custom roles; explicitly selected files
must exist. Valid definitions can be launched through explicit `--custom-role`
or version-4 exact-project `customRoles`. A profile mapping never creates a role.
Selected roles use the fixed
path activation rules of their bound probe/Playwright/Django contract after an
implementation report; `--force-specialist CUSTOM_ID` forces the selected identity.
Omitted custom selection leaves built-in starts unchanged. See
[the complete schema and filesystem policy](custom-roles.md).

### `supervisor ...`

Supervisor API v2 reads retained state without tmux runtime observation:

```bash
pi-tmux-agents --json supervisor capabilities
pi-tmux-agents --json supervisor sessions
pi-tmux-agents --json supervisor runs SESSION
pi-tmux-agents --json supervisor snapshot SESSION --run RUN_ID
pi-tmux-agents --json supervisor usage SESSION --run RUN_ID --limit 100
pi-tmux-agents --json supervisor events SESSION --run RUN_ID \
  --cursor implementer=0 --cursor reviewer=0 --limit 50
```

Host liveness is `not_observed`; retained PIDs do not imply a running process.
`supervisor usage` is a bounded metadata-only page grouped by run, role, round,
and assignment kind. Each role contains separately labeled cumulative usage and
immutable assignment-local deltas. Input, cache read, cache write, output,
optional reasoning, provider-call count, provider-reported cost, operational
tokens, and context pressure remain separate fields. Legacy assignments expose
usage as unavailable rather than estimated. `--limit` selects the latest retained
assignments across the run and the response reports when older results were
truncated.

## Parent Pi supervision

When the package extension starts a run, the invoking Pi itself is the parent
supervisor and opens an authenticated, read-only broker observer. Starting a
normal run creates one detached worker grid; it does not start a second parent
Pi, parent window, or persistent controller. Use the model tool's `watch` action
to subscribe the invoking Pi to a compatible existing run without changing the
terminal.

Use Enter on a selected `/or-dashboard` row or the model tool's `attach` action
to watch future transitions and switch the invoking Pi's existing tmux client
into the live worker grid. An existing initial actionable outcome is shown only
as non-triggering progress; explicit `watch` requests existing-outcome
supervision. Select panes with normal tmux keys and type directly into a native
Pi worker's input editor to steer it. Prefix then `L` returns that exact client
to the same invoking Pi and original project context; the workers and observer
continue running, so attach/detach can be repeated. Pi exposes no
supported terminal-suspension API for an outside-tmux parent, so seamless
in-place attach deliberately requires the invoking Pi to already run inside
tmux.

Tmux remains the live worker view. The observer does not mirror raw worker logs
into the parent. It shows bounded non-triggering lifecycle and report-received
progress, sends bounded structured role reports when the workflow becomes
`ready`, and sends attention/uncertainty updates when parent intervention is
required. Terminal updates trigger the parent Pi to assess results and decide
follow-up. Metadata-only `status` summaries include the workflow and role states
so completion is legible even before an observer is attached. For current
broker runs, status adds one bounded latest-assignment usage line per role, and
the dashboard token cell uses `cumulative/+latest-assignment` without adding a
new payload hierarchy.

Observer report bodies are bounded, held only in broker memory while live, and
stored only in the relevant Pi sessions. They are excluded from SQLite, status,
journals, registries, and Supervisor API output. Terminal-started detached runs remain supported without a parent observer.
Parent observation requires a broker process from `0.6.0` or later; retained
runs hosted by an older broker remain status-readable but cannot be retrofitted
with live report observation.

## Event-driven workflow

1. Every worker bridge connects to the owner-only run socket.
2. The broker adds task/role baseline plus the optional parent context capsule to each Pi session without waking idle roles.
3. It triggers the optional initial probe and either a direct `implementation`
   assignment (`single`) or a read-only `plan` assignment (`phased`).
4. In phased flow the accepted plan becomes rolling run state and a distinct
   same-round `implementation` assignment; in both flows the implementer ends
   implementation with `orchestrator_report`.
5. The initial probe and each round's configured specialists are deterministically
   run or skipped. Forced roles run, and reviewer assignment waits for every
   activated report while exact skips count as not required.
6. Accepted evidence and bounded activation metadata update one latest-per-role
   run-state capsule bounded to 16 KiB of UTF-8; recipients no longer accumulate
   one context body for every historical report. Updates targeting an active
   role are coalesced until its next assignment.
7. The broker supplies the latest run state to the reviewer and wakes it once.
8. `changes_requested` supplies the coalesced latest run state and starts the next implementation round.
9. Acceptance of each distinct new assignment emits one metadata-only `context_boundary` event. Pi invokes context projection for every provider request. With default `prune`, that boundary removes prior assignment turns; explicit `retain` keeps them. Every assistant/tool turn in the current assignment remains visible in either mode.
10. A confirmed restart replays the live in-memory baseline and latest coalesced run state, including a pending replacement deferred during the active assignment, before recovery without creating a second boundary for that assignment.
11. `approved` marks the run ready without waking the implementer for an acknowledgement turn.
12. An attached parent observer returns the latest structured reports to the parent Pi, with authoritative per-generation launch assignments rendered first. A confirmed model-changing restart refreshes that role's launch assignment from current manifest metadata before the new generation reports. Report-body provider or model names stay untrusted; a machine-readable worker process identity, when present, is compared exactly and may be labeled matching, omitted, unavailable, or conflicting without changing the launch assignment.

The terminating report tool avoids an extra post-report provider turn. Idle
workers end their turn and never sleep or poll. A watching parent also ends its
turn and relies on broker events instead of sleeping or repeatedly polling
status/tmux. Non-terminal progress does not start a turn when the parent is
idle; if the parent is already active, progress is steered in before its next
model step. Timeouts detect failure; they do not schedule workflow transitions.

The deterministic two-round context regression measures serialized
provider-visible message characters before and after a new assignment boundary.
Its current fixture drops from 99,170 to 8,678 characters (91.2%); CI requires
at least a 50% reduction. A separate regression proves multiple assistant/tool
turns accumulate throughout one assignment and remain until the next boundary.
These are stable context-size proxies, not provider-specific token savings or
production-wire acceptance. Cumulative usage and current context occupancy
remain separate Pi/provider metadata.

Report fields, limits, ACLs, acknowledgements, deduplication, retry, crash
semantics, and token accounting are specified in
[protocol-v1.md](protocol-v1.md).

## Durable state

Files remain for:

- mode-`0700` run/session directories;
- mode-`0600` manifests and authentication tokens;
- Pi's complete JSONL sessions;
- one mode-`0600` metadata-only SQLite database;
- a transient startup payload deleted by the broker immediately after reading.

The live broker's rendered role baselines, bounded accepted report evidence, and
run-state capsules needed for confirmed handover replay are ephemeral. Its
copies are lost on broker exit and never enter SQLite, status, dashboards,
registries, journals, or the Supervisor API; an interrupted handover fails
closed as `uncertain`.

New workers never create or poll Markdown reports, readiness markers, mailbox
payload files, or relay-seen files. The database excludes task, assignment,
report, prompt, message, provider, diff, and log bodies.

Retained manifests from `0.4.x` remain compatible with legacy readers and
controls. There is no option to start that protocol in current releases.

## Token accounting and budgets

The worker bridge reports Pi/provider values for:

- provider-call count;
- input and output tokens;
- cache-read and cache-write tokens;
- reasoning tokens when exposed;
- total cost;
- current context tokens/window/percentage;
- peak observed context tokens for each assignment when available.

At each accepted assignment boundary the worker records a numeric cumulative
baseline outside model context. Its terminating report carries current
cumulative usage and the assignment-local delta. Report metadata, cumulative
role usage, and one immutable assignment usage result commit together before
any specialist/reviewer/next-round routing. Duplicate reports cannot overwrite
that result, and restart recovery reuses the recorded baseline rather than
starting from zero.

Unavailable values remain unavailable; no provider token estimate is invented.
Retained reports created before assignment accounting expose usage as unavailable.
Status and Supervisor API expose cumulative per-role/total usage, each role's
latest assignment usage, and current context occupancy without payload bodies.
The packaged policy preserves the existing soft role/run operational-token
warnings. Assignment provider-call and context-pressure thresholds are observed
inside the worker at tool boundaries. Warning and hard levels differ only in
visible severity; neither blocks non-report tools nor downstream assignments.
Budget configuration cannot silently skip required review, mark a workflow
ready, or otherwise alter routing.

### Opt-in enforcing provider-call ceilings (static starts)

Ordinary worker turns can use a **distinct** version-1 admission policy. This
never changes the observational `warn-only` or compatibility `hard` policy,
never has inferred/default thresholds, and currently rejects dynamic starts
before planning. Supply explicit `budgetOverrides.callLimits` (`run`, `role`,
`assignment`) on a static model-tool start; the interactive launch confirmation
shows the resolved ceilings and capability restrictions. Terminal example
(numbers are illustrative, not recommended defaults):

```bash
pi-tmux-agents start --project "$PWD" --task 'Your change' \
  --enforce-provider-calls run=40 --enforce-provider-calls assignment=12 --dry-run
# After reviewing the exact same thresholds, replace --dry-run with:
# --confirm-call-enforcement
```

Each scope is optional; a role or assignment ceiling applies independently to
every role or assignment. Values must be integers from 1 to 1,000,000. A fresh
broker reservation precedes **every ordinary provider turn**, including report
recovery. The single writer commits reservations before replying, so concurrent
roles share one run allowance. A missing/denied/invalid/uncertain authorization
aborts before dispatch. Grants are never refunded, even after cancellation,
transport loss, or restart; a lost reply can consume allowance without a call.
Duplicate grants cannot authorize another dispatch. These conservative admitted
turn counts are separate from observed provider usage. The metadata ledger is
bounded to 1,000,000 authorization attempts; exhausting its capacity requires
stopping the run rather than resetting accounting.

The currently verified boundary is **Pi 1.4.0**, OpenAI completions/responses
APIs using explicit `transport: "sse"` and `retry.provider.maxRetries: 0` (the
provider-retry default). Workers reject unsupported request settings; cache
warming, compaction and tree-summary navigation are blocked in enforcing mode.
Other APIs/transports and older Pi versions are not established enforcement
capabilities. This is not an OS sandbox: do not authorize nested provider
requests from worker tools or unrelated extensions. Already-admitted parallel
turns and their tools may finish; no arbitrary active tool is killed. A ceiling
is enforced at admission of the *next* turn, not by cancelling a response.

An exhausted ceiling leaves the workflow non-ready/needs-attention with the
assignment intact. Status, dashboard and Supervisor workflow metadata expose
`call_admission`, distinguishing it from observational warnings. Ordinary
messages, restarts and repair-round approvals do not increase the allowance.
Only a separately confirmed operator command extends **each configured ceiling**
by the stated amount, bounded by 1,000,000:

```bash
pi-tmux-agents extend-calls SESSION --run EXACT_RUN_ID --additional 2 \
  --command-id 0123456789abcdef0123456789abcdef --yes
```

Reusing the exact command ID replays its receipt without another increase;
changing the amount under that ID conflicts. This does not auto-resume work.
Then use explicit `send` guidance for a waiting role that owns an assignment.
The model must never invoke this approval itself. Mandatory review is unchanged;
neither a budget pause nor a continuation acknowledgement is completion.

**Actual-cost enforcement remains unavailable.** Pi's standard `usage.cost`
calculation uses catalog rates, not verified provider-billing data. The new
admission status reports that unavailability, and cost is not accepted as an
enforcing threshold. Do not treat the existing displayed cost as actual billed
spend. See [provider-free admission evidence](provider-call-admission.md) for
reproduction and the remaining #182 acceptance boundaries. This initial static
call-admission slice does not close the full cost/dynamic-planning issue.

The categories have different meanings and costs:

- input is provider-reported non-cached or otherwise provider-classified input;
- cache read/write records provider-reported cache activity and must not be
  presented as uncached input;
- output is generated assistant output;
- reasoning is separate only when the provider exposes it;
- context occupancy is a current-window measurement, not cumulative usage;
- cost is authoritative only when the provider reports it.

For development comparison, `operational_tokens` means input + output + cache
read + cache write. It is deliberately labeled as an operational aggregate, not
a billing unit or estimate of provider charges.

The source repository includes a checked-in model-free baseline:

```bash
node scripts/token-efficiency-baseline.mjs --check
```

It measures serialized provider-visible characters/UTF-8 bytes by synthetic
provider call and tool-result characters by tool across simple, medium, and
multi-round fixtures. These values are reproducible proxies only. The retained
usage analyzer reads body-free broker metadata without reading Pi histories or
any task, report, prompt, diff, log, or provider body:

```bash
python -m pi_tmux_orchestrator.token_efficiency \
  --state-root ~/.pi/agent/orchestrations --max-runs 100
```

Analyzer schema 2 preserves cumulative token/cost aggregates and adds available
provider-call distributions, implementation-flow and run-round counts, complete
assignment state/role/kind counts, repair and specialist assignment counts, and
accepted-assignment provider-call/peak-context distributions by role, kind, and
initial/repair stage. Legacy missing usage and specialist-activation metadata,
per-run assignment-page truncation, and scan issues remain explicit. Specialist
activation counts use complete SQL aggregates rather than a retained row page;
malformed categorical metadata is counted as an issue and is not emitted.
Percentiles are nearest-rank values over available retained measurements. These
results are an optimization baseline, not evidence that a context action saves
provider usage or authorization to alter worker context, routing, or review behavior.

## Pre-release extension acceptance

To test the exact checked-out extension before a version bump, tag, publication,
or installation over the released package, use the staged-artifact workflow in
[`prerelease-testing.md`](prerelease-testing.md). It produces a persistent local
package root plus commit/tarball provenance, proves package discovery in a
disposable provider-free Pi home, and documents a separately explicit temporary
`-e` test with real authentication and rollback. No custom-role registry is
required or included.

## Security boundaries

- Only the implementer receives normal write tools.
- Read-only roles retain `bash` and are governed by explicit role instructions;
  they are not OS-sandboxed.
- Run directory `0700`; socket/database/token files `0600`.
- Independent role tokens and control token; broker enforces role/report ACLs.
- Same-user peer credential validation where supported.
- No Pi/provider credential reading or copying.
- No TCP listener, cloud service, external message queue, or package dependency.
- Project trust remains explicit and mandatory.
- Status, journals, registries, and Supervisor API never include workflow payloads.
- No exactly-once claim: crash ambiguity is `uncertain`.

## tmux navigation

```text
Ctrl-b q       show pane numbers
Ctrl-b arrows  move between panes
Ctrl-b z       zoom/unzoom current pane
```

Recommended for tmux 3.5+:

```tmux
set -g extended-keys on
set -g extended-keys-format csi-u
```

## Troubleshooting

### Existing session name

Use `status`, explicitly stop it, or select another `--session`. The tool never
replaces an existing tmux session.

### Worker is `disconnected`

Inspect its pane. The bridge reconnects with bounded exponential backoff without
using model turns. A transition in an unprovable window remains `uncertain`.

### Worker is `waiting`

Pi settled while an assignment remained open, usually because it did not call
`orchestrator_report`. Without explicit attention, the first settlement receives
one bounded automatic report-recovery turn. Explicit attention, interrupted
recovery, or a second unreported settlement marks `needs_attention`; an attached
parent receives an event-driven update identifying the waiting role. Send focused
guidance to that owner or restart it; sends to idle roles without the blocking
assignment are rejected. Neither acknowledgement nor a nudge is task completion.

### Broker pane exited

Workflow delivery stops. Do not start a legacy relay. Preserve the worktree and
restart or stop/recreate the brokered run after inspecting retained state.

### Project trust prompt

Approve each interactive child only after inspection, use saved/global trust
for RPC presentation, or restart with a separately confirmed `--approve-project`.

## Structured worker attention

`orchestrator_attention` is available to every active worker, including read-only
custom roles and implementer plan assignments. Its strict object requires
`reason: clarification|blocked|tool_failure|report_failure` and permits optional
`summary` and `question`, each nonempty and at most 500 Unicode characters,
without control characters or unpaired surrogates. Unknown keys and malformed
values fail closed. This terminates the worker turn but does not complete its
assignment or substitute for review/report evidence.

Prose appears only as a transient notification in the live authenticated parent
TUI/RPC UI. It is not a parent model message or tool result and is never replayed.
The worker bridge strips attention arguments and accompanying assistant
text/thinking before Pi journal persistence. No prose or raw validation errors
are written to SQLite, metadata events, status, dashboard, Supervisor,
manifests, or registries. If the parent was absent or missed the notification,
use the retained bounded reason/classification and ask the user for clarification.

Parent updates include assignment kind, last activity phase, settlement count
(saturated at two), attempt classification (`none`, `rejected`, `attention`,
`accepted`), reason, and reminder state. A worker settling on its active
assignment without accepted report or explicit attention gets exactly one
private system reminder, and the bridge gates at most one additional provider
request, including retries. The next settlement becomes actionable
`needs_attention`; it never generates another automatic reminder or a fabricated
report. Reconnect, worker restart, broker restart, replay, duplicate messages,
and stale assignment/generation cannot replenish the allowance. Interrupted
reminder scheduling is conservatively actionable rather than silently retried.
Legacy active assignments migrate without granting an automatic recovery turn.

Acknowledgement or an automatic nudge is **not task completion**. Use `/or-send`
or the model tool only for the waiting role owning the active assignment, not an
idle role or an unassigned reviewer. Explicit authenticated guidance resumes that
owner, without resetting its automatic nudge allowance. That explicit resume
authority survives reconnect/restart; old pre-guidance attention, settlement,
reminder, or recovery-claim replays cannot rearm the automatic gate or revoke the
resumed turn. A later valid report
remains subject to exact-once broker acceptance and normal mandatory review.
