> ## Documentation Index
> Fetch the complete documentation index at: https://docs.claw.boo/llms.txt
> Use this file to discover all available pages before exploring further.

# Delegation and orchestration

> How Clawboo turns structured delegation signals from runtime events into durable board mutations instead of scraping prose.

When a team's leader decides a teammate should do something, that decision has to become real work: claimed, tracked, recovered if the run dies, and reported back when it's done. Clawboo's orchestrator is the machine that turns a delegation signal into a [board](/concepts/the-board) task and shepherds it to completion.

The orchestrator observes every team participant's [RuntimeEvent](/appendices/glossary) stream and reads **structured** delegation signals from typed lifecycle events, never from a regex over prose. A signal becomes a board task that is created, atomically [claimed](/concepts/the-board#the-atomic-claim), and delivered; the result rounds back to the board and reflects to the leader for synthesis. This page explains the structured-first contract, how a delegation flows end-to-end, how plans and fan-out are handled, the depth cap and the single reduce point, and what happens when a delegate fails or goes silent.

## What it is, and what it isn't

Orchestration is **board-driven**. A delegation does not live in chat scrollback; it lives as a durable board task with a claim, an execution row, and a status. Chat is narration of that state; the orchestrator reflects board mutations into the team room, but a chat message is never a write path back to the board. This is the same authority rule the board enforces: the board is canonical, [peer chat](/concepts/peer-chat) is narration.

The orchestrator is **structured-first**. It reads only typed lifecycle signals, never prose:

