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