v0.51.0 a9d674e

subagents.md RawHistoryFolder

Resident subagents

V0.x breaking change: zut no longer supports subprocess subagent state. Previous state is ignored rather than read or migrated; remove it when you no longer need it. Existing child jobs are never resumed.

V0.x breaking change: the separate subagent_spawn, subagent_status, subagent_stop, and subagent_resume tools are replaced by one subagent tool whose actions are selected by an action argument. --tools subagent_spawn no longer selects anything; use --tools subagent:spawn, or bare --tools subagent for every action. Under --no-yolo, "always allow" is remembered per action (subagent:status and subagent:spawn are separate grants), so approving a read-only status call never pre-approves any other action.

Subagents are independent core.Agent conversations resident in the same zut process as their parent. A child has a stable, private session identity, its own provider client and tool registry, a cancellation boundary, and an authoritative journal. Starting a child never launches another zut executable.

Profiles

Profiles are Markdown files discovered from ~/.agents/agents/*.md and paths in ZUT_AGENT_PROFILES. They are inputs only; zut does not execute them.

---
name: reviewer
description: Read-only code reviewer
tools: [read, grep]
model: openai-codex/gpt-5.6-luna
thinking: high
systemPromptMode: replace
inheritProjectContext: false
inheritSkills: false
fastMode: false
---

Inspect the requested scope and report evidence-backed findings.

tools is a capability boundary. An omitted value inherits the child-safe catalogue, tools: [] grants no tools, and an explicit list replaces the default. The child-safe catalogue contains only tools offered by the parent that are also available in the resolved child runtime; parent-only scheduling and extension tools are never inherited. Names unavailable to the child (including host-only extensions) and tools denied by subagents.allowed_tools are omitted from an explicit list; they never grant the child additional access. mcp in tools or subagents.allowed_tools selects every MCP tool; under headless --orchestrate, workers receive MCP tools the manager-only parent does not hold (see mcp.md). model, provider, thinking, the prompt mode, project/skill inheritance, and fastMode are resolved before the child is accepted. Spawn-level model, provider, reasoning, and fast-mode values take precedence where supplied.

Children are always fresh conversations: they receive the delegated task and resolved host/profile context, never the parent transcript or hidden reasoning. They cannot recursively create more children.

Lifecycle and persistence

The manager records each accepted child under its managed state root:

subagents/<child-id>/
  transcript.jsonl  # accepted turns, finalized messages, and compaction checkpoints
  owner.lock        # host-ownership coordination; do not modify or remove
  .transcript-backup-* # retained private pre-repair transcript, when repaired
  metadata.json     # rebuildable bounded state
  result.json       # latest outcome, final summary, artifacts
  patch.diff        # optional worktree capture

Acceptance is durable before the subagent tool's spawn action reports success. Finalized user, assistant, tool-call, and tool-result messages are journaled; streamed deltas and hidden reasoning are not exposed as ordinary history. A tool call is stored before execution and reconciliation repairs incomplete call/result pairs. A context-overflow recovery appends one child.compacted checkpoint carrying the replacement transcript; resume starts from the newest checkpoint, while the paged history view still shows everything appended before it.

All children stop when the host exits. On the next start, queued or running turns are marked interrupted; zut never replays their task. Resume only with an explicit new prompt through the subagent tool's resume action, the child-session composer, or /subagents resume <id> <prompt>.

Multiple zut processes may share a state root. Each resident journal has one host owner at a time. A process that finds a child owned elsewhere reports it as such and does not inspect, recover, or modify its transcript. Resume that child from its owning host or after the owner exits. On a subsequent safe reconciliation, zut repairs only the known legacy false-recovery sequence; it leaves any ambiguous journal corruption untouched. A repair retains the pre-repair transcript as .transcript-backup-*; it can contain private session data and is intentionally not removed automatically.

The subagent tool's status action reports owned_elsewhere: true when another process owns a child. The field is omitted when false. A foreign-owned child cannot be resumed, or have its history or result read, from this process.

The global scheduler admits the oldest eligible accepted prompt, runs at most one turn for each child, and defaults to six concurrent turns. Set subagents.max_concurrent to a positive limit to override it. Queueing is unlimited by default; a positive subagents.queue_timeout cancels an accepted prompt that has not received a slot and records its terminal failure durably. subagents.allowed_tools is an allowlist for child-visible tools and subagents.allowed_roots limits eligible child workspaces. Resident children have no cumulative token budget and no child-only step cap: a child inherits the parent's resolved limit, including the unlimited default. A turn is bounded by the provider context window, with one compaction recovery, and by an explicit parent --max-steps. Removed legacy settings, including tui_subagent_position and subagents.budget_ratio, are ignored. Resident journals written by older versions are read with explicit translation (an old budget_exhausted outcome reconciles as failure) or, for unknown versions, left untouched on disk and excluded from automatic discovery. Incompatible journals cannot be resumed; start a new child instead. Other journal recovery errors are still reported.

Compatibility notes: new journals write version 3 and carry no budget fields, baselines, or exhaustion states. Version 2 archives are read with explicit translation and their transcripts are never rewritten by translation. result.json keeps a deprecated handoff field that stays empty for new results and remains readable for archives. The subagent tool's status action no longer exposes budget or budget_source fields.

Context reminders

When a child's last-turn prompt reaches 85%, 90%, or 95% of its model context window, the runner injects a non-blocking reminder into the next provider request:

Context usage is at NN% of the model window. Finish the current task, report
results, limits, and remaining verifications, and do not start broad new work.

Each band fires at most once per child runner and reminders never block a turn. A jump straight to a higher band delivers one reminder for that band, and usage that falls does not re-deliver a band. Reminders travel as developer context in the live request; the durable transcript keeps only finalized history. Usage is the last-turn prompt size (input plus cache read/write tokens) against the resolved context window; an unknown window never triggers a reminder. The per-turn gauge resets when the host restarts and when a recovery compacts the context, so neither event reports a stale percentage. The band ladder itself advances at most once per child runner: a restart starts a fresh ladder, while a compacted child is reminded again only when usage reaches a higher band.

Context-overflow recovery

A provider request that exceeds the model context window ends the turn. When the transcript holds at least four messages, the child recovers once per turn: it compacts the transcript, keeps the two most recent messages verbatim, journals the replacement as a child.compacted record, and continues the same turn. A compaction or persistence failure restores the pre-compaction transcript and fails the turn, and a second overflow stays terminal. Recovery never replenishes an explicit parent --max-steps: when the allowance is already spent, the checkpoint is still written for a later resume, but the turn is not continued.

Explicit resume replays the newest checkpoint instead of the full append-only log. The history views (/subagents logs, HistoryPage, subagent:// refs) still show the append-only log, including pre-compaction records. A build that predates checkpoint support cannot resume such a child correctly; downgrading is unsupported.

The summarization request itself can be rejected when a single oversized message leaves nothing to summarize away. The turn then fails with the original provider error and no checkpoint is written, so the child keeps failing on resume until its transcript shrinks. Recovery is a best effort, not a guarantee.

Retrieve the saved result without executing a model:

{"action":"status","agent_id":"<child-id>","include_result":true}

Pass this to the subagent tool's status action, then reconcile the history and artifacts before repeating any side effects. The subagent tool's explicit resume action after a terminal failure continues the retained session, workspace, and cumulative cost. It does not automatically retry the task. Ordinary follow-ups continue the existing session.

required: true makes a delegated result an obligation of the parent turn. Failed, cancelled, and interrupted required work remains unresolved until an explicit successful follow-up. Reading a saved result or accepting a recovery prompt does not satisfy the obligation. A host restart never retries it automatically.

Delegation ownership

Interactive proactive delegation makes the primary agent an orchestrator that delegates by default. Implementation, debugging, testing, review, and broad research go to workers; answers, quick lookups, edits of a few lines, and integration of worker results stay local. Blocking work is delegated too: the primary spawns it with required: true and yields for the completion update.

Routing happens for each new request, not at process start: the reply that starts the work names each part, its owner, and the profile for each delegated part. The routing guidance is part of the prompt only when launch-time policy exposes the spawn action.

Before spawning, the primary maps dependencies, runs independent parts in parallel, and gives every worker a self-contained task with a disjoint scope. For a multi-part feature it creates a feature worktree branch, then one sub-worktree per worker with worktree create and base set to the feature branch. It reviews each result, commits on the sub-branch, and merges it into the feature branch. It then removes merged sub-worktrees and their branches with worktree cleanup, into set to the feature branch and delete_branch: true, and checks with list that none are left behind.

While a child is active, it owns that scope; the primary does not repeat its investigation, review, testing, or implementation. Once an isolation: "worktree" child succeeds, the primary may apply and verify its captured patch without redoing the task, then stop the idle child so its temporary worktree is removed.

Explicit headless --orchestrate remains manager-only. Its primary divides the request into disjoint worker scopes, coordinates active children, and yields rather than implementing or reproducing delegated work. Children do not inherit the parent's strict orchestrator role. Headless orchestration waits for every accepted child before continuing its completion wave; required: true additionally creates a durable obligation. When proactive interactive delegation cannot spawn because of launch-time policy, the primary continues locally; a strict headless orchestrator instead reports the missing required capability.

Tools and slash commands

The model-facing tool keeps one logical name and five actions, selected by its action argument. Launch-time gating is per action: --tools subagent grants every action, --tools subagent:<action> grants one, and --no-tools disables all of them.

  • subagent accepts an action of spawn, status, stop, resume, or interrupt.
    • spawn accepts task, optional agent, model and provider, reasoning, fast_mode, required, wait, and isolation (shared or worktree). wait is an explicit whole-second value from 1 through 300; when omitted, spawning returns immediately. A timed-out wait leaves the accepted child active, whether it is queued or running. Do not retry that task until it reaches a terminal failure, cancellation, or interruption. It returns a logical subagent://<id> reference.

    • status accepts optional agent_id and include_result, and returns bounded current state for one child or the current set immediately. With agent_id and include_result: true, it also reads the saved terminal result without model execution. Without this option it remains metadata-only; foreign-owned results cannot be read. Result-read errors distinguish foreign ownership, a missing saved result, and permission denial without exposing filesystem paths or saved content. With agent_id, a running child also includes activity: a phase (waiting_for_model, writing, tools, or working), the tail of its visible text, and its active tools with truncated arguments. Hidden reasoning is never exposed. watch (1–60 seconds, requires agent_id) observes that activity and returns a timeline of phase and tool changes. It returns early when the child stops running. Use it to inspect progress, not to wait for completion. pending_followups counts follow-ups the child has accepted but not read yet.

    • stop accepts agent_id and stops one live child.

    • resume accepts agent_id, prompt, optional mode, and optional wait. prompt is an explicit follow-up prompt for an existing child. Do not use resume solely to wait for existing work or ask for its result again: yield for the automatic completion update. queue schedules another turn and produces another completion. After a terminal failure, inspect the saved result before resuming; resume continues the retained session. mode controls how a follow-up reaches a running child:

      • steer (default) injects it into the current turn at the next tool or model boundary, like typing while the main agent works. It adds no new turn and no extra completion.
      • queue runs it as a separate turn after the current one.

      An idle or stopped child starts a new turn in either mode, and a steer never jumps ahead of already queued turns. The response's delivery is steered or queued. wait uses the same 1–300 second bound as spawn and waits for the turn that answers the follow-up, returning its outcome or reporting the timeout while the child stays active. A returned outcome can be dropped when a queued follow-up never started. When the host accepts the completion report, the summary and undelivered steers arrive in the completion update; otherwise the outcome includes them.

    • interrupt accepts agent_id and cancels only the child's running turn. Unlike stop, the child stays live with its transcript, so a later resume such as "report what you have" continues with full context. Queued follow-ups are dropped. It fails when no turn is running.

When a turn ends before the child reads a steered follow-up, for example after stop, interrupt, or a failure, the completion update lists it as undelivered. Queued follow-ups that never started are reported as dropped. Neither appears as an interrupted task.

Child execution started by the subagent tool's spawn or resume action is asynchronous unless it receives an explicit wait value. For an unwaited call, completion arrives through the host’s typed completion update; the subagent tool's status action returns immediately and does not wait for completion. Do not use sleep loops, repeated status calls, journal files, or terminal UI inspection as a completion signal. When the host accepts a completion report, a completed spawn or resume wait returns terminal status and report_delivery: host_update; the full report arrives only through the completion update, not again in the tool result. If no host observer accepts the report, the tool result includes it inline. An expired wait does not suppress later completion delivery. Cancelling the parent turn discards pending completion updates; cancelling only a tool wait leaves host tracking intact. In interactive mode, a result received while the primary is busy enters the visible sliding in queue and reaches the model at its next safe boundary, without interrupting a model request or tool call and without waiting for other children. Results already queued are not repeated when the parent turn ends. Undelivered results remain queued after a provider or compaction error for the next turn; they do not automatically retry the failed request. Explicit cancellation clears pending queue entries. The queue is in memory, while the child’s saved result remains available through the subagent tool's status action. When the primary is idle, each child completion immediately starts the next parent turn instead of waiting for its siblings. The host update names the finished child and lists sibling agent IDs that are still running. A completion that arrives while that parent turn is active slides into its queue. Headless orchestration still waits for every accepted child before its next parent turn. Successful completions include the final visible assistant summary, capped at 256 KiB; open the child session for the complete durable transcript.

/subagents opens the resident-child list, ordered by the latest state change. Each row leads with the profile (or model), shows a human terminal state such as completed, a relative update time, and a short ID. Press Down from the main composer to open this list without clearing a draft when a child exists. Use arrows and Enter to open a child session; /subagents new <task> creates a child; /subagents logs <id> opens its history; /subagents result <id> shows the bounded final summary; kill <id> stops it; and resume <id> <prompt> continues it. A prompt sent from the child composer or resume to a running child steers its current turn.

The child session uses the same transcript renderer as the main session. Recent history is bounded and loaded asynchronously; PgUp asks for an older page. Up/Down preserves the current reading position, and PgDn returns to the live tail after unread updates accumulate. The screen combines durable finalized history with an immutable in-memory projection of the active turn. Enter submits the local composer only after the manager durably accepts it; Esc closes the session. History may contain task text, tool arguments, tool results, and source-derived output, so treat it as private local session data.

Worktrees and references

Shared children use the host working directory. With isolation: "worktree", zut prepares a detached Git worktree and captures a patch and changed-file list on successful completion or non-cancelled failure. Failed turns retain partial work in the worktree, along with any captured patch and changed-file list. zut never applies a captured patch automatically. Failed or interrupted worktrees are retained for inspection; an idle successful worktree is cleaned when its child is explicitly stopped.

Use the subagent tool's status action with agent_id and include_result: true to retrieve the saved result, changed_files, and patch_ref when a patch was captured. The patch bytes are stored in subagents/<child-id>/patch.diff under the managed state root shown above; logical references are identifiers, not filesystem paths. Inspect the retained worktree and patch before resuming or applying partial changes.

New terminal journal records also save the capture metadata, so reconciliation can restore it if result.json is missing or corrupt. Older records remain readable, but cannot reconstruct artifact metadata they never recorded.

Logical references avoid exposing runtime paths:

subagent://<id>
subagent://<id>/history
subagent://<id>/result
subagent://<id>/patch

Provider caching

Each main and child conversation sends a stable logical session ID and a new turn ID per accepted prompt to the provider layer. Provider adapters decide whether and how to use them: OpenAI/Codex translates a supported stable session into its cache key and routing header, while other adapters preserve deterministic request input and use only cache controls their provider/model/endpoint supports. An OpenAI-compatible wire shape is not itself evidence that a cache extension or transport feature is available. Models continue through their declared provider transport; a transport change must not change the logical session or turn identity used by the provider request.

source
1# Resident subagents
2
3> **V0.x breaking change:** zut no longer supports subprocess subagent state.
4> Previous state is ignored rather than read or migrated; remove it when you
5> no longer need it. Existing child jobs are never resumed.
6
7> **V0.x breaking change:** the separate `subagent_spawn`, `subagent_status`,
8> `subagent_stop`, and `subagent_resume` tools are replaced by one `subagent`
9> tool whose actions are selected by an `action` argument.
10> `--tools subagent_spawn` no longer selects anything; use
11> `--tools subagent:spawn`, or bare `--tools subagent` for every action.
12> Under `--no-yolo`, "always allow" is remembered per action
13> (`subagent:status` and `subagent:spawn` are separate grants), so approving a
14> read-only `status` call never pre-approves any other action.
15
16Subagents are independent `core.Agent` conversations resident in the same zut
17process as their parent. A child has a stable, private session identity, its own
18provider client and tool registry, a cancellation boundary, and an authoritative
19journal. Starting a child never launches another zut executable.
20
21## Profiles
22
23Profiles are Markdown files discovered from `~/.agents/agents/*.md` and paths
24in `ZUT_AGENT_PROFILES`. They are inputs only; zut does not execute them.
25
26```markdown
27---
28name: reviewer
29description: Read-only code reviewer
30tools: [read, grep]
31model: openai-codex/gpt-5.6-luna
32thinking: high
33systemPromptMode: replace
34inheritProjectContext: false
35inheritSkills: false
36fastMode: false
37---
38
39Inspect the requested scope and report evidence-backed findings.
40```
41
42`tools` is a capability boundary. An omitted value inherits the child-safe
43catalogue, `tools: []` grants no tools, and an explicit list replaces the
44default. The child-safe catalogue contains only tools offered by the parent
45that are also available in the resolved child runtime; parent-only scheduling
46and extension tools are never inherited. Names unavailable to the child
47(including host-only extensions) and tools denied by `subagents.allowed_tools`
48are omitted from an explicit list; they never grant the child additional
49access. `mcp` in `tools` or `subagents.allowed_tools` selects every MCP tool;
50under headless `--orchestrate`, workers receive MCP tools the manager-only
51parent does not hold (see [mcp.md](mcp.md)). `model`, `provider`, `thinking`,
52the prompt mode, project/skill inheritance, and `fastMode` are resolved before
53the child is accepted. Spawn-level model, provider, reasoning, and fast-mode
54values take precedence where supplied.
55
56Children are always fresh conversations: they receive the delegated task and
57resolved host/profile context, never the parent transcript or hidden reasoning.
58They cannot recursively create more children.
59
60## Lifecycle and persistence
61
62The manager records each accepted child under its managed state root:
63
64```text
65subagents/<child-id>/
66  transcript.jsonl  # accepted turns, finalized messages, and compaction checkpoints
67  owner.lock        # host-ownership coordination; do not modify or remove
68  .transcript-backup-* # retained private pre-repair transcript, when repaired
69  metadata.json     # rebuildable bounded state
70  result.json       # latest outcome, final summary, artifacts
71  patch.diff        # optional worktree capture
72```
73
74Acceptance is durable before the `subagent` tool's `spawn` action reports
75success. Finalized user, assistant, tool-call, and tool-result messages are
76journaled; streamed deltas and hidden reasoning are not exposed as ordinary
77history. A tool call is stored before execution and reconciliation repairs
78incomplete call/result pairs. A context-overflow recovery appends one
79`child.compacted` checkpoint carrying the replacement transcript; resume
80starts from the newest checkpoint, while the paged history view still shows
81everything appended before it.
82
83All children stop when the host exits. On the next start, queued or running
84turns are marked `interrupted`; zut never replays their task. Resume only with
85an explicit new prompt through the `subagent` tool's `resume` action, the
86child-session composer, or `/subagents resume <id> <prompt>`.
87
88Multiple zut processes may share a state root. Each resident journal has one
89host owner at a time. A process that finds a child owned elsewhere reports it
90as such and does not inspect, recover, or modify its transcript. Resume that
91child from its owning host or after the owner exits. On a subsequent safe
92reconciliation, zut repairs only the known legacy false-recovery sequence; it
93leaves any ambiguous journal corruption untouched. A repair retains the
94pre-repair transcript as `.transcript-backup-*`; it can contain private session
95data and is intentionally not removed automatically.
96
97The `subagent` tool's `status` action reports `owned_elsewhere: true` when
98another process owns a child. The field is omitted when false. A foreign-owned
99child cannot be resumed, or have its history or result read, from this process.
100
101The global scheduler admits the oldest eligible accepted prompt, runs at most
102one turn for each child, and defaults to six concurrent turns. Set
103`subagents.max_concurrent` to a positive limit to override it. Queueing is
104unlimited by default; a positive `subagents.queue_timeout` cancels an accepted
105prompt that has not received a slot and records its terminal failure durably.
106`subagents.allowed_tools` is an allowlist for child-visible tools and
107`subagents.allowed_roots` limits eligible child workspaces. Resident children
108have no cumulative token budget and no child-only step cap: a child inherits
109the parent's resolved limit, including the unlimited default. A turn is bounded
110by the provider context window, with one compaction recovery, and by an
111explicit parent `--max-steps`. Removed legacy
112settings, including `tui_subagent_position` and `subagents.budget_ratio`, are
113ignored. Resident journals written by older versions are read with explicit
114translation (an old `budget_exhausted` outcome reconciles as failure) or, for
115unknown versions, left untouched on disk and excluded from automatic
116discovery. Incompatible journals cannot be resumed; start a new child
117instead. Other journal recovery errors are still reported.
118
119Compatibility notes: new journals write version 3 and carry no budget
120fields, baselines, or exhaustion states. Version 2 archives are read with
121explicit translation and their transcripts are never rewritten by
122translation. `result.json` keeps a deprecated `handoff` field that stays
123empty for new results and remains readable for archives. The `subagent` tool's
124`status` action no longer exposes `budget` or `budget_source` fields.
125
126### Context reminders
127
128When a child's last-turn prompt reaches 85%, 90%, or 95% of its model context
129window, the runner injects a non-blocking reminder into the next provider
130request:
131
132```text
133Context usage is at NN% of the model window. Finish the current task, report
134results, limits, and remaining verifications, and do not start broad new work.
135```
136
137Each band fires at most once per child runner and reminders never block a turn.
138A jump straight to a higher band delivers one reminder for that band, and usage
139that falls does not re-deliver a band. Reminders travel as developer context in
140the live request; the durable transcript keeps only finalized history. Usage is
141the last-turn prompt size (input plus cache read/write tokens) against the
142resolved context window; an unknown window never triggers a reminder. The
143per-turn gauge resets when the host restarts and when a recovery compacts the
144context, so neither event reports a stale percentage. The band ladder itself
145advances at most once per child runner: a restart starts a fresh ladder, while a
146compacted child is reminded again only when usage reaches a higher band.
147
148### Context-overflow recovery
149
150A provider request that exceeds the model context window ends the turn. When
151the transcript holds at least four messages, the child recovers once per turn:
152it compacts the transcript, keeps the two most recent messages verbatim,
153journals the replacement as a `child.compacted` record, and continues the same
154turn. A compaction or persistence failure restores the pre-compaction
155transcript and fails the turn, and a second overflow stays terminal. Recovery
156never replenishes an explicit parent `--max-steps`: when the allowance is
157already spent, the checkpoint is still written for a later resume, but the turn
158is not continued.
159
160Explicit resume replays the newest checkpoint instead of the full append-only
161log. The history views (`/subagents logs`, `HistoryPage`, `subagent://` refs)
162still show the append-only log, including pre-compaction records. A build that
163predates checkpoint support cannot resume such a child correctly; downgrading
164is unsupported.
165
166The summarization request itself can be rejected when a single oversized
167message leaves nothing to summarize away. The turn then fails with the original
168provider error and no checkpoint is written, so the child keeps failing on
169resume until its transcript shrinks. Recovery is a best effort, not a
170guarantee.
171
172Retrieve the saved result without executing a model:
173
174```json
175{"action":"status","agent_id":"<child-id>","include_result":true}
176```
177
178Pass this to the `subagent` tool's `status` action, then reconcile the history
179and artifacts before repeating any side effects. The `subagent` tool's explicit
180`resume` action after a terminal failure continues the retained session,
181workspace, and cumulative cost. It does not automatically retry the task.
182Ordinary follow-ups continue the existing session.
183
184`required: true` makes a delegated result an obligation of the parent turn.
185Failed, cancelled, and interrupted required work remains
186unresolved until an explicit successful follow-up. Reading a saved result or
187accepting a recovery prompt does not satisfy the obligation. A host restart never
188retries it automatically.
189
190## Delegation ownership
191
192Interactive proactive delegation makes the primary agent an orchestrator that
193delegates by default. Implementation, debugging, testing, review, and broad
194research go to workers; answers, quick lookups, edits of a few lines, and
195integration of worker results stay local. Blocking work is delegated too: the
196primary spawns it with `required: true` and yields for the completion update.
197
198Routing happens for each new request, not at process start: the reply that
199starts the work names each part, its owner, and the profile for each delegated
200part. The routing guidance is part of the prompt only when launch-time policy
201exposes the spawn action.
202
203Before spawning, the primary maps dependencies, runs independent parts in
204parallel, and gives every worker a self-contained task with a disjoint scope.
205For a multi-part feature it creates a feature worktree branch, then one
206sub-worktree per worker with `worktree` `create` and `base` set to the feature
207branch. It reviews each result, commits on the sub-branch, and merges it into
208the feature branch. It then removes merged sub-worktrees and their branches
209with `worktree` `cleanup`, `into` set to the feature branch and
210`delete_branch: true`, and checks with `list` that none are left behind.
211
212While a child is active, it owns that scope; the primary does not repeat its
213investigation, review, testing, or implementation. Once an
214`isolation: "worktree"` child succeeds, the primary may apply and verify its
215captured patch without redoing the task, then stop the idle child so its
216temporary worktree is removed.
217
218Explicit headless `--orchestrate` remains manager-only. Its primary divides the
219request into disjoint worker scopes, coordinates active children, and yields
220rather than implementing or reproducing delegated work. Children do not inherit
221the parent's strict orchestrator role. Headless orchestration waits for every
222accepted child before continuing its completion wave; `required: true`
223additionally creates a durable obligation. When proactive
224interactive delegation cannot spawn because of launch-time policy, the primary
225continues locally; a strict headless orchestrator instead reports the missing
226required capability.
227
228## Tools and slash commands
229
230The model-facing tool keeps one logical name and five actions, selected by its
231`action` argument. Launch-time gating is per action: `--tools subagent` grants
232every action, `--tools subagent:<action>` grants one, and `--no-tools` disables
233all of them.
234
235- `subagent` accepts an `action` of `spawn`, `status`, `stop`, `resume`, or
236  `interrupt`.
237  - `spawn` accepts `task`, optional `agent`, `model` and `provider`,
238    `reasoning`, `fast_mode`, `required`, `wait`, and `isolation` (`shared` or
239    `worktree`).
240    `wait` is an explicit whole-second value from 1 through 300; when omitted,
241    spawning returns immediately. A timed-out wait leaves the
242    accepted child active, whether it is queued or running. Do not retry that
243    task until it reaches a terminal failure, cancellation, or interruption. It
244    returns a logical `subagent://<id>` reference.
245  - `status` accepts optional `agent_id` and `include_result`, and returns
246    bounded current state for one child or the current set immediately. With
247    `agent_id` and `include_result: true`, it also reads the saved terminal
248    result without model execution. Without this option it remains
249    metadata-only; foreign-owned results cannot be read. Result-read errors
250    distinguish foreign ownership, a missing saved result, and permission
251    denial without exposing filesystem paths or saved content.
252    With `agent_id`, a running child also includes `activity`: a `phase`
253    (`waiting_for_model`, `writing`, `tools`, or `working`), the tail of its
254    visible text, and its active tools with truncated arguments. Hidden
255    reasoning is never exposed. `watch` (1–60 seconds, requires `agent_id`)
256    observes that activity and returns a `timeline` of phase and tool changes.
257    It returns early when the child stops running. Use it to inspect progress,
258    not to wait for completion. `pending_followups` counts follow-ups the
259    child has accepted but not read yet.
260  - `stop` accepts `agent_id` and stops one live child.
261  - `resume` accepts `agent_id`, `prompt`, optional `mode`, and optional
262    `wait`. `prompt` is an explicit follow-up prompt for an existing child.
263    Do not use `resume` solely to wait for existing work or ask for its result
264    again: yield for the automatic completion update. `queue` schedules another
265    turn and produces another completion.
266    After a terminal failure, inspect the saved result before resuming; resume
267    continues the retained session. `mode` controls how a follow-up reaches a
268    running child:
269    - `steer` (default) injects it into the current turn at the next tool or
270      model boundary, like typing while the main agent works. It adds no new
271      turn and no extra completion.
272    - `queue` runs it as a separate turn after the current one.
273
274    An idle or stopped child starts a new turn in either mode, and a steer
275    never jumps ahead of already queued turns. The response's `delivery` is
276    `steered` or `queued`. `wait` uses the same 1–300 second bound as `spawn`
277    and waits for the turn that answers the follow-up, returning its outcome or
278    reporting the timeout while the child stays active. A returned outcome can
279    be `dropped` when a queued follow-up never started. When the host accepts
280    the completion report, the summary and `undelivered` steers arrive in the
281    completion update; otherwise the outcome includes them.
282  - `interrupt` accepts `agent_id` and cancels only the child's running turn.
283    Unlike `stop`, the child stays live with its transcript, so a later
284    `resume` such as "report what you have" continues with full context.
285    Queued follow-ups are dropped. It fails when no turn is running.
286
287When a turn ends before the child reads a steered follow-up, for example after
288`stop`, `interrupt`, or a failure, the completion update lists it as
289`undelivered`. Queued follow-ups that never started are reported as `dropped`.
290Neither appears as an interrupted task.
291
292Child execution started by the `subagent` tool's `spawn` or `resume` action is
293asynchronous unless it receives an explicit `wait` value. For an unwaited call,
294completion arrives through the host’s typed completion update; the `subagent`
295tool's `status` action returns immediately and does not wait for completion. Do
296not use sleep loops, repeated status calls, journal files, or terminal UI
297inspection as a completion signal.
298When the host accepts a completion report, a completed `spawn` or `resume`
299wait returns terminal status and `report_delivery: host_update`; the full report
300arrives only through the completion update, not again in the tool result.
301If no host observer accepts the report, the tool result includes it inline.
302An expired wait does not suppress later completion delivery. Cancelling the
303parent turn discards pending completion updates; cancelling only a tool wait
304leaves host tracking intact.
305In interactive mode, a result received while the primary is busy enters the
306visible **sliding in** queue and reaches the model at its next safe boundary,
307without interrupting a model request or tool call and without waiting for other
308children. Results already queued are not repeated when the parent turn ends.
309Undelivered results remain queued after a provider or compaction error for the
310next turn; they do not automatically retry the failed request. Explicit
311cancellation clears pending queue entries. The queue is in memory, while the
312child’s saved result remains available through the `subagent` tool's `status`
313action.
314When the primary is idle, each child completion immediately starts the next
315parent turn instead of waiting for its siblings. The host update names the
316finished child and lists sibling agent IDs that are still running. A completion
317that arrives while that parent turn is active slides into its queue. Headless
318orchestration still waits for every accepted child before its next parent turn.
319Successful completions include the final visible assistant summary, capped at
320256 KiB; open the child session for the complete durable transcript.
321
322`/subagents` opens the resident-child list, ordered by the latest state change.
323Each row leads with the profile (or model), shows a human terminal state such
324as `completed`, a relative update time, and a short ID. Press Down from the
325main composer to open this list without clearing a draft when a child exists.
326Use arrows and Enter to open a child session; `/subagents new <task>` creates a child; `/subagents logs <id>`
327opens its history; `/subagents result <id>` shows the bounded final summary;
328`kill <id>` stops it; and `resume <id> <prompt>` continues it. A prompt sent
329from the child composer or `resume` to a running child steers its current turn.
330
331The child session uses the same transcript renderer as the main session.
332Recent history is bounded and loaded asynchronously; PgUp asks for an older
333page. Up/Down preserves the current reading position, and PgDn returns to the
334live tail after unread updates accumulate. The screen combines durable finalized
335history with an immutable in-memory projection of the active turn. Enter submits
336the local composer only after the manager durably accepts it; Esc closes the session. History may contain task
337text, tool arguments, tool results, and source-derived output, so treat it as
338private local session data.
339
340## Worktrees and references
341
342Shared children use the host working directory. With `isolation: "worktree"`,
343zut prepares a detached Git worktree and captures a patch and changed-file list
344on successful completion or non-cancelled failure. Failed turns retain
345partial work in the worktree, along with any captured patch and changed-file
346list. zut never applies a captured patch automatically. Failed or interrupted
347worktrees are retained for inspection; an idle successful worktree is cleaned
348when its child is explicitly stopped.
349
350Use the `subagent` tool's `status` action with `agent_id` and
351`include_result: true` to retrieve the saved result, `changed_files`, and
352`patch_ref` when a patch was captured. The
353patch bytes are stored in `subagents/<child-id>/patch.diff` under the managed
354state root shown above; logical references are identifiers, not filesystem
355paths. Inspect the retained worktree and patch before resuming or applying
356partial changes.
357
358New terminal journal records also save the capture metadata, so reconciliation
359can restore it if `result.json` is missing or corrupt. Older records remain
360readable, but cannot reconstruct artifact metadata they never recorded.
361
362Logical references avoid exposing runtime paths:
363
364```text
365subagent://<id>
366subagent://<id>/history
367subagent://<id>/result
368subagent://<id>/patch
369```
370
371## Provider caching
372
373Each main and child conversation sends a stable logical session ID and a new
374turn ID per accepted prompt to the provider layer. Provider adapters decide
375whether and how to use them: OpenAI/Codex translates a supported stable session
376into its cache key and routing header, while other adapters preserve deterministic
377request input and use only cache controls their provider/model/endpoint supports.
378An OpenAI-compatible wire shape is not itself evidence that a cache extension
379or transport feature is available. Models continue through their declared
380provider transport; a transport change must not change the logical session or
381turn identity used by the provider request.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close