* a **`delegate` tool-call** (how a native leader hands work off) or a **`sessions_send` tool-call** (OpenClaw's built-in), each resolved to a target against the team roster, and
* a `<delegate>` or `<plan>` directive parsed once from a terminal `done` summary (the structured-output contract).

It does **not** scan prose for natural-language delegation intent. An earlier engine matched nine natural-language patterns (`@Name, please …`, `route to @Name`, and so on) plus an implicit fan-out heuristic over plural prose; that engine was retired. The structured-tag parsing the lifecycle path still needs was relocated into a pure parsing module (`delegationTags.ts`) that does tag extraction and stripping only; it does not interpret prose. Fan-out survives, but as a structured fact: two or more structured delegations in one turn become two or more parallel tasks.

<Note>
  Agents are *instructed* to emit the structured tags. The team's `AGENTS.md` (generated by `buildTeamAgentsMd`) tells each agent the required `<delegate to="@Name">task</delegate>` form and explicitly warns that plain prose `@`-mentions "are only a fallback and may not route." The tag parser tolerates common model drift (a dropped `<`, smart quotes, a mangled opener) by anchoring on the closing `</delegate>` plus the `to="…">` attribute shape; prose effectively never contains that shape, so the tolerance recovers weak-model output without false positives.

  On a server-orchestrated team, the OpenClaw adapter ignores the per-message tool blocklist, so tool-level enforcement alone is not enough. The orchestrator therefore injects the same contract, the `<delegate>` syntax plus an explicit "coordinate the existing team, and never spawn sub-agents" rule, into **every OpenClaw agent's volatile per-turn context** (`buildServerTeamContext`) on every OpenClaw run. A vanilla OpenClaw agent that never saw this brief reaches for its native `sessions_spawn` / `sessions_yield` tools and launches its own throwaway sub-agents, bypassing the real team and the board.
</Note>

## The model

A delegation flows from the delegator's terminal event through the board to the delegate, and the delegate's result flows back. The orchestrator is the per-team mediator in the middle.

```mermaid theme={"theme":{"light":"github-dark","dark":"github-dark"}}
sequenceDiagram
    participant L as Leader/delegator
    participant O as Orchestrator
    participant B as Board
    participant D as Delegate

    L->>O: done summary with <delegate> (or sessions_send tool-call)
    O->>O: extractSignals (structured only)
    O->>B: createTask (parentTaskId, sourceDelegationId)
    O->>B: claim (atomic; 409 = lost, never retried)
    O->>B: createExecution (the run ledger)
    O->>D: deliver task (nudge-queued; never interrupts a busy run)
    Note over D: runs to a terminal done
    D->>O: done(success, summary)
    O->>B: updateStatus → done + report-up comment + complete execution
    O->>B: pumpReady (auto-unblock dependent plan steps)
    O-->>L: [Task Update] reflection (batched, single reduce point)
```

The orchestrator core is a pure, framework-free function (`createBoardOrchestrator`) holding small in-memory maps that bridge a session to its task. It runs **server-side, as one long-lived instance per team** (`getTeamOrchestrator`): it observes each participant's [RuntimeEvent](/appendices/glossary) stream, feeds events to the core, routes deliveries through a nudge-queue, and writes board mutations that stream to the client. Because the engine lives on the server and is keyed to the durable board, a cascade runs to completion with no client connected and survives a tab close or a server restart, and hydrated history is never replayed as new work. The browser is a thin client: it posts the user's message (`POST /api/teams/:id/chat`), renders the live stream over Server-Sent Events (`/chat/stream`), and stops via REST (`/chat/stop`). The same core drives every runtime, including OpenClaw.

## How it works

### Reading a signal

For each observed event, the orchestrator extracts signals from typed fields only:

* A `tool-call` event whose name is `delegate` (a native leader's structured hand-off) or matches `sessions_send` (OpenClaw's built-in) becomes a single delegation, with the target resolved from the call's arguments (`assignee` / `sessionKey` / `agentId` / `label`) against the team roster.
* A `done` event with a `<plan>` block becomes an ordered list of plan steps.
* A `done` event with `<delegate>` blocks (and no plan) becomes a list of independent parallel delegations.

Self-delegations, unknown targets, and empty task bodies are filtered out. Anything that is not one of these typed shapes yields nothing; there is no prose fallback.

### Deriving a task

Each independent delegation runs through `spawn`, which is the DERIVE step of the board fusion:

1. Resolve the target's session; if it has none, tell the delegator (so it never waits forever) and stop.
2. Refuse if the same `(target, task)` has already failed `MAX_DELEGATION_FAILURES` (3) times in a row, a code-level loop breaker the model's own judgement can't override.
3. Refuse if the source task is already at the [depth cap](#the-depth-cap).
4. If the delegation is risky (a heuristic flags destructive/external verbs), surface it on the leader's approval queue and proceed only on `allow_once` / `allow_always`.
5. Create the board task (recording `parentTaskId` and a `sourceDelegationId` that encodes the delegator and the target on every delegation, deferred or not, so the target stays recoverable from the durable row after a sweep or an orphan release), then atomically claim it, open an execution row, and deliver the task message.

A claim that comes back `{ ok: false }` is a `409`, someone else owns the work, and is **never retried**, the same rule the board itself follows.

### Serial delivery and deferral

An agent has one team-scoped session, so it works delegations serially. If a target's session is already running another delegated task, the orchestrator does not overwrite the session-to-task mapping (which would orphan the first task and misattribute its completion). Instead it creates the second task as a durable `todo` with an `:agent:` marker in its `sourceDelegationId`, and the ready-pump fires it once the session frees. Delivery itself is routed through a non-destructive nudge-queue: a message to a busy session is queued FIFO and sent at the next turn boundary, never interrupting an in-flight run.

### Plans become dependency chains

A `<plan>` of ordered `<step>` blocks becomes a durable dependency chain on the board: step *i* is linked to depend on step *i−1*, so only step 0 starts ready. Each step's intended target is encoded in its task so the chain survives a refresh. When a step completes, the orchestrator runs `pumpReady`, which claims and delivers any step whose blocker just finished, auto-unblock. The board's ready query (`todo`, not dropped, every dependency `done`) and the atomic claim are the final arbiters of double-firing.

### Round-trip and reflect

When a delegate finishes successfully, the orchestrator runs the ROUND-TRIP and REFLECT steps: it moves the task to `done`, closes the execution as `succeeded`, and records the **summary** (not the transcript) as a report-up comment on the task. Completed tasks are batched within a short window into one `[Task Update]` message delivered to the **reduce point**, the immediate delegator (so a mid-chain delegator isn't left standing), falling back to the leader. The leader synthesizes across the batch. A success also resets the failure loop breaker for that `(agent, task)`.

### The single reduce point

The depth cap plus report-up-by-default establish a single point where results converge. A sub-task reports to its parent; a top-level task reports to the leader. On every delivery a **child tool blocklist** (`sessions_send`, `sessions_spawn`, `sessions_yield`) stops a delegate from re-delegating and any agent from spawning its own sub-agents. Enforcement is asymmetric: native and coding-runtime drivers strip the tools from the run outright, while the OpenClaw adapter can't block per-message, so Clawboo denies `sessions_spawn` / `sessions_yield` in the Gateway's `tools.deny` on connect (see [AgentSource](/internals/agent-source)). Recursion is bounded by the board's ancestor chain, not by a prompt.

### The depth cap

A source task at ancestor-depth `MAX_SPAWN_DEPTH` (2) or deeper may not spawn children. Depth is read from the board's ancestor chain (`getTask(...).ancestors.length`), so it is enforced by durable state rather than by trusting the model. A leader/user-initiated turn has no source task, it is depth 0, and may always delegate. Hitting the cap is reported: a system comment lands on the source task and the delegator is told to handle the work directly or report it back. Dispatch is not the only enforcement point. The board's capped create path applies the same ceiling at **creation** time, reached through the [Tasks MCP](/reference/mcp-tools#create_subtask) create tools, plus a per-parent live-child cap (24) — so a raw `create_subtask` loop from an attached runtime is bounded by the same durable state instead of filling the board with rows.

### Fan-out

Two or more structured delegations in one turn fire as parallel tasks. A per-turn fan-out cap (default 8) bounds how many one turn may spawn; overflow is counted and reported, not silently dropped. A system comment records the cap hit and the delegator is told to re-issue any dropped delegations in a follow-up.

## Failure handling

The orchestrator's hardest job is making sure a delegating agent is never "left standing", waiting forever for an answer that will never come. Every way a delegate can fail to deliver a result is handled and reflected:

| Failure               | How it's detected                                                                                                     | What happens                                                                    |
| --------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| Errored / out of room | a `done` with `reason` `error` / `max_turns`, or a fatal `error` event                                                | task → `blocked`, execution closed `failed`, failure reflected to the delegator |
| Went silent           | the idle watchdog (8 min, refreshed on every observed event; 24 min while the delegate is still inside one tool call) | task → `blocked` (timed-out), the live run aborted, failure reflected           |
| Session dropped       | the per-session observer ended outside teardown                                                                       | task → `blocked`, failure reflected                                             |
| Can't be delivered    | the nudge-queue rejects the send                                                                                      | task failed immediately, delegator told                                         |

When a task is blocked by failure, its downstream plan steps can never become ready, so the orchestrator cancels the still-pending (`todo` / `backlog`) transitive dependents and rolls them into the reflection; the delegator learns the whole chain stalled, not just one step. A failure reflection is a `[Task Update]` entry marked "DID NOT COMPLETE" with the reason, telling the leader to retry, reassign, or report the failure rather than keep waiting.

A user pressing **Stop** is deliberately *not* a failure. Stop is detected as a generation change since the delegation was dispatched; the task is released cleanly back to `todo` (re-runnable), with no `blocked`, no dependent cancellation, and no failure reflection, releasing the work the user just halted, not re-amplifying it.

## Design rationale and trade-offs

Prose-scanning orchestration is fundamentally a heuristic: an LLM is a creative writer and will always invent a delegation phrasing the regex didn't anticipate. The earlier engine's nine natural-language patterns were a maintenance treadmill, and a missed pattern meant a silently dropped delegation. The structured-first contract flips the burden: the agent is constrained to a machine-parseable directive, so a routed delegation comes from explicit intent rather than a guess. The cost is that the agent must be *told* the contract (the `AGENTS.md` instructions) and the parser must tolerate weak-model drift, which it does, by anchoring on the closing tag.

Making the board the substrate, rather than chat, buys durability and recoverability that narration can't. A board task survives a refresh as authority, can be atomically claimed so two clients can't both run it, and carries an execution ledger that crash recovery reads on restart. The trade-off is a second persistence layer beside each runtime's own session state, and an orchestrator that must carefully bridge an ephemeral session to a durable task, which is most of the in-memory bookkeeping in the core.

The depth cap, the report-up-to-a-single-reduce-point discipline, the fan-out cap, and the failure loop breaker are all enforced *in code, below the model*. A prompt can ask an agent to behave; only durable state and a hard counter can guarantee a bounded, terminating fan-out tree. The "leader left standing" class of bug, a delegating agent waiting forever on a dead delegate, is closed structurally by the watchdog plus the failure reflection, not by hoping a run always emits a clean terminal.

## Boundaries and non-goals

* **No prose interpretation.** The orchestrator does not infer delegation from natural language. A teammate that wants to delegate must emit a `<delegate>` / `<plan>` tag or call `sessions_send`; an `@`-mention in prose does not route.
* **Server-side, per team.** The engine runs on the server, one instance per team, observing every team member's runtime for structured signals. It is client-independent: closing the browser does not stop a cascade. The server-side executor runner (which runs spawned coding-agent board tasks) is a separate, complementary path.
* **Bounded fan-out, not arbitrary recursion.** Delegation depth is capped at 2 and per-turn fan-out at 8 by default. These are safety ceilings, not workflow limits; a deep or wide plan must be expressed as a `<plan>` chain or re-issued across turns.
* **The orchestrator coordinates; it does not execute.** It creates, claims, delivers, and reflects. The actual work happens inside the delegate's runtime, and the result is reported up as a condensed summary, never the raw transcript.

<Note>
  These docs describe Clawboo **v0.3.1**, the current release.
</Note>

## See also

* [The board](/concepts/the-board), the durable substrate every delegation becomes a task on
* [Peer chat](/concepts/peer-chat), the team room delegations narrate into
* [Verification](/concepts/verification), the builder-≠-judge gate a task crosses to reach `done`
* [Governance](/concepts/governance), the depth/fan-out/cost caps and the approval gate
* [Observability](/concepts/observability), the event log the orchestrator's mutations project into
* [Board API](/reference/rest-api/board), the REST surface the orchestrator drives
* [Glossary](/appendices/glossary), canonical term definitions
