Skip to content
Back to skills

Orchestrate

ASecurity

Use when this session is the top-level orchestrator (\"오케스트레이터로\", \"모든 세션 관리해줘\", \"이 세션도 편입해줘\") or drives a program to done through Orca workers — \"PM 겸 오케스트레이터로 끝까지\", 3+ tickets in parallel, \"대시보드 갱신해줘\", \"resume\" another lead's program, or why its PRs are stuck.

  • 3 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added November 5, 2026
ai-agentsrustgoshellbashgitsecurity

Works with

  • terminal

Security analysis

A100/100

Pro scans all 16 files and shows the line behind each finding

Scanned November 11, 2026

npx -y skills add JeongJaeSoon/agent-skills --skill orchestrate --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Orchestrate?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Orchestrate
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jeongjaesoon-orchestrate/badge)](https://www.skillsdirectory.com/skills/jeongjaesoon-orchestrate)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: orchestrate
description: "Use when this session is the top-level orchestrator (\"오케스트레이터로\", \"모든 세션 관리해줘\", \"이 세션도 편입해줘\") or drives a program to done through Orca workers — \"PM 겸 오케스트레이터로 끝까지\", 3+ tickets in parallel, \"대시보드 갱신해줘\", \"resume\" another lead's program, or why its PRs are stuck."
---

# Orchestrate a program

Core rules. The plugin's reorient hook prints this list verbatim after every compaction, so it stays short and self-contained:
1. Delegate. When the human gives an instruction, do not do the work yourself: hand it one layer down at once (a worker, a card, a background subagent) with the facts you already have, and have that layer sum up its result for you.
2. Your own turn holds coordination (briefs, starting and closing units, inbox ack and wait, decisions, landing), the acts in `references/top-level.md` "Acts only the human's session may take", answers from what is already in your context, and one `--json` read (`orch status`, one `orca … --json`, one `gh … --json`). Any other task work is a delegation; you write no PR yourself.
3. The orchestrator is the root. Leads sit under it, each lead's workers under that lead, and a single card the orchestrator starts sits directly under it.
4. The orchestrator sends a project's work to its lead, never to the lead's workers or into its own hands, and gives a lead to a project that meets "Starting a lead" (`references/top-level.md`); a lead sends its own project's work to its workers.
5. Start a child card with `skills-sync card`. A raw `orca orchestration worker-start` that makes a worktree takes `--worktree new-child` (`new-top-level` and `--no-parent` only when the brief names them); one that attaches a Dispatch to an existing card takes `--worktree id:<its worktree>` (`references/top-level.md` "Starting a lead", promoting a running card). When Orca refuses `new-child`, stop and report the refusal, never retry it as `new-top-level`.
6. Exactly one inbox wait runs at all times (the orchestrator's `orch inbox --stream` under Monitor, which also watches the cards; a lead's `orch wait <slug>`; otherwise `orch inbox`), plus one `orch watch-cards` when you started cards no Run lists and no stream watches them; after a compaction or restart, check both are alive before anything else (agent-skills:reboot).
7. A status report is `orch brief render` output as printed (agent-skills:brief); add judgment through its flags, never rewrite its shape.
8. A PR lands only through `orch land` with green required checks and an independent review with nothing left to act on (`references/landing.md`), as a plain merge the human approved, or, for a standalone card in a repo with the land executor off, by that card itself (all under "Merge policy").
9. Your turn ends on a short answer to the human; completion reaches you as a notification, never by polling.

You own the program, not the code. You frame it, write briefs, drain the inbox, keep dependencies and the land order honest, and decide. Orca already owns the mechanics: Run, Task and its deps, Dispatch, `check --wait`/ack, `ask`/`reply`, gates, the worker contract, recovery and release. This skill adds only the program layer. Where an Orca command does the job, use it rather than add a wrapper that parses its output; the inbox wait in step 5 keeps its own rule. Code that must still read a response passes it through raw with one warning line when a field is missing, and gets no per-Orca-version branches, fixtures or contract tests.

**REQUIRED BACKGROUND:** at the start of every orchestrator or lead session, run `orca skills get orchestration` and read it. Every Orca command here comes from it; never compose one from memory.

## Roles

Two modes share these rules: **top-level** is the orchestrator's (`references/top-level.md`), **program** is a lead's (`references/program.md`: a lead reads it now, before its first step). Every layer above a worker is one of these two, and the skills name it as one of them, never as "coordinator".

| Name | What it is | Started with | ROLE line |
|---|---|---|---|
| orchestrator (오케스트레이터) | The one top-level session the human talks to, above every task session and every lead. It routes, answers and starts leads; it drives no program itself. It owns the routing between projects and supervises the leads and the single-PR cards it started (their review, and the closing reports it checks). | `claude --agent agent-skills:orchestrator --name orchestrator` | `ROLE: orchestrator` |
| lead (리드) | A session that drives one project (one repository, one topic) to done through workers, in program mode. A session asked to run a project to done ("PM 겸 오케스트레이터로 끝까지", a program resumed) is a lead even when the human calls it 오케스트레이터. It owns its project end to end: the split into units, who runs each and in what order, the dependencies between them, and the final check. | `claude --agent agent-skills:lead --name lead:<slug>`, or `skills-sync card` with the Lead brief (`references/brief.md` "Lead"): a dispatched worker or a `/goal` card, by Orca's setting | `ROLE: lead <slug>` |
| worker, card | One unit (a ticket, an investigation) in its own worktree: a `worker-start` worker reports to its Run, a `/goal` card to the session that started it. | `worker-start`, `dispatch-card` | none |
| standing role | A worker with no ticket: main guardian, QA lead, flow improver, resource steward (`references/roles.md`). "QA lead" names this worker role, not a lead. | `worker-start`, then `orch record … spawned --role` | none |
| coordinator (Orca's word) | What Orca calls the session bound to a Run that dispatches workers: here always the orchestrator or a lead. The word stays only where Orca's own text, output or fields (`coordinator_handle`, a worker preamble's "Your coordinator") are quoted, and in code, whose identifiers and comments follow Orca's data. Orca's "sub-worker" is a worker a worker started: a helper, below. | — | — |

**Depth.** Units nest at most three layers under the orchestrator: a lead (a dispatched worker on the orchestrator's Run, or a `/goal` card with its own Run when Orca's setting is below 3; `references/top-level.md` "Starting a lead"), the lead's workers (ticket units and standing roles), and a worker's helpers, which the worker starts with `worker-start` on the Run it works for. A card the orchestrator starts with no lead counts as a lead's layer, so its helpers are the second layer. A helper starts no unit of its own; a subagent inside a session is not a layer. Orca's nesting limit (Settings → Orchestration, `references/top-level.md` "Starting a lead") is the hard stop, and this ceiling holds whatever the setting. When a worker's helper `worker-start` is refused (`nested_worker_depth_exceeded`, the default setting refuses every one), do the work in the worker itself or a subagent, or ask the lead (the orchestrator, for a card with no lead) for another worker; never start that unit from a new Run or as a card, which only hides the depth from Orca. Starting a lead as a card when the setting is below 3 is the intended path, not that workaround.

Where a unit runs is one of three placements, named this way everywhere:

| Name | Made with | What Orca shows |
|---|---|---|
| child card (하위 카드) | `worker-start --worktree new-child`, or `orca worktree create --parent-worktree <selector>` | Its own worktree, branch and PR, listed under the session that made it (Orca's lineage, `parentWorktreeId`) |
| child terminal (자식 터미널) | `worker-start --worktree current` | A new terminal in your own worktree: no branch or card of its own, so only for work that writes nothing |
| `/goal` card | `dispatch-card` (dispatch or next ticket) (`orca worktree create --prompt "/goal …"`) | Its own worktree and session, unsupervised by a Run; under its parent when created with `--parent-worktree` |

Which of the two takes a piece of work (one PR: the orchestrator and a card; related PRs, an order, deploy stages or a predicate: a lead) is `references/top-level.md` "Starting a lead".

A session's role is declared, never guessed from its terminal: the `--agent` flags above, or, for a session already running or a lead card whose launcher cannot pass flags, a prompt line of its own, `ROLE: orchestrator` or `ROLE: lead <slug>`; `ROLE: none` silences either. The plugin's reorient hook reads the role from the session itself, so it survives compaction, resume and fork, and puts one reminder line before every prompt of a declared session. A lead card's first prompt carries its `ROLE` line (`references/brief.md` "Lead").

### Who checks what

An index only: each rule lives behind its link. The worker's, the lead's and the QA lead's rows are in [program.md](references/program.md#who-checks-what).

| Check | Owner | Rule |
|---|---|---|
| A lead's closing report before the human hears "done"; a single-PR card's review | The orchestrator, through a background subagent | [Starting a lead, After](references/starting-a-lead.md#after) |
| Human authorization and judgment | The owner | [brief HUMAN ONLY](references/brief.md), [deliver-ticket §6](../deliver-ticket/SKILL.md#6-finish-the-ticket--done-means-its-acceptance-criteria-are-met), [Asking the human](references/top-level.md#asking-the-human) |

## Stay answerable

The human must get an answer from you within seconds, at any time. **Decide up, execute down**: you, or the lead that owns the project, make the call; the work itself goes one layer down the moment the request arrives, with the facts you already have and no "quick look first". An order to handle something yourself means you decide instead of sending it back to the human; it never means doing its steps in this session. The cases:

- Inside your turn, only three things happen: routing a request to its owner, checks that finish in seconds (`orch status`, one `orca … --json` read, one `gh … --json` read), and answering the human. A request that would take you more than one short tool call is a delegation, even when you know the answer's shape.
- Investigation, implementation, verification, reviews, browser, desktop, chat-send and web steps, edits outside your state directories, reads past a quick check (code, pages, PRs, chats), long waits and monitoring go one layer down: a supervised worker on your Run (`orca orchestration worker-start`, or `dispatch` to a live terminal), whose `worker_done`, escalation or `ask` wakes your inbox wait; a card (implementation always goes to a card, below); or a background subagent (`run_in_background`). Which one takes a given request is `references/top-level.md` "Routing". Never pipe a background command into `tail` or `head`: a watcher's lines never reach its output file.
- A project that has a lead: the layer above sends all its work to that lead, never to the lead's workers and never into its own hands, and the orchestrator starts a lead unasked once a project's work meets `references/top-level.md` "Starting a lead". These rules bind every layer above a worker, a lead card another session started included (`references/brief.md` "Lead"): such a layer judges results, lands, records decisions and puts what waits on the human in front of them.
- Never block in the foreground: no `until` loops, no `sleep`, no `check --wait` or `orch wait` without `run_in_background`, no back-to-back polling reads. The one inbox wait you keep is in Step 5, "One inbox wait, always". A PR waiting on a human is read at most hourly, and a rate-limit error waits for its reset (`references/brief.md` LAND). Your own shell loops follow the zsh rule in `references/brief.md` FORBIDDEN, and a report that cites a watcher quotes its last output line.
- Completion reaches you as a notification: the background task's completion, or a line of your inbox wait. Between notifications, your turn is over. A notice that arrives without the subagent's report (dropped by a hook or never shown as a turn) means the work ran: read the report from the subagent's transcript (`<session>/subagents/agent-<id>.jsonl`, its hand-back input) or the result file its prompt named, then the shared record (diff, tracker, PR); never ask it to resend or redo side effects. Tell a worker in that state the same.
- You write no PR: not code, not a doc, not a script, however small the follow-up. It goes to a card (a `worker-start` worker inside a program; otherwise `dispatch-card` §2 and `skills-sync card`, which starts a brief that reports to your Run as a supervised worker when your terminal is bound to that Run, else a `/goal` card; with an APPROVED line when the unit needs approved acts), not to a background subagent, and you judge, review and land it. A program unit is never a `/goal` card: a card owns no Dispatch, so Orca rejects its escalations (`sender_not_assignee`) and `orch wait` picks up the status they come back as only late, through its untyped fallback. At the first such rejection, start the remaining units with `worker-start` rather than writing status reporting into the shared brief. Under auto mode a background subagent's Edit or Write can get no verdict from the classifier; a unit already given to one restarts as such a card at the first failure, not after retries ("Refused acts"). The acts in `references/top-level.md`, "Acts only the human's session may take", are the only task work you do yourself, and none of them is writing a PR.
- A research answer that later tickets will build on (a contract, an authorization or security rule, a scope cut) is one model's draft until it is challenged. Before you post it as the ticket's answer, copy it into briefs or close the ticket, have a background subagent run `challenge` interrogate on it, and fold the findings to act on into the answer: every brief that quotes it inherits its blind spots. Your reading of the owner's direction is the same kind of draft: a reinterpretation "by applying an invariant" (folding the owner's choice into your own option) goes through `challenge` interrogate before it reaches a brief or an option list.
- A card already on the task (the same PR, branch or ticket) that only needs to be told something gets a message, not a new card. One whose work needs a different implementation is superseded by a new card: first get a state summary from it (what is done, what is unpushed, what is left; read its worktree where it cannot answer) and put it in the new card's brief, then, in the turn you start the new one, tell the old card `superseded by <new card>: stop and close by end-session §8` (`orca orchestration send --to dispatch:<id>` for a worker; `skills-sync nudge <handle> "<that line>"` for a `/goal` card, logged with `orch sent add`). `skills-sync card --supersede` (with `--reference`) does that send and the log below for a card it recorded. Log the supersede itself with `orch sent add --to <old card's handle or worktree name> --kind supersede --text "superseded by <new card>"`, even when Orca keeps the send: `orch patrol` checks that card against this log. Without the summary the new card redoes or undoes finished work. A nudge refused because a prompt is open on its screen → close its agent terminal in this turn. A question the old card left waiting is stale: drop its decision and inbox item (`orch decide drop`, `orch-dash inbox resolve`), never answer it. Not closed by the next wake → close its agent terminal; its worktree follows `end-session` §4.
- A card that is stuck is not yours to finish: no merge, dispatch or browser step done in its place. A missing approval gets a new `/goal` card that carries it; a missing permission rule gets the human one `!` line ("Refused acts").
- What you started, you close, in the wake that tells you its work is over: a `worker_done`, or any message from a card that says it is done, whatever its form. Judge closing in that turn, before the merge or review the same wake brings: no later wake brings the report back. A background subagent or task you no longer need → `TaskStop` (never the one `orch wait`). A scratchpad or `.claude/worktrees/agent-*` worktree whose work landed or was dropped → `git worktree remove` (clean ones only). A card you made with `orca worktree create` or `dispatch-card` has no `worker_done`, so no `CLOSE OUT` line names it: in the wake its report arrives, read its screen. Its brief's `CLOSE` line should have closed it in that same turn. Still open (idle at its prompt, waiting on its inbox, or asking about work already done) → close its agent terminal now (`orca terminal close --terminal <handle>`); where a real open question holds it, leave it and note what. The worktree is the cleaners', except a lead's card, which you remove by `end-session` §4 (`end-session`, "Who cleans up"). Each cleanup command runs alone (`end-session` §4). A standing loop (a heartbeat routine, `/loop`) also reads the `card` targets of `<state>/janitor-plan.json` (`reap-resources`) on every wake and closes each card of yours listed there the same way.

## When not to use

- One agent could finish inside the budget → do it in this session, or give it to one card with `dispatch-card`'s next-ticket mode. A program costs a lead.
- A single ticket handed to another session → `dispatch-card`'s next-ticket mode.

## Where each fact lives

A program's table of record owners is in `references/program.md` "Where each fact lives".

`orch` runs `scripts/prog.py` and `orch-dash` runs `scripts/dash.py`; the plugin's `bin/` puts both on the Bash PATH. Run either with no arguments for usage.

## Steps

A lead's steps 1–4 (Frame, with "Check the permission chain"; Verification first; Pilot; Scale) and 6–9 (Triage, Land, Verify main, Close) are in `references/program.md` under the same numbers. Step 5, Drain, stays here: the orchestrator runs it too.

5. **Drain.**
   - **One inbox wait, always.** The orchestrator and every lead keep exactly one inbox wait running and no other inbox watcher. The orchestrator in an Orca terminal runs `orch inbox --stream` with the Monitor tool (`timeout_ms` 1800000, never Bash): each message arrives as one notification line with its body, status mail is batched for up to five minutes while urgent mail goes out at once, and it runs the card watch itself, so a wake has nothing to read, ack or start again. On its `STREAM END` line, before Monitor's 30-minute limit, start it again in that turn. A lead keeps `orch wait <slug>` under `run_in_background`; a session with neither a program nor the Monitor tool runs `orch inbox --wait` the same way. Never both. A background wait only peeks while it waits, and a batch it already printed stays in `orca orchestration inbox --terminal <its mailbox> --full` (`run:<run>`, or a dispatched lead's `dispatch:<id>`). On every wake of a background wait, in the same turn: act on the batch, then run the exact command it prints: `orch wait`'s ack line followed by a new `orch wait`, or `orch inbox`'s `orch inbox --ack <delivery> --wait`, which acks and is the new wait. Never read the inbox with raw `orca orchestration check --json` calls. After a compaction, `claude --continue` or a restart, `agent-skills:reboot` checks this wait first; a sleep loop is not a substitute, and a second watcher beside it swallows the `CLOSE OUT` and `status` lines.
   - Process every message in the batch, decide each settled worker's next owner (reuse or release), then ack.
   - On a worker's `worker_done`, in the same turn, reconcile its tickets (`use-tracker` "Reconcile": the `gh` read and the moves it supports, with the REPORT's evidence standing for `completed`; a criterion that needs checking again goes to a background subagent; the worklog and notes by `end-session` `references/record.md`, read now, and a body without its record line is asked for one) and act on the `CLOSE OUT` lines `orch wait` prints beside it: release the worker; close its agent terminal if it did not close itself (never this session's own, which a `--worktree current` worker reports as its card) unless its next task starts there; keep a failed one only for its retry. The worktree goes to the cleaners (`end-session`, "Who cleans up"). `status` lists landed cards still on disk as `LANDED-BUT-OPEN`; `wait` names the released ones too, since a worker you stopped sends no `worker_done`. Leftover cards made Orca itself slow.
   - A worker closes its own session once it settles (`end-session` §7, named in every brief's REPORT); the lines below are the backstop for the ones that could not. Every return of `orch wait` also lists `SETTLED` workers nobody released (worker done or failed, no open PR, nothing unpushed, and no `autoReleaseAt` still ahead for Orca to release it by itself): release each in that turn. A worker that `worker-release` already left `release_unknown` with its card gone is done, though later wakes keep listing it, a few at a time. To tell a new or unreleased worker from them, count `orca orchestration worker-list --run <run> --json` by `terminalState`; a filter that drops wait lines by kind hides the new ones too. A `KEEP` line names what still holds a worker; the card itself goes only after landing, as above. A `TAKEN OVER` line is a settled worker whose terminal was typed into, a `terminal send` nudge included: Orca never releases it, so run the self-check command the line carries; later wakes print only when it was asked. The session then closes itself with `end-session` or says what is left; where it has no `end-session`, close it yourself once it answers that nothing is (`orca terminal close --terminal <agentTerminalHandle>`). When the host's permission layer, not Orca, refuses `worker-release` (an auto-mode classifier has called it workload interference), stop releasing and follow "Refused acts" below (the rule: an autoMode allow for releasing this program's own workers). Do not reach the same end another way (`worker-stop`, closing its terminal, a subagent).
   - A `STUCK` line is a live worker whose screen shows a select menu, a permission prompt or a wait for input. Nobody watches a worker's terminal, so its own question can hold the program; `orch wait` reads every live worker's screen each round (`active`, and `retained` ones that have not succeeded or failed, such as a card someone nudged with `terminal send`; released and settled workers are skipped) and wakes early on a new one. Workers may ask this way; answering is your side. In that turn, yourself or through a subagent you dispatch with the line, read the question and its options on the screen and answer from what the program already decided: its briefs, standing orders and decision trail. Select the option by its number, or type the answer, with `orca terminal send` (the terminal then counts as taken over). For a permission prompt, first check its target with real output (the pid, the cwd, that the worktree exists), then pick the one-time yes; never "don't ask again", which edits permission settings. Put it to the human at once only when no decision covers it, a call that is theirs (`orch-dash inbox add --type decision`). Record each answer and each escalation with the `orch record … signal` the line carries, the answer or the escalation in its note.
   - **Watch the cards' screens.** `orch wait` reads only its Run's workers. A `/goal` card (`dispatch-card`, a lead) is not one, and `orch inbox` reads no screen, so such a card can sit unseen on a confirmation or a question only a human can answer. The top-level, and any layer that started such cards, keeps one `orch watch-cards` under `run_in_background` beside its inbox wait (`orch inbox --stream` runs it as its child and prints its findings, so the orchestrator starts none). It reads no inbox, so it is not a second inbox watcher. It reads every agent terminal but your own (a lead passes `--handle <terminal>` once per card it started, so another program's finding does not end its watch) and exits on a new finding, one line each (under the stream, a `CARDS:` line, and it starts again by itself); otherwise it exits `QUIET` after 55 minutes. In that wake act on each line, then start it again. It reports a finding once while it stays on screen and never answers one; the answer is yours, from the screen's content:
     - A card you started: as a `STUCK` line above. A question about work already settled (merged already, or done by a newer card) gets that fact, or the card is closed as superseded.
     - A card or worker in a project that has a lead: that lead (`references/top-level.md`, "Routing").
     - Any other session you did not start: the inbox (`references/top-level.md`, "Sessions you did not start").
     - Several cards retrying at once: a shared usage limit; wait for its reset.
     - Low disk: `reap-resources`.
     - `SETUP FAILED <card>: close-setup|goal-input (reason)`: the card's start helper logged a failure (a trust dialog, no visible start, a `/goal` line never typed), so an idle screen is not a working card. Run the command on the line below it, or read the screen.
     - A silent `/goal` card: read its screen, then nudge it or close it as finished.
     - `auth` or `goal lost`: the card will not go on by itself; read its screen. A lost login: do not type `/login` into it (a re-login can reset the token store every session shares); start a new card on the same brief and close the old one as superseded. A usage-limit pause waits for its reset; a lead whose last transcript `goal_status` is met, or that waits on a live background `orch wait`, or has a board to-do of its own whose `--due` has not come, is parked, not lost, and is not reported; a finished card that never closed is closed.
   - A permission dialog raised by a lead's workflow agent or worker takes the lead's own terminal input, so the lead cannot answer it. The layer above reads the screens of the leads and workers it started on every wake and answers such a dialog the same way when the approved scope (APPROVED lines, standing orders) covers it; anything outside goes to the human. An agent that uses a write tool whose host asks it to load a policy skill before the first write gets, in its prompt, an instruction to load that skill before its first write, so the confirmation does not come back in every session.
   - A `STALLED` line is a worker whose ticket is open while its session has stopped writing (a turn that ended on a review report, a notification that never started a turn). `orch wait` ends early on a new one, once per 30 minutes. Read its screen before waking it: a spinner, a running tool or upload, a background shell it waits on, or a browser hold it waits for is work, so leave it; nudge only when nothing moves. A worker you told to wait (the next QA round, another PR, the human) gets `orch record <slug> parked --ticket <id> --note <what wakes it>` in that turn, which keeps it off the `STALLED` lines, and `record admitted --ticket <id>` when that happens.
   - A start that ended `outcome_unknown` with an empty composer: `worker-stop --dispatch <id>`, then `worker-start --retry-of <id> --task <task> --worktree <that card> --agent <agent> [--model <id>]` (a retry inherits neither placement nor model).
   - Record a lesson signal when the process, not the product, went wrong: `orch record <slug> signal --kind <human_correction|brief_gap|stall|tooling> --evidence <message id, PR comment URL or transcript path:line> [--ticket T] --note "<one line>"`. A human correction of how the work runs, a worker question the brief should have answered, a stall the process caused, a skill or script that misbehaved. A refusal report is sorted first ("Refused acts"). Only record; the flow improver's rounds and Close analyze it. `land_failed`, `main_red` and failed verdicts are in the ledger already.
   - `WATCH-CARDS DOWN` (from `orch inbox` or `orch wait`): the `orch watch-cards` this terminal ran has finished no round in two intervals; start it again now, `run_in_background`, no pipe. `PATROL <code> <id>` lines are `orch patrol` findings routed to you (the card's starter, else the orchestrator), repeated every 4 hours until acked (an `I` alone, on a card known to have no open PR, only once it has stayed open an hour); each line names what it found (codes in `docs/automation.md`, "세션 순찰"), and an `E` line is a hint only. Patrol only records them; before acting, read the screen and Dispatch state again, then act as for `STALLED` or a superseded card, and run `orch patrol ack <id>`. A card a lead started goes to that lead, not to you.
   - End every drain with `orch status`; its lines are how a drain ends. `status` also prints what only the dashboard's collector sees: `STALLED` workers (turn ended with the task open, no session activity since dispatch, one tool call running too long), `SPARE` slots with ready tasks, and `LEDGER GAP`s. Act on them like the other lines. Its last line, `note values:`, says whether the program note's merge policy, ceiling, deadline and predicate lines match `program.json` (the source; the note is a copy). It reads a markdown notes root and writes nothing: a `DIFFER` line is yours to fix in the note, or with `orch set` if `program.json` is the stale one. `orch-dash note` records a risk or decision the dashboard should show.
   - Under `/goal`, a running background task defers the Stop hook's goal check. If the hook re-prompts anyway with no new event, answer in one line with no tool call. If it fires back-to-back, the background wait is gone: check it and start it again ("One inbox wait, always"), never as a foreground wait.
   - Once every open predicate item waits on the human or an outside event (a human-only check, which stays out of reach after a named agent-reachable stand-in was tried; a rare event in prod), register the decision as in "What reaches the human" with its default stated (park it as LATER and Close). A lead sends it once through its established channel to its PARENT, which routes it to the human. Restart an expired wait with no reply when there is no new event or changed decision. A changed blocker, new evidence or a direct user question still gets an update; deduplication applies only to unchanged waiting notices.

## How the human's words change the program

| The human says | Do, in the same turn |
|---|---|
| "I'll watch X myself, don't bother" (usage, a metric, a channel) | Delete X from the standing orders and from every judgment rule now, and never defer work on X's account again |
| "Can it go faster?" | Offer structural levers: parallelize the critical path, stack dependent chains, reorder the land order, narrow `exclusive_paths`, risk-tiered review depth, split CI jobs by role. Apply the approved ones at once. Not "work harder", and not serializing for safety (one CI at a time, one landing per N minutes) |
| Feedback about how the work flows, not about the product | Record a `signal --kind human_correction`, and send the feedback to the flow improver (`send --to dispatch:<its id>`) while you stay on the program. It folds feedback into the skills in batches, and asks you before changing this program's contract; after its "reload needed", run `skills-sync broadcast` |
| Feedback or a request about the product, one that arrives mid-turn included | Put it on the board before you send it on: in the `next` of the lead or card that will do it, recorded as `references/top-level.md` "Periodic report" says, or, when no session runs that work yet, `orch board doing add <title> --owner W --next E`. A message to a lead is not a record, and the board is where the human looks for it |
| "Make it better" about in-flight work | A new ticket with its own brief. Never append it to the running task |
| "Make a ticket for …" inside another question | Split it out and file it immediately, then answer the question |
| Doubts your report ("is that right?", "불안하다") | A read-only verifier agent re-checks it. Your self-report is not evidence |
| "Check" (점검) one section | Check the whole related scope. "Check and align" (점검하고 얼라인) is two tracked steps: findings, then the alignment changes, each reported done separately |
| "Why is #N not moving?" / priority doubts | `orch queue <slug>`: answer with its order and reasons, then fix the reason (stack, Orca dep, class, fix task) |
| "Update the dashboard and summarize" | It updates itself. Run `orch status` and summarize its numbers; if the dashboard looks stale, `orch-dash ensure` |

## Merge policy

- `autonomous` (default): workers land with `orch land`, each carrying the merge in its first prompt's APPROVED line. A card stops at READY only for a `READY-WAIT:` kind in `references/brief.md` LAND; `hooks/self_land_gate.py` warns on any other close over an open PR (`orchestrate.self_land`, `deny` to enforce).
- `human-gate`: workers stop at READY. You `orch gate <slug> --pr N` (an Orca decision gate), and after the user resolves it, `orch land`.
- A standalone card (no `PROGRAM:` line) in a repo with `orchestrate.land_executor` on stops at READY with its head sha, CI run ids and review verdict; you record that verdict and run `orch land` on the repo's standing program (`references/landing.md`, "Land executor"). With the executor off, the card merges its own PR under its APPROVED line (`deliver-ticket` §6).
- `merge_policy` is program state, not a user setting. When the human's words call for a change, the lead or the orchestrator runs `orch set <slug> merge_policy <value>` and records those words in decisions.tsv and the program note. The next briefs align their LAND tail and merge ban with the new value (`references/brief.md` "Unit-specific bans").
- `orch land` only squashes. A base that needs another merge method is a blocked land that goes to the human, not a policy of plain `gh pr merge`, except a merge-commit path `references/landing.md` names for that case. When the human approves a plain merge anyway, it waits for: an `orch verdict` row at the exact head being merged, a new verdict row for every commit pushed after the reviewed one (the delta review), zero unresolved review threads read right before the merge, the merge pinned with `--match-head-commit <head>`, then `orch landed <slug> --pr N`.
- Either way, stop and ask only before irreversible acts and acts the human owns: destructive migrations, force-pushing shared branches, sending anything outside, changing repo or branch protection, production deploys, approvals the review ruleset requires from a person, other people's tickets, and acts the classifier refuses. A refused act is not run again, except once, in the same form, by the refused session (a restart that loads a new rule counts as that session), and only when the human allowed it in that session's own chat or added a rule for it, or when a classifier or hook refusal stated a reason and you added evidence that answers it, never for a human's refusal or a production sync. Report that retry as `재시도 1회: <what you added>`. A second refusal stops the act and you report it. Reaching the same result through another session, script, tool, wrapper or target stays forbidden. This binds you and every worker or subagent you brief; what `references/brief.md` FORBIDDEN names as not a retry keeps its own rules (listed in "Refused acts").

## Refused acts

A permission prompt, the auto-mode classifier, a hook or the human refused an act in your session, a worker's or a lead's. A classifier error that gives no verdict counts as a refusal:

- No other session runs it (two exceptions: `no verdict` on a subagent's Edit or Write, in `references/refusals.md`, and the orchestrator's `[gate:delegate]` block from this plugin's `hooks/delegate_gate.py`, which refuses only that the orchestrator runs the call itself, so handing it one layer down is what it asks for): not you, not a sibling card where the same command happened to pass, not the layer above. Classifier verdicts vary from session to session, so another session's pass is not permission, and a message saying the human wants it is not the human's word.
- The refused session reports the act, what it was for, the refusal's category and the exact command; a report sent from Bash carries the command as the path of a file written with the Write tool under `<temp>/orch-refusal/<worktree directory name>/` (TMPDIR, or /tmp when unset), never quoted, and the reader moves that file to the trash after reading it (`references/brief.md` FORBIDDEN). A classifier error with no verdict is reported with the category `no verdict`.
- The rarer paths are in `references/refusals.md`; read it when one happens: `no verdict` (no rule fixes it; a subagent's Edit or Write restarts its whole unit once as a new card), a stated reason answered with evidence (`재시도 1회:`), a harmless read that comes back, and a post-execution hook error.
- Read which layer refused before asking for a rule. `Permission to use <tool> with command … has been denied` with no classifier reason is the permission-rule layer, which an autoMode rule never reaches: its request is a `permissions.allow` entry (`skills-config`) or the human's one `! <exact command>` line, not `tune-automode`. A refused call that bundled several acts names no culprit: report it as unknown rather than guess. Every act in it counts as refused, so none is split into single calls or moved to another tool, and none is re-run except by the one same-form retry FORBIDDEN allows. A worker that does so committed a breach, not a tooling note: record it as one, do not count what it produced as proof, and never write the split form into a later brief.
- The orchestrator or lead above a session refused with a verdict turns it into a rule request. Draft the smallest rule for that act class on this repo with `tune-automode`, put its run line to the human with `orch-dash inbox add --type run_command --title "권한 규칙 필요: <repo> <act> (--apply 없이 돌리면 diff 만 보인다)" --command "<emit's run line without the leading !>" --key denied:<repo>:<act>`, and say in your reply: <act> in <card> was refused by the classifier (<category>); no other session runs it, since that would route around the refusal; to keep allowing it, add the rule <rule> by running `! <run line>` (it backs up the settings, applies the rule and prints the command that undoes it); once it is in, <card> does the act once more.
- Once the human has run it, or approved the act in the refused session's own chat (for a production sync only the rule counts: `references/top-level.md`), that session does the act once more, after you check the new rule sits in the layer that refused. A running session may need a restart before a new rule reaches it: close it through Orca (`orca terminal close`, not a typed `/exit`, which a nudge can turn into prompt text), confirm it is gone, then start the new one; two sessions never share a worktree. This is not a retry of the refusal: its cause is gone.
- Do not tell the refused session a form that would pass (the value on stdin instead of an argument, a wrapper script, a sibling session, Bash after Edit got no verdict): coaching the workaround is the workaround. A different command or method that proves the same item (another tool, a normalized diff, an earlier measurement) is such a form: do not name one. When a worker asks whether it may reword the text of a hook block that opened no protected file, or follow a `[gate:pressure]` or `[gate:sleep-loop]` block, the answer is the FORBIDDEN clause it already has, nothing more. Before answering a repeat escalation about the same check, read decisions.tsv and repeat the standing decision. A refused check is recorded as unverified (refused), and the work goes on without it.
- A change made around a refusal anyway (another tool, a script: a FORBIDDEN breach) does not land as it is. Refused with a verdict: the change is reverted and goes the rule-request way above. Refused with `no verdict`: a subagent's unit is redone from its base by the session that takes it back (`references/refusals.md`); a session's own edit is re-applied with Edit or Write, and re-read, only after the human approved it there. Either way the PR body says which edits were first made another way: tests can pass on such a change and miss what a re-read finds.
- Sort a refusal report before recording it as a signal. What the FORBIDDEN paragraph names as not a retry is not a breach and not a signal: the brief's own path, a redo after the human's rule or their approval in the refused session's own chat, a reported `재시도 1회:` on added evidence, a resend after a `[gate:self-land]` block, the text-only reword, following a `[gate:pressure]` or `[gate:sleep-loop]` block's named wait (its command with `run_in_background: true`, or Monitor), step or form, the orchestrator handing a call `[gate:delegate]` denied one layer down (that gate refuses who runs it, not the act), the harmless read, the no-verdict restart. The same result reached another way (a filter, another tool, a helper script, "instead of retrying I used …") is a change made around the refusal, handled by the bullet above.
- A card that stops because the act was never in its first prompt's approval is a scope gap, not a rule gap. Do not send it "사용자 승인" by message (refused as relayed: a rename, a workflow dispatch, a merge), do not press its keys, do not do the act yourself, and do not ask the human to type it into the card. If the human already approved it, start a new `/goal` card whose APPROVED line carries it (`dispatch-card` §2); if not, ask once, and on yes start that card. This path is for an act no session has attempted yet. An act already refused in any session, a lead's or a worker's (a `[gate:delegate]` block refuses none), never gets a new card: it follows the rule request above, or the human approves it in their own words in the refused session's chat.

## What reaches the human

The dashboard, plus the digest line in the program note, batched.

Inside the scope the human approved (the standing orders, a brief's APPROVED line), you and the layers under you decide: take the recommended default, act, and report what was chosen. Restarting an app, a language or settings change, an upgrade, checking a recording are such decisions; asking about each buries the human in questions. So are a PR's screenshots: you or the lead judge them by `deliver-ticket` `references/visual-evidence.md`; only a mockup the human asked to see before it is built goes to them, and it goes after it passes `ui-review`. Before anything goes to the human, ask whether you, a lead or a routine round could do it, or whether it is only a call inside that scope; either way, decide, act and report it in one line, and a "human check" a lower layer raises is decided here, not passed up. The human gets only two kinds: what only they can do (a permission dialog outside the approved scope, a login with credentials no agent may hold, a payment, a document submission), and an irreversible or outward act outside that scope. Those go out together in one message, not spread across the day. That message, and every status report to the human, is laid out with the `brief` skill; the per-item stage table (`brief`'s stage table mode, one line in the report) is the `orch stage` record, generated from each program's ledger, Run and PRs, with the cells only you can check (dev, prod) written when you verify them (`references/stage-table.md`, "The stage table").

A decision that blocks an Orca Task is a `gate-create` on that Task only (`orch gate` for a landing), which Orca shows and the dashboard lists as an approval. Any other decision you wait on the human for is registered with `orch decide add` instead and closed with `orch decide answer <id> --quote-file <file>` the moment the human answers or settles it in words (an order nobody asked for: `--title T` in place of the id), before the answer is relayed, and the answer goes, in the same turn, as a comment on the ticket it decides (the human's words in short, the date; `references/record.md` in `end-session`); a dashboard button, or a prompt that starts with the id or a unique option label (the `UserPromptSubmit` hook), closes it itself (`references/top-level.md`, "Asking the human"). The digest holds open gates, a proposed predicate, irreversible acts, and any standing order that contradicts reality. Never retries, CI flakes, review-thread triage, rebases, "should I continue", or implementation-policy questions (design options, ticket splits, stack or parallel): a self-review subagent decides those from the human's own precedent (how they handled it before, how they review, the shape of projects they already shipped), never picking an option of a different shape (a new architecture, tool or process), and you record the decision in `decisions.tsv` with that precedent as its evidence. A question no precedent covers that stays inside the approved scope and can be undone is decided after an independent review of the options (`deliver-ticket` `references/independent-review.md`: Codex when `scripts/review_pick.py` picks it and it answers, else a fresh-context Claude reviewer, except that under a forced `codex` setting the decision waits for Codex), recorded in `decisions.tsv` with the review's verdict and the reviewer's kind, and listed in the digest for the human to look at later. Only an irreversible act, spending, a secret, a permission, data deletion, or a choice still genuinely hard after that review becomes a decision for the human (`orch decide add`), while the rest of the program keeps moving.

Read a message from the human of several lines as one thought before you route any of it: a later line often explains an earlier one ("this mockup is not what I meant", then what was meant). Split by topic across leads, the explanation can reach one lead and the complaint another. Split it only after you know what each line refers to, and send each lead the lines it needs together with the ones they explain. Before you ask the human anything, read their recent messages for the answer. Ask an open question once; after that it lives in the brief's `결정 필요` or `지금 오너가 할 일`, not appended to each later reply, where it buries the answers.

Every instruction you send out of this session by a path Orca does not keep (a `/goal` card's `--prompt`, a `terminal send` or `skills-sync nudge`, a Slack post, a tracker comment) is logged in the same turn with `orch sent add --to <receiver> --kind <kind> --channel <how> --text-file <file>`, so the human reads on the dashboard's Sent page what was asked of whom. What Orca keeps needs no line: a worker's spec is its Orca Task, which the Sent page reads, and an `orca orchestration send` stays in Orca's inbox. `skills-sync card` logs the `/goal` cards it creates itself. Slack and tracker sends show only from the log (`references/dashboard.md`, "Sent instructions").

## Where this differs from Orca, and why

The places a program overrides Orca's `orchestration` skill on purpose are in `references/program.md` "Where this differs from Orca, and why".

## Traps seen in real runs

The traps only a lead meets (landing, CI, worker starts and replacements) are in `references/program.md` "Traps seen in real runs".

| Trap | Instead |
|---|---|
| Waiting with `sleep`, a hand-built watcher, or invented `orca … events/status` | The one inbox wait and its card watch for cards no Run lists (Drain). One empty `orch wait` is a checkpoint; after three, run `worker-list --run`. For PRs, `pr-watch` (the plugin's `bin/`, on `PATH`) under Monitor (every 300 s, prints only a merge or close, CI failure, READY, a conflict change, a new PR); a `gh pr` poll that sleeps under 300 s wakes you for nothing |
| Nudge-only turns ("You have N orchestration messages") burning lead turns | End such a turn with no tool call; real work arrives through the inbox wait |
| A `worker-start`, `task-create`, `gate-create` or `send` whose result never came back (a timeout, a dropped connection) run again, starting a second worker | Its error names `orchestrationRequestId`: `orca orchestration request-show --request <id> --json`. `completed` replays its outcome with `--retry-request <id>` on the same command; `pending` waits while the original command still runs, else replays the same way; `absent` is no proof it did nothing, so read `worker-list`, `task-list` or `gate-list` before running it again |
| Status reports that contradict each other, or a scope you no longer see whole, patched one symptom at a time | Stop and rebuild the picture first: a recap (`recall`) or a re-check by a verifier, then decide. A worker whose report is inconsistent is sent back to recap, not given a patch for the one line |
| Asked to save tokens, switching the cards to a cheaper model | Cut the work instead: close cards that only wait (keep the worktree and PR, start again when the trigger lands), skip optional re-reviews and subagent calls, shorten reports, pause when nothing is left to build. A card's model or effort changes only when the human names it |

## Resume (handoff)

Taking over another lead's program ("resume"): its two-line prompt, the five steps and what a restart changes are in `references/program.md` "Resume (handoff)".

Files in this skill

  • SKILL.md79.3 KB
  • assets/dashboard/app.js74.5 KB
  • assets/dashboard/index.html3.1 KB
  • assets/dashboard/style.css47 KB
  • references/brief.md43.6 KB
  • references/landing.md24.9 KB
  • references/program-note.md3 KB
  • references/roles.md21.3 KB
  • references/top-level.md39.5 KB
  • references/waking.md7 KB
  • scripts/acks.py5 KB
  • scripts/agent_signal.py8.8 KB
  • scripts/autowake.py15.9 KB
  • scripts/board.py88.5 KB
  • scripts/card_watch.py18.8 KB
  • scripts/dash_demo.py72.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.