返回 CodeWhale
SUBAGENTS.md
根目录 / docs / SUBAGENTS.md
1 # Fleet and sub-agents
2
3 > 阅读简体中文版:[zh_hans/SUBAGENTS.md](zh_hans/SUBAGENTS.md)
4
5 Fleet manages saved models and role assignments for these same sub-agents.
6 Use `agent` for an individual assignment and `workflow` for phases with
7 dependencies and completion checks. See [Workflow authoring](WORKFLOW_AUTHORING.md)
8 for plans that use the Fleet model shortlist.
9
10 Fleet roles are the user-facing vocabulary for delegated work: a parent
11 launches a focused `general`, `explore`, `planner`, `reviewer`, `implement`,
12 `test`, or `advisor` through `agent` and gets back an `agent_id`, declared
13 deliverables, and effective limits while the worker runs. The default receipt is
14 compact; request addressed detail when you need the transcript handle or ledger.
15 The internal runtime type is `FleetRole` (formerly
16 `SubAgentType`); the older role spellings (`worker`, `scout`, `plan`,
17 `review`, `builder`, `verifier`, `consultant`, `oracle`, …) remain accepted only as a persisted/deserialize
18 compatibility adapter during v0.9.x. New prompts and config should use fleet
19 names.
20
21 Architecturally, sub-agents should not be a second execution substrate. The
22 durable primitive is the fleet-backed worker run described in
23 [`AGENT_RUNTIME.md`](AGENT_RUNTIME.md): retries, terminal status, receipts,
24 artifact refs, inspection, and restart behavior belong there. The
25 model-facing launcher is the single `agent` tool and detached work should
26 converge on the same lifecycle as Agent fleet.
27
28 The current `agent` implementation delegates to the durable sub-agent runtime
29 while that cutover completes. It can still be useful for short in-session
30 delegation. Transient provider header/stream/time-out failures are retried with
31 backoff inside the child runtime before the worker is marked interrupted; if the
32 retry budget is exhausted, Codewhale preserves a checkpoint and returns a
33 continuation handle instead of leaving the parent to infer what happened. For
34 work that must survive process restarts, sleep, or remote execution, prefer
35 fleet or a Workflow-backed fleet run.
36
37 Sub-agents inherit the parent's permitted tool registry, including `agent`
38 coordination. Spawning obeys one absolute depth ceiling: the root is depth 0,
39 its child is depth 1, and a child at `max_spawn_depth` cannot spawn again.
40 The operator default is 3, with a hard ceiling of 8. A role, saved profile, or
41 compatibility request can only narrow that ceiling. Recovery and transcript
42 forking retain the source's position and bounds; they do not buy another
43 generation. The removed `agent_open`/`agent_eval`/`agent_close` lifecycle tools
44 are absent from every registry.
45
46 Healthy children continue after an ordinary parent response. Their completion
47 returns through the existing Engine inbox and can wake the parent for another
48 normal turn. Explicit interruption or cancellation remains authoritative.
49 `detached: true` additionally opts a subtree out of parent-turn cancellation;
50 it does not remove child budgets or the headless host's deadline.
51
52 This doc covers roles and individual worker controls. Use `workflow` to coordinate
53 multiple assignments through the same worker runtime; see the sub-agent guidance in
54 `crates/tui/src/prompts/text.rs` (`AGENT_MODE`) and the in-line
55 tool description.
56
57 ## Role taxonomy
58
59 The `type` field on `agent` selects a fleet posture for the child
60 (`agent_type` is accepted as a compatibility alias). Each role is a distinct
61 stance toward the work — not just a different label.
62
63 ## Maintainer posture
64
65 Sub-agents help Codewhale move faster, but the parent agent still owns the
66 maintainer decision. Use children to gather evidence, review patches, and run
67 verification while keeping the community posture in
68 [`AGENT_ETHOS.md`](AGENT_ETHOS.md): issues are open intake, PR gates are
69 review-load controls, and harvested work needs clear contributor credit.
70
71 When a child reviews community work, the parent should still inspect the PR
72 diff, linked issues, tests, and CI before merging, harvesting, closing, or
73 deferring it. A sub-agent's result is a working set, not a substitute for
74 stewardship.
75
76 | Role | Stance | Writes? | Network? | Shell posture | Typical use |
77 |---------------|----------------------------------------|---------|----------|---------------|----------------------------------------------|
78 | `general` | flexible; do whatever the parent says | yes | yes | yes | the default; multi-step tasks |
79 | `explore` | read-only; map the relevant code fast | no | yes | read-only (net + bounded verify) | "find every call site of `Foo`; check the PR with gh" |
80 | `planner` | analyse and produce a strategy | no | yes | read-only probes | "design the migration; don't execute" |
81 | `reviewer` | read-and-grade with severity scores | no | yes | read-only (net + bounded verify) | "audit this PR for bugs" |
82 | `implement` | land a specific change with min edit | yes | yes | yes | "rewrite `bar.rs::Foo::bar` to do X" |
83 | `test` | run tests / validation, report outcome | no | yes | bounded verification (no writes) | "verify the diff with the bounded test checks; report PASS/FAIL" |
84 | `advisor` | short-lived, high-reasoning counsel | no | yes | none | "what are we missing in this design?" |
85 | `custom` | explicit narrow tool allowlist | inherits | inherits | inherits | hand-picked tools on the parent's posture |
86
87 A role's default is what the role *intends*, and the parent's effective
88 posture is always the ceiling (a child never widens beyond its parent).
89 Read-only roles withhold **workspace writes** by intent; nothing else is
90 taken away by default — every role keeps network reads, and `custom`
91 inherits the parent's write/network/shell posture and is narrowed only by
92 its explicit tool list or the spawning call. The focused worker's header
93 states the effective posture (`scout · read-only · network · read-only
94 shell`) from the runtime's own permission snapshot.
95
96 **Delegation moves work, never authority.** A read-only parent may delegate
97 to `implement`, but the child's effective write, network, shell, and tool
98 permissions remain within the parent's live posture. Inspection roles can use
99 the classified read-only shell surface and, where native enforcement is
100 available, the explicit read-only analysis mode described below. A different
101 role name or `read_only` flag cannot grant a shell tool the caller lacks.
102 The clamp (`ChildAuthority::clamp` in `fleet/exact.rs`) intersects every field
103 with the narrower side. Deny lists are unioned, so
104 `inherit_disallowed_tools: false` cannot drop any operator or ancestor denial.
105 Resuming a saved worker intersects its saved posture with the current caller's
106 posture again. This containment is pinned by
107 `a_read_only_parents_delegation_never_widens_authority` in
108 `crates/tui/src/fleet/exact.rs` tests.
109
110 Inside the process, the resolved authority is one object —
111 `ChildGrant` in `crates/tui/src/worker_profile.rs`: `files`
112 (none/read/write), `shell` (none/inspect/verify/full), `network`, `desktop`
113 (never granted to a child), the named tool `surface`, the caller's explicit
114 `scope`, and remaining `spawn` depth. A role is a preset over that object
115 (`ChildGrant::for_role`); `ChildGrant::resolve` intersects it with the
116 parent-derived profile. The child's tool catalog, its dispatch refusals, and
117 its capability envelope all read the same fields — a tool that is visible is
118 callable, and a tool that is denied never appears.
119
120 The session's **permission posture** applies inside every child exactly as
121 it applies to the parent turn: under Auto-Review the same deterministic
122 floor and one-shot model guardian decide a worker's held calls (never a
123 prompt; an unavailable guardian denies, fail closed); under Ask a held call
124 the role cannot delegate is raised as an approval prompt in the parent's
125 UI and the worker waits visibly (`waiting for user`), or is denied with the
126 reason on hosts that cannot prompt; Full Access still fails closed on the
127 non-bypassable safety floor. Each decision nobody was prompted for is a
128 one-line note in that worker's transcript (visible when it is focused) and
129 an audit-log record. See `docs/MODES.md`.
130
131 Each role's full system prompt lives in
132 `crates/tui/src/tools/subagent/mod.rs` (search for
133 `*_AGENT_INTRO`). The prompt prefix loads automatically when the
134 child agent boots; the parent's assignment prompt becomes the first
135 turn's user message.
136
137 ## Context forking
138
139 `agent` starts fresh by default: the child gets its role prompt plus the
140 task you pass. Use `fork_context: true` when the child should continue from
141 the parent's current request prefix instead. (`fork_context` is not in the
142 advertised schema — it stays parse-accepted for compat callers, and
143 auto-forking for read-only roles continues unchanged.) In fork mode the runtime keeps the
144 parent prefill/prompt prefix byte-identical where available, appends a
145 structured state snapshot, then adds the sub-agent role instructions and task
146 at the tail. That preserves DeepSeek prefix-cache reuse while giving the child
147 the context needed for continuation, review, summarization, or compaction work.
148
149 Use fresh sessions for independent exploration. Use forked sessions when the
150 task depends on decisions, files, todos, or plan state already in the parent
151 transcript.
152
153 Forked state shows the parent's To-do snapshot — the sole Work surface, written
154 by `todo_write`. The child's `<codewhale:fork_state>` block carries the bounded
155 body rendered by `crates/tui/src/todo_snapshot.rs`, so a fork continues from the
156 parent's real progress position rather than a paraphrase. That To-do section is
157 resolved when the spawn happens, so a `todo_write` earlier in the same parent
158 turn is included.
159
160 **The list is shown once, at that spawn, and never re-sent.** No sub-agent
161 request re-states a To-do list, and neither does a parent request. Each agent
162 keeps its own private list (#4810); what it knows about that list comes from the
163 tool results its own `todo_write` calls returned, which are ordinary messages in
164 its own transcript. A worker therefore cannot read or write a parent's or a
165 sibling's list, and a forked child cannot mutate the snapshot it was handed or
166 keep reading later parent changes.
167
168 That same private list is what the child's in-transcript card shows. A
169 delegate card renders a bounded projection of **its own** agent's To-do — the
170 settled/total count, the in-progress item always included, up to three rows, and an
171 explicit `… +N more` when the bound elides the rest — built by
172 `card_todo_projection` from the same snapshot, priority order, and sanitizer the
173 model-facing body uses. A card only ever consumes an envelope whose `agent_id`
174 matches it, so a parent's list never appears under a child and no sibling's list
175 appears under another. An agent that has stated no work shows no To-do rows at
176 all rather than a placeholder task, and a terminal card keeps the last snapshot
177 its agent actually published. Fanout cards stay a dot grid and do not show child
178 To-do: with many workers behind one card there is no truthful place to hang a
179 single list. A child To-do appears only when the runtime already represents
180 that child as its own delegate card.
181
182 The durable Runtime ledger (projected through fleet task status) still owns
183 lifecycle state. `update_plan` is no
184 longer reachable by a model: `model_visible()` returns `false`
185 (`crates/tui/src/tools/plan.rs:408-413`), so it is filtered out of the API tool
186 list and never appears to a child. It survives only to replay older transcripts.
187 Strategy that used to go there now goes in the response body, and lifecycle
188 state goes in `todo_write`.
189
190 ## Worktree isolation
191
192 For parallel edit lanes, launch the child with `worktree: true`. Codewhale
193 creates a fresh git worktree and branch for that child, runs the child from the
194 isolated checkout, and reports the resulting workspace/branch in the returned
195 session projection and worker record. By default the branch is
196 `codex/agent-<name>-<id>` and the checkout lives beside the parent repo under
197 `.codewhale-worktrees/`, so the parent checkout stays clean.
198
199 Isolation is not write authority. A prompt-only start with no role/profile or
200 write declaration remains read-only, and read-only roles need no write scope.
201 Explicitly selected write-capable roles such as `general` and `implement`
202 inherit the parent's write ceiling and default to the workspace
203 (`write_roots: ["."]`) unless narrowed. Prefer explicit, disjoint `exact_files`
204 or `write_roots` for parallel work; `coordination_contracts` can reserve named
205 shared contracts. If only `deliverables` supplies a writer's scope, those files
206 become the exact-file scope.
207
208 `write_authority` is optional typed narrowing: `read_only` admits no write
209 scope, `workspace_write` uses the shared checkout, and `worktree_write`
210 requires actual worktree isolation. Incompatible role/scope declarations fail
211 before admission. Active overlapping shared claims fail before mutation; a
212 real isolated worktree may proceed in parallel. A `custom` role requires
213 explicit write-capable authority to claim writes; otherwise it starts
214 read-only.
215
216 Optional fields:
217
218 - `worktree_branch`: exact branch to create.
219 - `worktree_base`: git ref to branch from; defaults to `HEAD`.
220 - `worktree_path`: exact checkout path. Relative paths stay under the default
221 sibling `.codewhale-worktrees/` root.
222
223 `cwd` may be combined with `worktree`: the requested directory becomes the
224 discovery anchor the repo root (and the new checkout) is resolved from
225 (`prepare_child_workspace`). Without `worktree`, `cwd` remains the manual
226 escape hatch for an already-created directory inside the parent workspace.
227
228 ### File deliverables and edit claims
229
230 Put required files in `deliverables`; keep the human outcome in
231 `expected_artifact`. For example, call `agent` with:
232
233 ```json
234 {
235 "action": "start",
236 "type": "implement",
237 "prompt": "Summarize the local routing evidence in reports/routing.md.",
238 "exact_files": ["reports/routing.md"],
239 "deliverables": ["reports/routing.md"],
240 "expected_artifact": "A concise report with source references and open gaps"
241 }
242 ```
243
244 At most 16 repo-relative file paths are accepted. Absolute paths, traversal,
245 repository metadata paths, and symlink traversal are refused. Completion checks
246 each file against the admitted scope and reports its path, status, and byte
247 count where available. The terminal statuses are `present`, `missing`, `empty`,
248 `not_file`, `out_of_scope`, `invalid_path`, and `unreadable`.
249 `present` means a nonempty regular file exists; it does not prove the report is
250 correct or that tests passed.
251
252 A missing or invalid required file sets `verification.status` to
253 `deliverable_missing` with the individual verdicts. Successful file checks can
254 produce `deliverables_present`; they do not turn a child self-report into an
255 independent quality gate. The completion notice includes the actual verdicts,
256 including when a worker fails or exhausts a budget.
257
258 Edit claims are checked separately against the spawn-time git HEAD and dirty
259 file contents. Explicit changed-file declarations can produce
260 `claim_mismatch` when a claimed file did not change, or when a successful
261 bounded write receipt changed a file the child did not declare. A peer's
262 change inside a worker's broad scope is not enough to attribute that write to
263 the worker. `path:LINE` and `path:LINE-LINE` evidence citations, including
264 sentence punctuation and Markdown links, never count as edit claims.
265
266 ### Reading beside a writer
267
268 Read-only tools and classifier-approved shell reads can run while a peer owns
269 a shared write claim. For arbitrary analysis code, call `bash` with explicit
270 `read_only: true`:
271
272 ```json
273 {
274 "action": "run",
275 "read_only": true,
276 "command": "python3 -c \"import sqlite3; db = sqlite3.connect('file:cache/index.db?mode=ro', uri=True); print(db.execute('SELECT name FROM sqlite_schema').fetchall())\""
277 }
278 ```
279
280 This mode requires native filesystem read-only isolation and denies network
281 access. It accepts only foreground `run` with `command`, optional `cwd`, and
282 `timeout_ms`. Background or interactive modes, stdin, sandbox escalation, and
283 external execution backends are incompatible. If native enforcement is absent
284 or cannot be prepared, the call refuses before executing the command; the flag
285 never falls back to trusting a promise that the code only reads. Existing role,
286 tool, and ancestor policy restrictions still apply.
287
288 For a write refusal outside your own scope, `agent(action="claim", ...)` can
289 add permitted paths to your claim. It cannot take a live peer's claim. Wait for
290 that peer, choose disjoint bounded writes, or use a separate worktree for code
291 that needs writes. `action="release"` only clears claims whose owners are no
292 longer live; it is not a way to unlock another running worker's files.
293
294 ## Delegation briefs
295
296 The parent should pass a compact brief instead of a loose paragraph. Use the
297 structured `dependencies` and `acceptance` arrays for bounded prerequisite facts
298 and observable checks; keep the focused objective in `prompt`. Do not copy raw
299 parent reasoning or an unbounded transcript.
300
301 Default shape for the brief — a plain sentence beats the template when the
302 delegation is trivial:
303
304 ```
305 QUESTION:
306 SCOPE:
307 ALREADY_KNOWN:
308 EFFORT: quick | medium | thorough
309 STOP_CONDITION:
310 OUTPUT: VERDICT, EVIDENCE, GAPS, NEXT
311 ```
312
313 `scout` briefs default to quick, read-only investigation (no writes, but
314 network reach and the bounded verification surface are available for real
315 scouting). A quick scout usually needs only a handful of calls: orient,
316 search, read the decisive lines, and return — but stop at decisive evidence,
317 not at a number. There is no per-agent call cap to save; the runtime budgets
318 depth and concurrency, not curiosity. Do not repeat `ALREADY_KNOWN` work
319 unless evidence contradicts it. Builder and repair-style briefs should use
320 checkpoints before scope expansion or after repeated failures.
321
322 Good delegation prompt examples:
323
324 ```text
325 QUESTION: Does PR #3124 introduce release-risk behavior around provider routing?
326 SCOPE: PR #3124 diff, linked issue, provider routing tests, docs/PROVIDERS.md.
327 ALREADY_KNOWN: Branch is hunter/0.8.62-glm-subagents; workspace version stays 0.8.61.
328 EFFORT: medium
329 STOP_CONDITION: Return once you have either one BLOCKER/MAJOR issue or enough evidence for no MAJOR+ issues.
330 OUTPUT: VERDICT, EVIDENCE with file:line refs or PR refs, GAPS, NEXT.
331 ```
332
333 ```text
334 QUESTION: Where is the child-agent prompt assembled?
335 SCOPE: crates/tui/src/prompts*, crates/tui/src/tools/subagent/*.
336 ALREADY_KNOWN: The model-facing launcher is only `agent`; do not look for removed lifecycle tools.
337 EFFORT: quick
338 STOP_CONDITION: Stop after identifying the prompt source files and the function that wraps assignment text.
339 OUTPUT: VERDICT, EVIDENCE, GAPS, NEXT.
340 ```
341
342 ```text
343 QUESTION: Is the focused prompt/subagent test filter valid, and what fails if not?
344 SCOPE: cargo test -p codewhale-tui --bin codewhale-tui --locked prompt; subagent filter if needed.
345 ALREADY_KNOWN: Do not fix failures; capture exact command, exit code, and first relevant assertion.
346 EFFORT: medium
347 STOP_CONDITION: Stop after one clean PASS or one reproducible failing assertion with command evidence.
348 OUTPUT: VERDICT, EVIDENCE, GAPS, NEXT.
349 ```
350
351 ### When to pick which role
352
353 - **`general`** — when the task is "do this whole thing", not "go
354 look", "design", or "verify". This is the right default; reach for
355 a more specific role only when the posture matters.
356 - **`explore`** — when the parent needs evidence before deciding what
357 to do next. Scouts are cheap and fast; open 2–3 in parallel
358 for independent regions.
359 They should orient first: confirm the project root, read relevant
360 `AGENTS.md`/`README.md` guidance in unfamiliar trees, search only the
361 likely scope, and return `path:line-range` evidence instead of a narrative
362 tour. The role name to use is `explore`.
363 - **`planner`** — when the parent has an objective but no executable
364 decomposition. Planners write artifacts (`todo_write` items,
365 strategy in the response body) but don't carry them out.
366 - **`reviewer`** — when there's already a change and the parent wants
367 it graded. Reviewers run under read-only posture, so the runtime
368 refuses patch attempts — describe the fix in the finding and the
369 parent dispatches a builder when the verdict is "fix it".
370 - **`implement`** — when the change is already specified and just
371 needs to land. Builders stay tightly scoped: minimum edit, no
372 drive-by refactoring, run a quick verification before handing back.
373 - **`test`** — when the parent needs an authoritative pass/fail
374 on the test suite or other validation. The verifier posture never
375 writes — the runtime refuses fix attempts — so capture the failing
376 assertion + stack and put fix candidates under RISKS for the parent
377 to dispatch. Shell is clamped to the bounded built-in verification
378 surface: Run tests/verifiers (pass `cwd` when the checks live in a
379 subdirectory), Git fetch for remote refs, Git merge_tree for merge
380 results. The write ceiling is read-only and unbounded shell forms
381 are refused (#5186). A refused probe is reported to the parent,
382 never worked around (#6298).
383 - **`advisor`** — when the operator wants a high-leverage second opinion
384 before cheaper execution continues. Consultants read enough to ground a
385 recommendation; their grant carries no writes and no shell, so the
386 runtime refuses both. `oracle` and
387 `consultant` remain accepted only when loading older requests or persisted
388 records; new prompts, receipts, and UI use `advisor`.
389 - **`custom`** — only when the parent needs to constrain the tool
390 set explicitly. Pass the allowlist via the `allowed_tools` field
391 on legacy/internal sub-agent records; the model-facing `agent` tool keeps the
392 public schema intentionally small.
393
394 ### Aliases
395
396 The model can spell each role multiple ways:
397
398 | Canonical | Aliases |
399 |---------------|------------------------------------------------------------------|
400 | `general` | `worker`, `default`, `general-purpose`, `general_purpose` |
401 | `explore` | `scout`, `explorer`, `exploration` |
402 | `planner` | `plan`, `planning`, `awaiter` |
403 | `reviewer` | `review`, `code-review`, `code_review` |
404 | `implement` | `builder`, `implementer`, `implementation` |
405 | `test` | `verifier`, `verify`, `verification`, `validator`, `tester` |
406 | `advisor` | `consultant`, `oracle` (compatibility input only) |
407 | `custom` | (none; explicit `allowed_tools` array required) |
408
409 All matching is case-insensitive. Unknown values produce a typed
410 error listing the accepted set, so the model can self-correct on
411 the next turn.
412
413 ## Concurrency cap
414
415 Up to **64** sub-agents run concurrently by default (`DEFAULT_MAX_SUBAGENTS`),
416 configurable via `[subagents].max_concurrent` in `~/.codewhale/config.toml` up to
417 the hard ceiling of **128** (`MAX_SUBAGENTS`). The session admits a bounded
418 queue of up to **1024** running plus queued sub-agents by default
419 (`MAX_SUBAGENT_ADMISSION`, `crates/tui/src/config/subagent_limits.rs:21`), so a turn can
420 request broad fan-out and let the manager drain it without creating an
421 unbounded population.
422
423 By default every admitted child may start immediately — there is no artificial
424 throttle. Request the fan-out the work actually needs and let the runtime
425 queue and drain it; the caps above are enforcement, not a reason to
426 pre-refuse valid work. If you want gentler fan-out, lower `[subagents].launch_concurrency`
427 (how many direct children start at once); children beyond that limit **queue**
428 for a launch slot rather than bursting. `launch_concurrency` defaults to the
429 resolved `max_subagents` cap. (The pre-v0.8.61 `interactive_max_launch` key is
430 still accepted as a deprecated alias; the new key wins when both are set.)
431
432 High-fanout Workflows can tune that bounded population with `[subagents]
433 max_admitted` (aliases: `max_total`, `admission_limit`). That total ceiling
434 counts both **running** and **queued** agents, while `launch_concurrency` keeps
435 instantaneous execution bounded. Completed / failed / cancelled records persist
436 for inspection but don't occupy an admission slot. Agents that lost their
437 `task_handle` (e.g. across a process restart) also don't count against the cap.
438
439 Provider profiles let one config stay aggressive for direct API routes while
440 keeping subscription or aggregator routes gentle. Every key under
441 `[subagents.providers.<provider>]` inherits from `[subagents]` when omitted.
442 Provider keys accept canonical names such as `deepseek`, `zai`, `openrouter`,
443 and aliases such as `glm` for Z.ai:
444
445 ```toml
446 [subagents]
447 # Global fallback for providers without a profile.
448 max_concurrent = 20
449 launch_concurrency = 20
450 max_admitted = 200
451 # Operator-selected Runtime delegation depth. The default is 3; this explicit
452 # value opts in above the default but remains below the hard ceiling of 8.
453 max_depth = 6
454 # Omitted or zero model-step budget is unbounded. Set a positive value only
455 # when an operator deliberately wants a per-child cap.
456 default_max_steps = 0
457 default_wall_time_secs = 1800
458
459 [subagents.providers.deepseek]
460 # Direct API key with room to fan out.
461 max_concurrent = 20
462 launch_concurrency = 20
463 max_admitted = 200
464
465 [subagents.providers.glm]
466 # Z.ai / GLM subscription-style route: keep pressure tight.
467 max_concurrent = 4
468 launch_concurrency = 3
469 max_admitted = 12
470 max_depth = 2
471 api_timeout_secs = 180
472 heartbeat_timeout_secs = 240
473
474 [subagents.providers.openrouter]
475 max_concurrent = 5
476 launch_concurrency = 3
477 max_admitted = 20
478
479 [subagents.providers.anthropic]
480 max_concurrent = 3
481 launch_concurrency = 2
482 max_admitted = 12
483 ```
484
485 Use `/config subagents status` to see both the global values and the active
486 provider's resolved fanout, depth, and timeout profile.
487
488 ## Advertised agent-tool fields
489
490 The model-facing `agent` schema exposes these controls:
491
492 | Purpose | Fields |
493 | --- | --- |
494 | Launch and route | `action`, `prompt`, `type`, `profile`, `name`, `model`, `model_strength`, `thinking` |
495 | Scope and outputs | `worktree`, `cwd`, `write_authority`, `write_roots`, `exact_files`, `coordination_contracts`, `deliverables`, `expected_artifact` |
496 | Narrow run limits | `max_steps`, `wall_time_secs` |
497 | Coordinate and recover | `agent_id`, `agent_ids`, `all_parked`, `message`, `until`, `detached`, `resume_from` |
498 | Inspect | `detail`, `offset`, `limit` |
499
500 `start` requires `prompt`. `message` requires a target and message;
501 `followup` requires a message and exactly one target form: `agent_id`/`name`,
502 `agent_ids`, or `all_parked: true`. `peek`, `interrupt`, and `cancel` require a
503 target. `claim` requires scope entries. These action requirements are validated
504 before execution.
505
506 `agent(action="roster")` reports each built-in role's resolved provider, model,
507 reasoning effort, known route limits and capability provenance. It uses the
508 same resolver as execution. An explicit saved profile wins first, followed by
509 a manual role pin in the current configuration, then a unique saved member
510 pinning that semantic role. Conflicting task `model` or `model_strength` choices
511 fail before admission. For an unpinned role, per-task `model` precedes
512 `model_strength`, then inherited role defaults and the session route.
513 When a Pod is selected, the `models` rows list its exact routes in saved order.
514 Use a listed `provider/model` selector for a task on an unpinned role; the session
515 model remains allowed. Off-list choices fail with the allowed routes, and a bare
516 model shared by multiple providers requires an exact selector. Without selected
517 models, current-provider overrides and `model_strength` retain their behavior;
518 foreign-provider requests fail. These choices do not change child authority.
519
520 The `profiles` rows expose saved members from the existing selected Fleet or
521 trusted config/personal/workspace/plugin layers, with bounded identities and the
522 same route/cost evidence. `profile="bug-hunter"` loads that member's instructions,
523 role, provider/model pin and depth limit. Conflicting type or model requests are
524 refused; explicit `thinking` overrides the saved tier. Missing providers, revoked
525 plugin authority and disabled project profiles fail before child admission.
526 Discovery never creates a profile or enrolls a model. These identity choices use
527 the existing child lifecycle; a saved profile alone does not create a continuing
528 Bot conversation or a computer lease.
529
530 Cost classes describe current uncached text input/output rates, not the total
531 price of a future task. Missing or routing-dependent prices remain unknown;
532 subscription/local routes are labelled not money metered. Discovery makes no
533 provider request and reports reachability as unverified.
534
535 **Parse-accepted but unadvertised (compat).** Other inputs remain accepted
536 for saved transcripts, ACP/MCP clients, fleet execution data, and
537 internal/operator compatibility. Runtime validates and intersects them with
538 live policy:
539
540 - delegation compatibility: `max_depth`, `maxDepth`, or `max_spawn_depth`;
541 values are restricted to 0 through the Runtime hard ceiling of 8 and only
542 narrow the inherited absolute ceiling. Model-facing calls inherit depth
543 from the operator and selected profile.
544 - workspace/isolation: `workspace_policy`, `fork_context`,
545 `worktree_path`, `worktree_branch`, `worktree_base`
546 - spawn contract: `deliberate`, `dependencies`, `acceptance`, `allowed_tools`
547 - lifecycle extras: `timeout_secs` (wait), `reason` (interrupt),
548 `include_archived` (status)
549
550 Compatibility input is not a way to widen inherited authority or remove a
551 finite budget.
552
553 ## Child budgets (steps, wall time, tokens)
554
555 `max_steps` and `wall_time_secs` are optional per-call limits.
556 Each can only narrow the applicable role, operator, parent, and saved-run
557 limits. Omission inherits those limits; explicit zero, null, negative, or
558 out-of-range values are rejected by the tool parser.
559
560 `max_steps` counts model turns and accepts 1 through 2000. All roles default
561 to no model-turn cap unless an operator or ancestor supplies one; the internal
562 zero representation for that default never cancels a finite inherited cap.
563 `wall_time_secs` accepts 1 through 86400, with an operator-configurable
564 1800-second default. It includes admission queue time, model requests, and
565 tools. The effective absolute deadline is persisted.
566
567 For example, a focused review can request:
568
569 ```json
570 {
571 "action": "start",
572 "type": "reviewer",
573 "prompt": "Review the parser diff and report concrete regressions.",
574 "max_steps": 12,
575 "wall_time_secs": 300
576 }
577 ```
578
579 The receipt's `effective_limits` is authoritative; a request for 300 seconds
580 cannot extend a parent's earlier deadline. A continuation keeps the source's
581 remaining steps, original deadline, and token history. A new ID, role, or
582 `resume_from` fork cannot reset those bounds.
583
584 ### Token accounting and partial results
585
586 Token budgets were retired in 0.9.14: token usage is tracked, never
587 enforced — runs are no longer stopped by token accounting. Legacy input that
588 still carries `token_budget` parses and is ignored; `max_steps` and
589 `wall_time_secs` remain the narrowable per-call limits.
590
591 The governor uses provider-reported input plus output tokens, not a local
592 estimate presented as a bill. Request output is capped to the remaining
593 allowance. Unknown prompt usage and requests already in flight can overshoot;
594 receipts retain the full reported usage. Missing usage remains unknown.
595 Worker records distinguish the worker's own token totals from shared
596 `budget_spent_tokens` and `budget_remaining_tokens`; do not sum a shared
597 pool once for every descendant.
598
599 The worker reserves room for one final report inside these limits: up to 10%
600 of a token allowance (at most 8192 tokens, only when at least 1024 can be
601 reserved), one turn when the step cap permits at least two, and up to 10% of
602 wall time (at most 10 seconds). Ordinary task execution stops before using
603 that reserve. Shared scopes hold back one token reserve for the scope;
604 reporting workers atomically claim remaining headroom so siblings cannot
605 independently reuse it. Continuation never refunds measured usage or resets
606 the original deadline.
607
608 The final reporting turn uses the worker's existing resolved provider and
609 model, with tools disabled and at most 1024 output tokens. It consolidates
610 bounded assistant notes and tool results into findings, evidence, produced
611 files, unfinished work and next steps. Estimated input cost counts against
612 its allowance. Provider transport retries remain inside the one logical
613 turn and its original wall-time deadline; no worker summary retry loop is
614 added. Token estimates are not billing receipts: unknown provider input and
615 requests already in flight can still overshoot, and actual usage is recorded.
616
617 The outcome stays `BudgetExhausted`, even when a useful report is obtained,
618 with the specific cause, checkpoint, measured usage and normal deliverable
619 verdicts. If the allowance is too small or already spent, earlier bounded
620 usage is unknown, the provider fails, or time expires, the worker returns
621 recorded partial text and says why a model report was unavailable.
622 Known missing response usage and attempts interrupted by timeout or cancellation
623 stay recorded across continuations and shared siblings; later known usage remains a
624 subtotal and cannot restore reporting headroom in that bounded scope.
625 Cancellation wins over reporting. Missing usage stays unknown. Exhausted
626 scopes reject further spawns or continuations; a partial report is not
627 successful completion.
628
629 ## Per-role models (#3018)
630
631 Children can run on a different model than the parent. Structured role pins,
632 the legacy model map, and convenience keys feed one override map. Structured
633 `[subagents.roles.<role>]` entries win over `[subagents.models]`, which wins over
634 the convenience keys. Keys are case-insensitive; within the structured table,
635 a canonical role key wins over its legacy alias:
636
637 ```toml
638 [subagents]
639 default_model = "deepseek-v4-flash" # fallback for every role
640 worker_model = "deepseek-v4-pro" # worker
641 scout_model = "deepseek-v4-flash" # scout
642 planner_model = "deepseek-v4-flash" # planner
643 reviewer_model = "deepseek-v4-pro" # reviewer
644 custom_model = "deepseek-v4-pro" # custom
645
646 [subagents.models]
647 # Free-form role → model map; any role alias accepted by agent works.
648 builder = "deepseek-v4-pro"
649
650 [subagents.roles.reviewer]
651 model = "deepseek/deepseek-v4-pro"
652 ```
653
654 These are manual pins for direct and Workflow `agent` starts. A task may restate
655 the same model or exact provider/model pair, but cannot change the pin with
656 `model` or `model_strength`. An explicit saved profile takes precedence over a
657 manual role pin. A type-only start also selects a unique saved role pin when
658 there is no manual override; ambiguous saved roles fail instead of choosing one.
659 Durable Fleet runs retain their selected member's frozen route.
660
661 Structured role pins accept `provider/model`, preserving the configured provider's
662 exact identity and the complete model suffix. Unknown providers, empty pairs,
663 and cross-provider `auto` choices fail before admission. A bare structured model
664 inherits the session provider. For a namespaced model, qualify it explicitly,
665 for example `openrouter/deepseek/deepseek-v4-pro`. Legacy scalar and
666 `[subagents.models]` values keep their full provider-owned id, including slashes;
667 they do not change providers.
668
669 The v0.9.x convenience keys `explorer_model`, `awaiter_model`, and
670 `review_model` remain accepted as deprecated aliases so existing config files
671 do not break.
672
673 Model ids may be **any model the active provider accepts** — validation is
674 provider-aware and happens at spawn time, not load time. On the official
675 DeepSeek API only DeepSeek ids are accepted; every other provider passes the
676 id through to the provider API, which is the authority. A non-DeepSeek
677 example:
678
679 ```toml
680 provider = "moonshot"
681 model = "kimi-k2.7-code"
682
683 [subagents]
684 worker_model = "kimi-k2.6"
685 ```
686
687 Model ids are validated the same way when applied to a child route; an invalid
688 id on the official DeepSeek API fails the spawn with the accepted-id list
689 instead of an opaque provider 400.
690
691 With `/model auto`, sub-agent routing is provider-aware too: providers with a
692 known big/cheap pair (DeepSeek, and the hosted DeepSeek routes on NVIDIA NIM,
693 OpenRouter, Novita, SiliconFlow, SGLang, vLLM) route between that pair;
694 providers without a known cheap tier (e.g. Ollama, Moonshot) skip the
695 network router and keep children on the session model.
696
697 ## Per-profile provider routes (#3965)
698
699 `[subagents.models]` changes the child model within the active provider. A slash
700 in that legacy input does not grant another provider. To pin a different provider,
701 use a structured `[subagents.roles.<role>]` declaration as above, or use a
702 fleet/AgentProfile and select it with `profile` or its unique saved role.
703 The profile's explicit `provider` +
704 `model` fields win over the parent session route; omitting `provider` preserves
705 the existing inherit behavior.
706
707 Example: keep the parent session on DeepSeek, but run a formatter child on a
708 local LM Studio OpenAI-compatible endpoint:
709
710 ```toml
711 # ~/.codewhale/config.toml or workspace config
712 provider = "deepseek"
713
714 [providers.deepseek]
715 api_key = "YOUR_DEEPSEEK_KEY"
716
717 [providers.lm-studio]
718 kind = "openai-compatible"
719 base_url = "http://127.0.0.1:1234/v1"
720 api_key = "lm-studio"
721 model = "qwen-2.5-7b"
722 ```
723
724 ```toml
725 # .codewhale/agents/local-formatter.toml
726 id = "local-formatter"
727 role_hint = "formatter"
728 provider = "lm-studio"
729 model = "qwen-2.5-7b"
730 reasoning_effort = "off"
731
732 [instructions]
733 text = "Use small, local edits. Keep formatting changes mechanical."
734 ```
735
736 Then call `agent(profile: "local-formatter", prompt: "...")`. In-process
737 children build a client for `lm-studio`; fleet workers forward
738 `--provider lm-studio` to `codewhale exec`, which resolves the same
739 `[providers.lm-studio]` table. Unknown or unconfigured provider ids fail the
740 spawn rather than silently falling back to the parent provider.
741
742 ## Per-step API timeout (#1806, #1808)
743
744 Each sub-agent step wraps its DeepSeek `create_message` call in a
745 per-step timeout so a single stuck request can't pin the parent's
746 completion wakeup channel indefinitely. The default is `600` seconds.
747 A timed-out attempt is retried with exponential backoff (up to 5
748 retries) before the step interrupts with a preserved checkpoint.
749 Long-thinking children that legitimately exceed that, for example
750 heavy plan or review work behind `agent`, can extend the timeout in
751 `~/.codewhale/config.toml`:
752
753 ```toml
754 [subagents]
755 api_timeout_secs = 900 # 15 minutes; clamped to 1..=3600
756 ```
757
758 Values are clamped to `1..=3600`. `0` and `unset` keep the `600`
759 second default.
760
761 ## Stale-agent heartbeat (#2614)
762
763 Running agents also track manager-visible progress. If a child stops emitting
764 progress for the heartbeat window, the manager auto-cancels it, releases its
765 sub-agent slot, and keeps the cancelled record inspectable through the returned
766 transcript handle and persisted worker record. The default is 5 minutes
767 (resolved to at least 30 seconds above `api_timeout_secs`, so 630 seconds
768 with the 600-second default API timeout):
769
770 ```toml
771 [subagents]
772 heartbeat_timeout_secs = 300 # clamped to 30..=3600
773 ```
774
775 The effective heartbeat is kept at least 30 seconds above
776 `api_timeout_secs`, so a configured long model request is not cancelled before
777 its own request timeout can fire.
778
779 ## Lifecycle
780
781 Each opened session produces a record that progresses through:
782
783 ```
784 Pending → Running → (Completed | Failed(reason) | Cancelled | Interrupted(reason) | BudgetExhausted)
785 ```
786
787 An explicit interrupt, exhausted provider retries, or recovery of an orphaned
788 running record can leave an `Interrupted` worker with a checkpoint. Inspect
789 `needs_continuation` and the recorded reason; use `followup` for continuable
790 work. `BudgetExhausted` includes the specific token, step, or wall-time cause;
791 continuation cannot replenish an exhausted allowance.
792
793 `wait` observes workers. A timeout returns current outcomes and never parks,
794 cancels, or resumes them. `until: "completion"` returns when one child settles;
795 `until: "all"` joins the workers running when that call starts;
796 `until: "activity"` can return on progress. A later spawn is not silently added to an
797 earlier join.
798
799 An ordinary parent response leaves healthy children running. The same Engine
800 turn loop consumes their completion notices and can continue the parent.
801 Headless `codewhale exec` defers a successful final receipt until its existing
802 Engine reports no live children and no queued child completions. Its original
803 wall-clock deadline still bounds that settlement, including autonomous parent
804 turns. Cancellation, deadline exhaustion, a fatal event, or a lost Engine
805 channel stops settlement and returns the appropriate interrupted or failed
806 receipt with recorded partial usage. It does not report successful child
807 completion merely because the parent's first response ended.
808
809 ### Session boundaries (#405)
810
811 Each `SubAgentManager` instance assigns itself a fresh `session_boot_id` on
812 construction. Every new session stamps the agent with that id; the workspace
813 state file records it for restart recovery.
814
815 Work-bar/status projections focus on current-session agents by default.
816 Prior-session agents that are not still running are treated as archived records
817 so the model does not mistake stale work for live work. This is a
818 *prior-session* rule only: agents that finished in the CURRENT session keep
819 their work-bar rows for the rest of the session (quiet completion), and their
820 details still open from those rows.
821
822 Records that loaded from a pre-#405 persisted state file (no
823 `session_boot_id` field) classify as prior-session because the
824 manager can't match them to the current boot.
825
826 ## Run receipts, follow-up, and takeover
827
828 Each compatibility sub-agent has a persisted worker record in
829 `.codewhale/state/subagents.v1.json`. The record is the current run-ledger
830 slice for sub-agent lanes until those lanes are backed directly by the fleet
831 ledger: it stores `run_id`, objective, role/model,
832 workspace/branch, lifecycle events, artifact refs, follow-up target, takeover
833 target, usage provenance, and verification provenance.
834
835 The normal parent flow is to keep working and consume the completion event.
836 Default start and status receipts are compact; full snapshots and worker
837 records are diagnostic detail, not repeated in every response.
838
839 ### Continue an existing worker
840
841 `message` queues a note without waking the child. `followup` wakes a running
842 child or resumes a continuable checkpoint:
843
844 ```json
845 {"action":"followup","agent_id":"child-previous-id","message":"Continue the assignment using the recorded evidence."}
846 ```
847
848 Use the returned `agent_id` for subsequent waits and messages. The receipt's
849 `from` and `to` identify the original target and its current continuation.
850 The original receipt is retained. Retrying through an old ID follows the
851 persisted continuation chain and does not create a duplicate worker. If the
852 current successor is running, the follow-up is delivered there; if it has
853 already settled and cannot continue, the response says no message was
854 delivered. Duplicate workers are prevented, but repeated messages to a running
855 worker are still repeated messages.
856
857 For a batch, choose exactly one target form:
858
859 ```json
860 {"action":"followup","agent_ids":["child-a","child-b"],"message":"Continue the remaining checks."}
861 ```
862
863 ```json
864 {"action":"followup","all_parked":true,"message":"Continue the parked assignments."}
865 ```
866
867 Explicit batches accept up to 32 distinct IDs. `all_parked` selects parked
868 children you control and refuses more than 32 so you can choose explicit
869 batches. Bulk responses return separate `results` and `errors`; a failing
870 target does not roll back a successful continuation. Parent/descendant control
871 checks apply to both the addressed record and its current successor.
872
873 Use `start` with `resume_from` only to create a separate worker from a settled
874 child's transcript, for example to assign a new review. Each such start is a
875 new worker. Missing, running, or cross-workspace sources are refused; the
876 source's authority and budget bounds still apply. This is distinct from
877 continuing parked work with `followup`.
878
879 ### Compact status and full transcript retrieval
880
881 Unscoped `agent(action="status")` returns a session-scoped page bounded to
882 8 KiB. `offset` and `limit` page the roster; the default and maximum limit is
883 20. Follow `next_offset`, since the byte bound can return fewer rows than
884 requested. The model-facing roster wire uses one stable `columns` header and
885 an array of values per entry in `agents`; pair each row with the header instead
886 of reading it as an object. `null` means absent or unreported, and a measured
887 zero stays numeric `0`. The header is present even on an empty page.
888 Rows include worker and parent IDs, current depth, state,
889 elapsed time, own token total, recent activity, pending input, and continuation
890 lineage (`resumed_from` / `resumed_as`). Verification includes the verdict,
891 nonempty deliverable counts and a short warning when needed. Names, steps,
892 routes, effective limits (including maximum depth), and token breakdowns remain
893 available in the unchanged object projection when addressing one `agent_id`.
894 Aggregate usage counts each worker's own reported tokens once and reports its
895 coverage. Completion receipts additionally report measured descendant usage,
896 deduplicate continuation lineage, and distinguish unknown usage from zero. A worker's
897 `has_unreported_usage` and the descendant/subtree `unreported_usage_workers`
898 counts identify missing responses even when later responses provide a measured subtotal.
899
900 Request one worker's detail when investigating a failure:
901
902 ```json
903 {"action":"status","agent_id":"child-a","detail":true,"offset":0,"limit":20}
904 ```
905
906 Addressed `peek` also accepts `detail: true`. Detail remains bounded to 32 KiB;
907 message/event archives and deliverable verdicts are paged, and omission fields
908 identify truncated detail. Use the returned typed `transcript_handle` with
909 `handle_read` for the complete retained transcript. The handle's lookup
910 coordinates are preserved even when diagnostic prose is omitted. Unscoped
911 `detail: true` does not expand the entire roster into transcripts.
912
913 Artifacts are symbolic refs. Treat `result_summary` as a child self-report and
914 inspect the specific `verification.status` and its evidence before relying on
915 it. `usage.status` remains `unknown` until provider usage is reported, then
916 becomes `reported` or `budget_exhausted` for a spent token scope. Neither a
917 file's `present` verdict nor a completed lifecycle state proves a test gate.
918
919 ## Output contract
920
921 Non-scout sub-agents end with five Markdown headings, in this order:
922
923 ```
924 ### SUMMARY one paragraph; what you did and what happened
925 ### EVIDENCE path:line-range citations and key findings; one bullet each
926 ### CHANGES files modified, with one-line descriptions; "None." if read-only
927 ### RISKS what could go wrong / what the parent should double-check
928 ### BLOCKERS what stopped you; "None." if you finished cleanly
929 ```
930
931 Use `### HEADING` lines, with `EVIDENCE` before `CHANGES`. List edited
932 repo-relative file paths under `### CHANGES`; blank lines before the bullets
933 are allowed. Begin each bullet with its file path, followed by a description;
934 quote paths containing spaces or literal trailing punctuation. The verifier
935 also accepts older explicit `CHANGES:`,
936 `Changed files:`, and `Files changed:` declarations. Evidence citations and
937 paths under `RISKS` are not declarations of edits. The five-heading prompt
938 contract is `SUBAGENT_OUTPUT_FORMAT` in
939 `crates/tui/src/prompts/text.rs`. `prompt_documents_structured_subagent_briefs`
940 in `crates/tui/src/prompts.rs` asserts every heading against it.
941
942 Scouts are the carve-out (#5189 F5): they end with `### SUMMARY` and
943 `### EVIDENCE` only (`SUBAGENT_SCOUT_OUTPUT_FORMAT` in
944 `crates/tui/src/prompts/text.rs`). `FleetRole::system_prompt` in
945 `crates/tui/src/tools/subagent/mod.rs` injects the scout contract for
946 `FleetRole::Scout` and the five-heading contract for every other role. A
947 subagent test pins that scouts contain `## Output contract (scout)` and do
948 not contain `### BLOCKERS`.
949
950 The parent reads `EVIDENCE` as a working set for the next turn, so
951 scouts and reviewers should be precise here.
952
953 ## Memory and the `remember` tool (#489)
954
955 Sub-agents share the parent's native memory store when memory is enabled
956 (`[memory] enabled = true` or `DEEPSEEK_MEMORY=on`). They can
957 append durable notes via the `remember` tool — handy for a
958 scout that discovers a project convention worth carrying across
959 sessions, or a verifier that learns "this test is flaky".
960
961 `remember` takes a `scope` of `global` or `workspace`
962 (`crates/tui/src/tools/remember.rs:79-108`) and writes through
963 `NativeMemoryStore` to `~/.codewhale/memory/global/MEMORY.md` or
964 `~/.codewhale/memory/workspace/<id>/MEMORY.md`. Writes do not go through the
965 standard write-approval flow. The legacy single-file `memory.md` path was
966 removed in v0.9.4 (remember.rs:165); see `docs/MEMORY.md` for the full layout.
967
968 ## Implementation notes
969
970 - Source: `crates/tui/src/tools/subagent/mod.rs`.
971 - Persisted state: `<workspace>/.codewhale/state/subagents.v1.json`. Schema
972 version `1` (forward-compatible — new optional fields use
973 `#[serde(default)]`).
974 - Settled records normally expire after `COMPLETED_AGENT_RETENTION`
975 (default 1h), with a normal retained-record target of 256. Running /
976 starting / waiting workers and the continuation identities and budget
977 lineage needed by live work are preserved. Cleanup cannot discard an old
978 ID while its continuation is still active or erase usage history needed
979 to enforce an active scope.
980 - `SubAgentRuntime::background_runtime()` starts from `child_runtime()` but
981 replaces the turn-scoped child token with a fresh cancellation token, so
982 parent turn cancellation does not stop detached background sessions.
983 - The `is_running` check ignores agents whose `task_handle` is
984 `None`; this avoids counting persisted-but-detached records
985 toward the concurrency cap (#509).
986 - `SharedSubAgentManager` is `Arc<RwLock<...>>` — read paths use
987 read locks so `/agents` and the workbar projection don't block
988 the main loop during multi-agent fan-out (#510).
989
990 Personal profiles use the same format at
991 `$CODEWHALE_HOME/agents/<id>.toml` (normally `~/.codewhale/agents/`). For example:
992
993 ```toml
994 # ~/.codewhale/agents/reasoner.toml
995 base_role = "explore"
996 provider = "openrouter"
997 model = "qwen/qwen3.7-plus"
998 reasoning_effort = "high"
999
1000 [permissions]
1001 allow_shell = false
1002 trust = false
1003 ```
1004
1005 Select it with `agent(action: "start", profile: "reasoner", prompt: "...")`.
1006 The provider must also be configured in `config.toml`. The receipt names the
1007 resolved profile, its personal/project origin, provider/model and effective
1008 reasoning effort. Effort is normalized to the selected model's supported tiers;
1009 an explicit `thinking` request overrides the saved preference.
1010
1011 `allow_shell` and `trust` belong under `[permissions]`, not at the top level.
1012 A profile cannot grant `allow_shell = true`, `trust = true`, or disable approval.
1013 Use the appropriate `base_role` for the task; the parent session's live policy
1014 remains the authority ceiling. These profile fields are not a way to grant
1015 additional access.
1016
1017 A malformed, unreadable or duplicate profile now causes an explicit selection
1018 error, including when its name matches a built-in role. It never silently
1019 substitutes a lower roster layer. Repair the file and retry; profiles are reloaded
1020 for each launch. `agent(action: "roster")` reports affected profile identities and
1021 paths in `profile_load_issues` without exposing parser excerpts. Other valid
1022 profiles remain available, and a valid project override still wins over a broken
1023 personal definition. Fleet run creation performs the same check before storing
1024 a run or launching workers.
1025
1025 lines MARKDOWN