pi-herdr-agents 2.0.5 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/AGENTS.md +20 -14
  2. package/CHANGELOG.md +41 -2
  3. package/CONTEXT.md +86 -32
  4. package/README.md +257 -136
  5. package/RELEASING.md +4 -2
  6. package/config.json.example +0 -3
  7. package/docs/README.md +38 -15
  8. package/docs/adr/0001-btw-ephemeral-side-questions.md +1 -1
  9. package/docs/adr/0002-agent-workflow-skill-runtime-taxonomy.md +1 -1
  10. package/docs/adr/0003-installable-role-packs.md +21 -13
  11. package/docs/adr/0009-remove-workflow-subsystem.md +1 -1
  12. package/docs/adr/0012-adopt-maestro-seams-in-repo.md +45 -0
  13. package/docs/adr/0013-pack-neutral-execution-host.md +63 -0
  14. package/docs/adr/0014-operator-cancel-terminal-intent.md +134 -0
  15. package/docs/worktree-subagents.md +4 -2
  16. package/maestro/adapters/fake/fake-harness-adapter.ts +263 -0
  17. package/{pi-extension/subagents/activity.ts → maestro/adapters/pi/activity-file.ts} +15 -72
  18. package/{pi-extension/subagents → maestro/adapters/pi/child}/subagent-done.ts +30 -3
  19. package/{pi-extension/subagents → maestro/adapters/pi}/completion.ts +4 -4
  20. package/{pi-extension/subagents → maestro/adapters/pi}/launch.ts +386 -328
  21. package/maestro/adapters/pi/model-registry.ts +46 -0
  22. package/maestro/adapters/pi/pi-harness-adapter.ts +701 -0
  23. package/maestro/adapters/pi/process-identity.ts +303 -0
  24. package/{pi-extension/subagents → maestro/adapters/pi}/session.ts +1 -13
  25. package/maestro/adapters/pi/task-model-init.ts +55 -0
  26. package/maestro/core/activity.ts +29 -0
  27. package/maestro/core/config/model-config.ts +473 -0
  28. package/{pi-extension/subagents → maestro/core/config}/pane-config.ts +4 -6
  29. package/{pi-extension/subagents → maestro/core/config}/persistent-config.ts +4 -6
  30. package/{pi-extension/subagents → maestro/core/config}/role-config.ts +15 -10
  31. package/{pi-extension/subagents → maestro/core/config}/supervision-config.ts +4 -6
  32. package/{pi-extension/subagents → maestro/core/config}/task-model-init.ts +45 -58
  33. package/maestro/core/config/task-model-types.ts +22 -0
  34. package/maestro/core/harness-adapter.ts +117 -0
  35. package/maestro/core/index.ts +3 -0
  36. package/{pi-extension/subagents → maestro/core}/lifecycle.ts +27 -126
  37. package/maestro/core/roles/discovery.ts +555 -0
  38. package/{pi-extension/subagents/runtime-routing.ts → maestro/core/routing.ts} +36 -43
  39. package/maestro/core/shell.ts +3 -0
  40. package/{pi-extension/subagents → maestro/core}/status.ts +3 -7
  41. package/{pi-extension/subagents → maestro/core}/supervision.ts +1 -1
  42. package/maestro/core/surface-provider.ts +185 -0
  43. package/maestro/core/types.ts +449 -0
  44. package/maestro/core/worktree-cleanup.ts +374 -0
  45. package/maestro/core/worktree.ts +93 -0
  46. package/maestro/runtime/index.ts +44 -0
  47. package/maestro/runtime/pi-run-session.ts +1210 -0
  48. package/maestro/runtime/run-session.ts +801 -0
  49. package/maestro/runtime/surface-retention.ts +6 -0
  50. package/maestro/runtime/task-model-init.ts +22 -0
  51. package/maestro/runtime/worktree-operations.ts +627 -0
  52. package/maestro/surfaces/fake/fake-surface-provider.ts +311 -0
  53. package/maestro/surfaces/herdr/herdr-surface-provider.ts +200 -0
  54. package/{pi-extension/subagents → maestro/surfaces/herdr}/herdr.ts +65 -14
  55. package/{pi-extension/subagents → maestro/surfaces/herdr}/terminal.ts +7 -5
  56. package/package.json +10 -9
  57. package/pi-extension/subagents/config-path.ts +5 -1
  58. package/pi-extension/subagents/index.ts +837 -1789
  59. package/pi-extension/subagents/model-registry.ts +46 -0
  60. package/skills/pi-herdr-agents/SKILL.md +276 -0
  61. package/agents/adversarial-reviewer.md +0 -153
  62. package/agents/planner.md +0 -87
  63. package/agents/poteto.md +0 -32
  64. package/agents/reviewer.md +0 -132
  65. package/agents/scout.md +0 -105
  66. package/agents/visual-tester.md +0 -234
  67. package/agents/worker.md +0 -121
  68. package/docs/review-evaluation.md +0 -183
  69. package/pi-extension/subagents/model-config.ts +0 -305
  70. package/pi-extension/subagents/plan-skill.md +0 -280
  71. package/pi-extension/subagents/worktree-cleanup.ts +0 -785
  72. package/skills/orchestrate/SKILL.md +0 -91
  73. package/skills/orchestrate/adversarial-review-example.js +0 -400
  74. package/skills/orchestrate/adversarial-review.md +0 -87
  75. /package/{pi-extension/subagents → maestro/core/config}/type-guards.ts +0 -0
  76. /package/{pi-extension/subagents → maestro/core}/wake.ts +0 -0
package/README.md CHANGED
@@ -13,8 +13,7 @@ Delegate investigation, implementation, and review without blocking the parent s
13
13
  - **Live supervision** — track process and turn state in Pi's subagent widget; interrupt one child turn without destroying its session.
14
14
  - **Managed worktrees** — isolate writing agents in retained Herdr workspaces with explicit Git ownership and recovery details.
15
15
  - **Conversation handoff** — continue the active Pi conversation in a new worktree with `/worktree` while preserving the parent session.
16
- - **Orchestrated reviews** — fan out fresh public reviewers and synthesize their evidence in the parent.
17
- - **Reusable roles** — use bundled agents, project or global definitions, and installable role packs.
16
+ - **Pack-neutral roles** — use project or global definitions and installable role packs; this package ships no default roles or workflows.
18
17
  - **Persistent specialists** — retain one policy-bound Pi session for sequential, turn-based tasks.
19
18
 
20
19
  ## Requirements
@@ -49,8 +48,45 @@ pi
49
48
 
50
49
  Restart or `/reload` Pi after installation. Review package source before installing any Pi package.
51
50
 
51
+ ## Release notes
52
+
53
+ [`CHANGELOG.md`](CHANGELOG.md) is generated from Git history on each release.
54
+ Hand-written upgrade notes for breaking releases live here.
55
+
56
+ ### 3.0.0
57
+
58
+ 3.0.0 makes the host pack-neutral. It also adds conditional task-model writes
59
+ (`expectedConfigRevision`, an advisory lock, and the reported `configRevision`),
60
+ the `pi-herdr-agents` operating skill, and `subagent_cancel`.
61
+
62
+ **Breaking changes.** The package no longer ships the seven former bundled roles,
63
+ `/plan` and its plan skill, or `/skill:orchestrate`; these moved to optional role
64
+ packs. `/iterate`, `/btw`, and `/btw-close` were removed without replacement.
65
+ `roles.bundled` is now a deprecated no-op. A named launch of a role that no
66
+ definition or installed pack supplies now fails before Herdr creates a pane or
67
+ worktree.
68
+
69
+ **Migration.**
70
+
71
+ - Install `pi-herdr-roles` for the six generic roles (`scout`, `planner`,
72
+ `worker`, `reviewer`, `adversarial-reviewer`, `visual-tester`), `/plan`, and
73
+ `/skill:orchestrate`.
74
+ - Install `pi-herdr-pstack` for the `poteto` role.
75
+ - Remove `roles.bundled` from `$PI_CODING_AGENT_DIR/herdr-agents/config.json`.
76
+ - Alternatively, copy a former role's definition into `.pi/agents/` or the
77
+ global agents directory to keep it without a pack.
78
+
79
+ See [Migrating from bundled roles](#migrating-from-bundled-roles) for the full
80
+ mapping and pack-compatibility notes.
81
+
52
82
  ## Quick start
53
83
 
84
+ This package is an execution host and ships no agent roles. Named roles come
85
+ from your project or global definitions or from an installed
86
+ [role pack](#publish-a-role-pack). The `scout` examples below assume one of
87
+ those provides `scout`; see [Migrating from bundled roles](#migrating-from-bundled-roles).
88
+ A bare launch without `agent` needs no role.
89
+
54
90
  Ask Pi to delegate naturally:
55
91
 
56
92
  ```text
@@ -74,7 +110,9 @@ Pi can also call the tool directly:
74
110
  ```typescript
75
111
  subagent({ name: "Auth scout", agent: "scout", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Map the authentication flow" });
76
112
  subagent({ name: "DB scout", agent: "scout", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Map the session schema" });
77
- // Both return immediately; each result comes back independently.
113
+ // A bare launch needs no installed role.
114
+ subagent({ name: "Auth summary", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Summarize the authentication flow" });
115
+ // All return immediately; each result comes back independently.
78
116
  ```
79
117
 
80
118
  Use ordinary panes for read-only agents. A single or sequential writer can work in the parent checkout; give each parallel independent writing agent a unique managed worktree. The parent acts as coordinator: decompose work, give each child one bounded outcome with its goal, allowed files, verification, and commit instruction, and keep dependent writes sequential. Children are leaves by default; the parent owns integration and final verification. See [Worktree subagents](docs/worktree-subagents.md).
@@ -119,19 +157,20 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
119
157
 
120
158
  ### Extensions
121
159
 
122
- **Subagents** — 9 parent-session tools + 7 commands, plus 2 child-only tools:
160
+ **Subagents** — 10 parent-session tools + 3 commands, plus 2 child-only tools:
123
161
 
124
162
  | Tool | Description |
125
163
  | -------------------- | ------------------------------------------------------------------------------------------- |
126
164
  | `subagent` | Spawn a sub-agent in a dedicated herdr pane (async — returns immediately) |
127
165
  | `subagent_interrupt` | Interrupt a running Pi-backed subagent's current turn |
166
+ | `subagent_cancel` | Cancel a running ordinary subagent: no fallback, one cancelled result after confirmed termination |
128
167
  | `subagent_send` | Deliver a follow-up task to an idle persistent specialist |
129
168
  | `subagent_stop` | Gracefully stop a persistent specialist after its active task settles |
130
169
  | `subagents_list` | List available agent definitions |
131
170
  | `worktree_list` | Parent-only inspect-only inventory of managed worktrees and cleanup blockers |
132
171
  | `worktree_remove` | Parent-only explicit removal by `target` path, branch, or workspace ID; optional `preserve: true` commits dirty state first |
133
172
  | `subagent_resume` | Resume a previous Pi-backed sub-agent session in a new ordinary pane (async) |
134
- | `subagents_write_task_models` | Parent-only internal tool that validates and atomically writes `models.tasks` preferences |
173
+ | `subagents_write_task_models` | Parent-only internal tool that validates and atomically writes `models.tasks` preferences, optionally conditional on `expectedConfigRevision` |
135
174
 
136
175
  | Pi child-only tool | Description |
137
176
  | ---------------- | ------------------------------------------------------------------------- |
@@ -140,10 +179,6 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
140
179
 
141
180
  | Command | Description |
142
181
  | -------------------------- | ------------------------------------ |
143
- | `/plan` | Start a full planning workflow |
144
- | `/iterate` | Fork into a subagent for quick fixes |
145
- | `/btw <question>` | Open an ephemeral side-question session in a background tab |
146
- | `/btw-close` | Close the current BTW session |
147
182
  | `/worktree <name> [task]` | Continue this session in a new managed worktree (`/worktree list` lists them) |
148
183
  | `/subagent <agent> <task>` | Spawn a named agent directly (`/subagent list` lists available agents) |
149
184
  | `/subagents-init [preferences]` | Draft task-category model preferences from the live authenticated registry, with optional ranking preferences |
@@ -154,47 +189,70 @@ This package distinguishes directly runnable **agent roles**, Pi-native
154
189
  **skills**, and authenticated Pi **runtimes**. A multi-stage user outcome may
155
190
  be a command or skill that composes roles; it is not itself an agent role.
156
191
 
157
- The current orchestration inventory is:
192
+ The host's own orchestration surfaces are:
158
193
 
159
194
  | Surface | Entry point | Behavior |
160
195
  | --- | --- | --- |
161
- | Planning | `/plan` | Scout, interactive planner, workers, and reviewer; writes plan artifacts. |
162
- | Iteration | `/iterate` | Opens one interactive full-context Pi fork. |
163
- | Side question | `/btw`, `/btw-close` | Opens one replaceable interactive Pi side session. |
196
+ | Delegation | `subagent`, `/subagent <agent> <task>` | Launches one bare or named child; results return automatically. |
164
197
  | Worktree handoff | `/worktree <name> [task]`, `/worktree list` | Forks the active conversation into a managed worktree. |
165
- | Orchestrated review | `/skill:orchestrate` | Parent materializes evidence, fans out public reviewers, and synthesizes results. |
166
- | Adversarial review | `/skill:orchestrate`, `adversarial-reviewer` | Risk-based public discovery, cross-family verification, and parent synthesis. |
167
198
 
168
- See [ADR-0002](docs/adr/0002-agent-workflow-skill-runtime-taxonomy.md) and
169
- [ADR-0009](docs/adr/0009-remove-workflow-subsystem.md).
199
+ Planning, review, and other multi-stage workflows belong to role packs and
200
+ skills, not to this package. See
201
+ [ADR-0002](docs/adr/0002-agent-workflow-skill-runtime-taxonomy.md),
202
+ [ADR-0009](docs/adr/0009-remove-workflow-subsystem.md), and
203
+ [ADR-0013](docs/adr/0013-pack-neutral-execution-host.md).
170
204
 
171
- ### Bundled visible definitions
205
+ ### Roles and role packs
172
206
 
173
- | Definition | Classification | Default runtime | Responsibility |
174
- | ---------- | -------------- | --------------- | -------------- |
175
- | **planner** | Coordinator agent role | Config, then parent | Clarifies requirements, explores approaches, and writes plans with ordered tasks. |
176
- | **scout** | Leaf agent role | Config, then parent | Maps relevant code, conventions, and verification paths. |
177
- | **worker** | Leaf agent role | Config, then parent | Implements bounded tasks and verifies the result. |
178
- | **reviewer** | Leaf agent role | Config, then parent | Reviews changes for correctness, security, and maintainability. |
179
- | **visual-tester** | Leaf agent role | Config, then parent | Performs visual QA through the `chrome-cdp` skill. |
180
- | **poteto** | Coordinator agent role | Config, then parent | Autonomously investigates, edits minimally, delegates independent work, and verifies. |
181
- | **adversarial-reviewer** | Coordinator role | Exact eligible authenticated Pi models selected by risk and project policy | Runs two routine or three high-risk discovery reviewers, candidate-dependent cross-family verification, and parent synthesis through public asynchronous children. |
207
+ This package is a pack-neutral execution host: it ships no agent roles, no
208
+ `/plan` command, and no planning or review skills. Its one skill,
209
+ `pi-herdr-agents`, is a general operating guide for the host. A named launch resolves
210
+ `agent` from project definitions, global definitions, and roles registered by
211
+ installed role packs, in that precedence order (see below). An empty catalog is
212
+ valid. A bare launch without `agent` always works. An explicitly named role that
213
+ is missing or invalid fails before Herdr creates a pane or worktree; it is never
214
+ silently replaced by a bare agent.
182
215
 
183
216
  All subagents execute through Pi. Claude models remain available through normal
184
217
  Pi provider/model routing. Legacy role definitions that contain `cli` fail before
185
218
  Herdr creates a pane or worktree; remove `cli` and `cli-model`, then select an
186
219
  authenticated Pi `provider/model-id`.
187
220
 
188
- Optional prerequisites fail closed and are not bundled:
221
+ Role packs own their roles' prerequisites, such as a required skill, and must
222
+ document them. This package does not install role packs or prerequisites.
189
223
 
190
- - `visual-tester` needs an external `chrome-cdp` skill that provides `scripts/cdp.mjs`.
191
- - Adversarial review needs a resolved standalone `reviewer` role, confirmed human-only authorship or known author model families, and enough distinct exact authenticated Pi models to satisfy project author-family exclusion and cross-family verification. Routine discovery uses two distinct IDs; concrete high-risk surfaces use three distinct lenses. The parent materializes pinned evidence before public fan-out. A project-approved reduced topology must disclose omitted coverage.
192
- - `/plan` uses the bundled scout and planner roles and records ordered tasks in
193
- `plan.md`; it does not require a researcher role, todo tool, or `write-todos` skill.
224
+ ### Migrating from bundled roles
194
225
 
195
- This package does not install optional prerequisites.
226
+ Earlier versions bundled seven roles and two workflows. They have moved to
227
+ separately installed packs or have been removed. Nothing is installed
228
+ automatically, and your global and project role files and `config.json` are not
229
+ modified.
196
230
 
197
- Bundled agents use model defaults from `config.json` when configured; otherwise
231
+ | Former bundled surface | Status | Destination |
232
+ | --- | --- | --- |
233
+ | `scout`, `planner`, `worker`, `reviewer`, `adversarial-reviewer`, `visual-tester` roles | Moved | `pi-herdr-roles` role pack |
234
+ | `/plan` command and its plan skill | Moved | `pi-herdr-roles` |
235
+ | `/skill:orchestrate` and its adversarial-review resources | Moved | `pi-herdr-roles` |
236
+ | `poteto` role | Moved | `pi-herdr-pstack` role pack |
237
+ | `/iterate` | Removed, not relocated | Call `subagent({ name, task, fork: true, interactive: true })` directly |
238
+ | `/btw`, `/btw-close` | Removed, not relocated | None |
239
+ | `roles.bundled` setting | Deprecated no-op | Remove it from `config.json` |
240
+
241
+ Both destination packs are experimental, unpublished candidates; their install
242
+ sources and compatible host versions are not final. Install a role pack with
243
+ `pi install` like any Pi package and enable it beside this extension; a role pack
244
+ stays inert without it. Older versions of this package that still bundle these
245
+ roles, `/plan`, or `orchestrate` collide with the replacement packs: a bundled
246
+ role rejects a same-named pack role, and Pi resolves duplicate commands and
247
+ skills by discovery order. Setting `roles.bundled: false` on an older host only
248
+ removes its roles, not its command or skill. Upgrade the host instead of
249
+ combining an older host with the replacement packs.
250
+
251
+ Existing `models.agents` preferences keyed by role name keep applying when a
252
+ pack or definition supplies that name. To keep a former role without installing
253
+ a pack, copy its definition into `.pi/agents/` or the global agents directory.
254
+
255
+ Roles use model defaults from `config.json` when configured; otherwise
198
256
  they inherit the parent model. Thinking defaults still come from agent
199
257
  frontmatter or the parent level. This resolution chain remains available as a
200
258
  fallback, but orchestrators should explicitly set each child's exact
@@ -207,17 +265,16 @@ different model family than the author. For ordinary review, prefer a different
207
265
  authenticated model family. When no other authenticated model family is
208
266
  available, ordinary review may use a same-family reviewer in a fresh standalone
209
267
  session. Disclose that this review is context-isolated, not cross-family
210
- independent. Cross-family verification, `/skill:orchestrate`, and
211
- `adversarial-reviewer` must not use this fallback. A stronger model in the same
212
- family is a quality escalation, not cross-family
268
+ independent. Cross-family verification must not use this fallback. A stronger
269
+ model in the same family is a quality escalation, not cross-family
213
270
  independent review. Family is the independence boundary; project policy may
214
271
  separately require a different provider.
215
272
 
216
273
  Discovery loads definitions in **package → global → project** order, so effective
217
274
  priority remains **project** (`.pi/agents/`) > **global**
218
275
  (`$PI_CODING_AGENT_DIR/agents/`, defaulting to `~/.pi/agent/agents/`) >
219
- **package**. Package definitions include bundled roles and roles contributed by
220
- installed Pi role packs. Both `subagents_list` and `/subagent list` show each
276
+ **package**. Package definitions are the roles contributed by installed Pi role
277
+ packs; there is no bundled layer. Both `subagents_list` and `/subagent list` show each
221
278
  visible definition's source; contributed roles include their package identity,
222
279
  for example `(package:@acme/security-roles)`. A hidden higher-priority definition
223
280
  still suppresses a visible lower-priority definition.
@@ -268,6 +325,7 @@ Projected labels include:
268
325
  - `stalled` — pane inspection is unhealthy long enough that the parent can no longer trust the run
269
326
  - `running` — fallback when only coarse process presence is known (e.g. non-Pi backends)
270
327
  - `finalizing` — completion was observed and delivery is in progress; the process elapsed timer freezes here
328
+ - `cancelling…` / `cancel unconfirmed` — a `subagent_cancel` is terminating the run, or its termination could not be confirmed and the run stays live
271
329
 
272
330
  The widget header counts **active** vs **open**:
273
331
 
@@ -278,7 +336,7 @@ When `activeCount === 0` (every tracked row is open), the border uses an amber a
278
336
 
279
337
  A fixed internal watchdog marks a run as `stalled` when pane inspection fails or the pane disappears without a completion sidecar; valid long-running `active` or `waiting` states do not become `stalled` just because time passes. When a run enters `stalled` or recovers from it, the parent agent receives a steer message so it can react. All other status transitions stay in the widget only.
280
338
 
281
- **Interactive subagents stay silent.** Long-running user-driven subagents (e.g. `planner`, or any `/iterate` fork) do not wake the parent session on `stalled`/`recovered` transitions — the user is working directly in the subagent's pane, and a steer message there would just burn an orchestrator turn on a no-op "still waiting" ping. The widget still updates normally, and activity snapshots are still recorded/classified regardless of the `interactive` setting. By default, agents with `auto-exit: true` are treated as autonomous and get stall pings; agents without it are treated as interactive and stay quiet. Override per-agent with `interactive: true|false` in frontmatter, or per-spawn with `interactive: true|false` on the tool call.
339
+ **Interactive subagents stay silent.** Long-running user-driven subagents (for example, an interactive planning role or a bare `interactive: true` fork) do not wake the parent session on `stalled`/`recovered` transitions — the user is working directly in the subagent's pane, and a steer message there would just burn an orchestrator turn on a no-op "still waiting" ping. The widget still updates normally, and activity snapshots are still recorded/classified regardless of the `interactive` setting. By default, agents with `auto-exit: true` are treated as autonomous and get stall pings; agents without it are treated as interactive and stay quiet. Override per-agent with `interactive: true|false` in frontmatter, or per-spawn with `interactive: true|false` on the tool call.
282
340
 
283
341
  #### Configuration
284
342
 
@@ -298,9 +356,6 @@ or re-run `/subagents-init`.
298
356
  "models": {
299
357
  "agents": {}
300
358
  },
301
- "roles": {
302
- "bundled": true
303
- },
304
359
  "persistent": {
305
360
  "maxAgents": 3
306
361
  },
@@ -355,8 +410,8 @@ a reviewer from a different model family than the author. For ordinary review,
355
410
  prefer a different authenticated model family. When no other authenticated
356
411
  model family is available, ordinary review may use a same-family reviewer in a
357
412
  fresh standalone session. Disclose that this review is context-isolated, not
358
- cross-family independent. Cross-family verification, `/skill:orchestrate`, and
359
- `adversarial-reviewer` must not use this fallback. Use an exact authenticated
413
+ cross-family independent. Cross-family verification must not use this fallback.
414
+ Use an exact authenticated
360
415
  shortlist `provider/model-id` when the
361
416
  authoring family is known; `task:review` does not establish independence. Family
362
417
  is the independence boundary; project policy may separately require a different
@@ -409,11 +464,37 @@ preserving unrelated settings. Its tool schema accepts partial nonempty
409
464
  categories (omitted categories are removed), rejects empty `tasks: {}` input,
410
465
  and rejects exact duplicate refs within a category after trimming;
411
466
  IDs remain case-sensitive. Its result includes normalized saved `tasks`,
412
- `tasksMeta`, `configPath`, and `missingCategories`. Init requests all six categories
467
+ `tasksMeta`, `configPath`, `missingCategories`, and `configRevision`. Init requests all six categories
413
468
  and a before/after table based on that saved result, not the unsaved draft. It
414
469
  must explain missing categories or changed choices; with no available models,
415
470
  it must report the limitation without writing.
416
471
 
472
+ Optional `expectedConfigRevision` makes a write conditional on the config the
473
+ proposal was read from. A revision is `sha256:` followed by 64 lowercase hex
474
+ digits of the SHA-256 of the exact `config.json` bytes (not normalized JSON or
475
+ only `models.tasks`), or the literal `missing` when the file is absent. Any byte
476
+ change, including whitespace or unrelated settings, makes the revision stale; a
477
+ `missing` revision rejects a file that now exists, and an existing revision
478
+ rejects a file that was removed. A stale revision fails with `Stale task model
479
+ config revision` without replacing configuration: re-read, re-propose, and
480
+ re-approve rather than retrying. Malformed revisions, including `null` and empty
481
+ strings, fail closed. Omitting the field keeps the unconditional write. A write
482
+ to a missing file still seeds from the packaged `config.json.example`.
483
+ `configRevision` is the revision of the exact bytes written and can serve as the
484
+ next precondition.
485
+
486
+ Every writer call, conditional or not, holds an exclusive `config.json.lock`
487
+ sibling while it reads one snapshot, checks the revision, and atomically renames
488
+ a private temporary file into place. A held lock fails immediately with `Task
489
+ model config writer busy`; there are no waits or retries. The lock is never
490
+ broken automatically: after a crash, the error names the recorded owner and
491
+ reports when that process is no longer running, and you remove the lock only
492
+ after confirming that no writer is active. Each call removes only its own lock
493
+ and temporary file. This lock is advisory: it serializes cooperating writers
494
+ but cannot constrain a text editor or another process that ignores it. The
495
+ revision check detects changes made before the snapshot is read; it is not a
496
+ filesystem transaction against arbitrary external writers.
497
+
417
498
  `task:<category>` values select subagent models; they are not slash commands and
418
499
  do not change the parent model. Ordered authenticated candidate plans resolve
419
500
  before launch. Ordinary nonpersistent runs can retry later candidates after
@@ -426,16 +507,21 @@ review requires a reviewer from a different model family than the author. For
426
507
  ordinary review, prefer a different authenticated model family. When no other
427
508
  authenticated model family is available, ordinary review may use a same-family
428
509
  reviewer in a fresh standalone session. Disclose that this review is
429
- context-isolated, not cross-family independent. Cross-family verification,
430
- `/skill:orchestrate`, and `adversarial-reviewer` must not use this fallback.
431
- Another route to the same family is not
510
+ context-isolated, not cross-family independent. Cross-family verification
511
+ must not use this fallback. Another route to the same family is not
432
512
  independent review. Family is the independence boundary; project policy may
433
513
  separately require a different provider. Run `/reload` (or start a new session)
434
514
  after writing preferences.
435
515
 
436
516
  Set `persistent.maxAgents` to the maximum concurrently retained persistent specialists. It defaults to `3`; a persistent spawn at the cap is rejected before Herdr creates a pane or workspace, and no specialist is evicted.
437
517
 
438
- Set `roles.bundled` to `false` to exclude this package's bundled role definitions from listing and exact-name launch. It defaults to `true`. Registered role packs remain available, and global and project definitions keep their existing precedence. A role-pack name collides with a bundled role only while that bundled layer is enabled; when it is disabled, the role pack can supply that name.
518
+ `roles.bundled` is deprecated and has no effect because this package ships no
519
+ roles. Existing `true` and `false` values are accepted so that current
520
+ configuration keeps loading; a parent session reports one warning per extension
521
+ load naming the file and asking you to remove the key. The extension never
522
+ rewrites the file. Other values remain configuration errors, as do unknown keys
523
+ under `roles`. Registered role packs are the entire package layer, and global and
524
+ project definitions keep their precedence over them.
439
525
 
440
526
  ### Supervision transport
441
527
 
@@ -470,7 +556,8 @@ never interrupts, kills, retries, or restarts a child. It identifies `blocked-to
470
556
  `truncated-turn` (an observed `toolUse` stop with no tool call; its cause is unknown), or
471
557
  `generic-no-progress` when neither condition is established, then
472
558
  includes the session path and manual recovery options. Ordinary children can be
473
- interrupted or, after manual termination, resumed or newly spawned. Persistent
559
+ interrupted, cancelled with `subagent_cancel`, or, after termination, resumed or
560
+ newly spawned. Persistent
474
561
  ordinary-pane specialists can be interrupted or stopped with `subagent_stop` and
475
562
  replaced; they cannot be resumed. Managed-worktree children, including persistent
476
563
  ones, retain their workspace and continue there only after the previous process
@@ -490,11 +577,11 @@ was 4.82 s. The benchmark measures `/proc` CPU ticks for the supervisor and
490
577
  isolated Herdr tree, not parent-model latency; raw samples are written to
491
578
  `/tmp/issue29-bench/` by `test/bench/supervision-bench.mjs`.
492
579
 
493
- `panes.mode` defaults to `"grouped"` when omitted. Ordinary public `subagent` and `subagent_resume` launches, including bare forks and `/iterate`, fill extension-owned `Agents`, `Agents 2`, etc. tabs in the target checkout's existing workspace. `panes.maxPerTab` is a positive safe integer, defaults to `4`, and counts all live panes in each owned tab, including user-added panes and retained shells. Overlapping launches in one parent respect this cap. It is independent of `persistent.maxAgents`.
580
+ `panes.mode` defaults to `"grouped"` when omitted. Ordinary public `subagent` and `subagent_resume` launches, including bare forks, fill extension-owned `Agents`, `Agents 2`, etc. tabs in the target checkout's existing workspace. `panes.maxPerTab` is a positive safe integer, defaults to `4`, and counts all live panes in each owned tab, including user-added panes and retained shells. Overlapping launches in one parent respect this cap. It is independent of `persistent.maxAgents`.
494
581
 
495
582
  Checkout matching uses Herdr's canonical `worktree.checkout_path` and includes descendant directories. Shell working directories do not establish workspace ownership. If no checkout matches (including non-Git directories), placement uses the caller's workspace; overflow never creates a workspace. A reviewer with `cwd` set to a managed checkout joins that workspace without creating another worktree. Resume placement uses the saved session's cwd.
496
583
 
497
- Explicit `panes.mode: "tab"` preserves one new tab per ordinary child in the caller's workspace. Explicit `"split"` preserves splits of the stable parent pane. `panes.direction` is `"right"` (default) or `"down"` and applies to grouped and legacy splits. `maxPerTab` does not affect these legacy modes. Managed worktrees retain their separate workspaces, while `/btw` keeps its existing tab behavior.
584
+ Explicit `panes.mode: "tab"` preserves one new tab per ordinary child in the caller's workspace. Explicit `"split"` preserves splits of the stable parent pane. `panes.direction` is `"right"` (default) or `"down"` and applies to grouped and legacy splits. `maxPerTab` does not affect these legacy modes. Managed worktrees retain their separate workspaces.
498
585
 
499
586
  Ownership is tracked by returned pane/tab/workspace IDs, never labels. Separate parent processes own separate groups; `/reload` preserves a parent's in-memory ownership, but a full restart does not adopt old tabs. Placement never moves existing panes or renames user tabs. Background launches preserve focus; Herdr may resize sibling panes when splitting or closing. User-added panes are never closed by automatic tab cleanup. An owned tab remains reusable while user panes remain, even after all child panes close.
500
587
 
@@ -536,12 +623,15 @@ when the extension starts. Run `/reload` after changing it. Package-root
536
623
 
537
624
  ## Spawning Subagents
538
625
 
626
+ Examples that set `agent` assume a role pack or a project/global definition
627
+ supplies that role; this package ships none.
628
+
539
629
  ```typescript
540
630
  // Explicit fast-tier runtime for bounded reconnaissance
541
631
  subagent({ name: "Scout", agent: "scout", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Analyze the codebase..." });
542
632
 
543
633
  // Force a full-context fork for this spawn
544
- subagent({ name: "Iterate", fork: true, model: "<provider>/<mid-tier-id>", thinking: "medium", task: "Fix the bug where..." });
634
+ subagent({ name: "Fix", fork: true, model: "<provider>/<mid-tier-id>", thinking: "medium", task: "Fix the bug where..." });
545
635
 
546
636
  // Explicit frontier-tier runtime for architecture work
547
637
  subagent({ name: "Planner", agent: "planner", model: "<provider>/<frontier-tier-id>", thinking: "high", task: "Work through the design with me" });
@@ -572,12 +662,19 @@ subagent({
572
662
  | `interactive` | boolean | derived | Mark this spawn as interactive (don't wake the parent on stall/recovery). Defaults to the agent's `interactive` frontmatter, otherwise the inverse of `auto-exit`. |
573
663
  | `model` | string | configured or parent | Exact authenticated `provider/model-id`, ordered fallback list, or whole-value `task:<category>` (coding, review, recon, qa, architecture, docs). Task routing is tool-only; worktrees use its first authenticated candidate. Resolution is tool argument → agent frontmatter → per-agent config → global config → parent |
574
664
  | `thinking` | string | parent level | Pick the model tier first, then set thinking within that model's range: minimal/low for bounded mechanical work, medium for ordinary implementation or review, high+ for architecture, security, or hard diagnosis. Omitting still inherits the parent level; this is a discouraged fallback for orchestrated children. |
575
- | `systemPrompt` | string | — | Role/system-prompt text for a bare spawn; named agents keep their definition body |
665
+ | `systemPrompt` | string | — | Role text for a bare spawn, delivered as a role block at the top of the child's first message (not the system prompt); dropped for `fork: true` children. Named agents keep their definition body |
576
666
  | `skills` | string | — | Comma-separated skill names |
577
667
  | `tools` | string | — | Comma-separated tool names |
578
668
  | `cwd` | string | — | Working directory, or source repository when `worktree` is set (see [Role Folders](#role-folders)) |
579
669
  | `worktree` | object \| null | — | Isolated Herdr-managed Git worktree; requires `branch`, with optional `base` (committed `HEAD` by default). Omit or pass `null` to use an ordinary pane in `cwd` when a client requires the property. |
580
670
 
671
+ A bare spawn's `systemPrompt` is not passed to Pi as a system prompt. The host
672
+ prepends it as a role block to the child's first message, which is delivered
673
+ through a task artifact file referenced with `@path`. A full-context fork
674
+ (`fork: true`) receives only the raw task, so its `systemPrompt` is dropped. Set
675
+ `fork: false` when a bare child must receive reference or role text through
676
+ `systemPrompt`.
677
+
581
678
  ### Naming coordinated children
582
679
 
583
680
  Before launching a new group, choose a short task slug and label each new child
@@ -591,7 +688,15 @@ prompts, handoffs, and results.
591
688
 
592
689
  Use one worktree per parallel independent writing task; a single or sequential writer can work in the parent checkout, and read-only agents use ordinary panes. Omit `worktree` for an ordinary pane; clients whose generated tool schema requires every property may send `worktree: null` with the same effect. `cwd` selects the source Git repository, `branch` must be unique, and `base` is resolved to an exact commit before creation. If `cwd` is a linked checkout, Herdr provisioning uses the principal checkout while the requested checkout supplies the base SHA and manifest provenance. A successful launch from that linked checkout does not itself authorize cleanup there: cleanup checks the canonical principal/source repository under the invoking parent session's cwd, not `manifest.sourceCwd` or shared Git identity. If cleanup is needed, start the parent Pi session rooted at the principal checkout or an ancestor containing it, then use the normal explicit cleanup flow; changing directories inside an existing Pi session does not change its session cwd. If `base` is omitted, the source checkout's committed `HEAD` is used. Parent-checkout changes that have not been committed are not copied.
593
690
 
594
- A launch with `worktree` and an effective bundled `scout`, `reviewer`, or `adversarial-reviewer` returns a non-blocking warning. Scouts and reviewers normally need an ordinary pane; the adversarial reviewer is a coordinator that uses an ordinary pane for its child reviewers. To inspect or review an existing worker result, start an ordinary child in that retained worktree path. Project or global role overrides do not receive these bundled-role warnings. A `read,bash` allowlist is not an enforced read-only boundary because shell commands can mutate files; report-only roles must restrict Bash to safe inspection and avoid artifact-generating verification in the reviewed checkout.
691
+ Choose a worktree from the task, not from a role name: the extension emits no
692
+ role-specific worktree warnings. Read-only scouting and review normally use an
693
+ ordinary pane; to inspect or review an existing worker result, start an ordinary
694
+ child in that retained worktree path. Do not infer that a role cannot write
695
+ because its `tools` omit `write` or `edit`: a `read,bash` allowlist is not an
696
+ enforced read-only boundary because shell commands can mutate files. Report-only
697
+ roles must restrict Bash to safe inspection and avoid artifact-generating
698
+ verification in the reviewed checkout. Herdr worktree workspaces persist until
699
+ explicitly removed.
595
700
 
596
701
  The child starts at the returned worktree root. Tell writing agents to test and commit when you want a commit-based handoff, and tell them not to push, merge, switch branches, or remove the worktree. The parent owns review and integration.
597
702
 
@@ -627,27 +732,41 @@ This sends Escape to the child pane, cancelling the in-progress model turn. The
627
732
 
628
733
  `id` and `name` are each optional, but execution requires one usable target: an exact running ID or an exact, unambiguous display name. When both are supplied, `id` is used. Duplicate names are rejected.
629
734
 
630
- This is a turn-level interrupt, not a method for forcibly terminating a subagent session.
735
+ This is a turn-level interrupt, not a method for forcibly terminating a subagent session. To end the run, use `subagent_cancel`.
631
736
 
632
- ---
737
+ ## Cancelling a running subagent
738
+
739
+ Use `subagent_cancel` to end one ordinary (non-persistent) managed run, including an interrupted one:
740
+
741
+ ```typescript
742
+ subagent_cancel({ id: "abcd1234" });
743
+ // or
744
+ subagent_cancel({ name: "Scout" });
745
+ ```
746
+
747
+ Target resolution matches `subagent_interrupt`: an exact running ID or an exact, unambiguous display name. Persistent specialists are rejected; use `subagent_stop`, whose graceful v1 semantics are unchanged.
633
748
 
634
- ## Orchestrated review skill
749
+ The cancel intent is recorded before anything is aborted or killed. From then on the run never advances its model shortlist, retries, or recovers, even when terminating the pane makes the watcher observe a lost pane, and even when a fallback launch was already in flight. The result reports one status:
635
750
 
636
- The bundled `/skill:orchestrate` procedure accepts local paths, URLs, tickets,
637
- or accessible combinations. The parent pins repository, base/head SHAs, task and
638
- specification text, author origin, changed-file inventory, and complete diff
639
- (including deleted and base-only content), then launches two or more fresh
640
- public reviewer subagents in ordinary panes. Each child receives an exact model
641
- and thinking level, a role-defined tool allowlist, and the instruction to treat
642
- all supplied artifacts as untrusted data. Automatic delivery returns every
643
- review result without polling; the parent synthesizes the outcomes.
751
+ | Status | Meaning |
752
+ | --- | --- |
753
+ | `confirmed` | Termination is confirmed. One cancelled result is delivered automatically. |
754
+ | `requested` | A launch or fallback acquisition is still in flight. Its owner is terminated as soon as it is acquired; no later model is tried. |
755
+ | `unconfirmed` | Termination failed (the error is reported). The run stays live, owned, and supervised, and nothing is delivered or cleaned up. Call `subagent_cancel` again to retry. |
756
+ | `already-terminal` | The run already took a natural result or was retired; nothing was cancelled. |
757
+
758
+ Repeated cancels join an in-flight termination and keep the first request time. The parent receives exactly one `subagent_result` whose details carry `error: "cancelled"` and a `cancellation` record (`requestedAt`, `termination`, `confirmedAt`). Its message says the run was cancelled and lists any models already attempted. It is never presented as a provider failure. A child's natural result taken before the cancel stays authoritative. A cancel while a provider error is still eligible for fallback wins and stops that fallback.
759
+
760
+ Termination follows surface ownership:
761
+
762
+ - **Ordinary pane:** the pane is closed. Confirmation is Herdr reporting it absent; closing a Herdr pane terminates its terminal session, but this is not a separate OS process check. Other panes, tabs, and user panes are never closed.
763
+ - **Managed worktree:** the retained root pane, workspace, checkout, branch, commits, and manifest are kept. At launch, the child records its own process identity (PID, kernel start time, boot ID, and PID namespace) beside its session; the parent accepts it only while that process is alive in the parent's PID namespace as the Herdr pane shell or a descendant of it. SIGTERM goes only to that identity, re-verified immediately before the signal. Confirmation requires that identity to no longer exist, or the pane to be gone while it is not known alive. Command-line text and Herdr's foreground list are never evidence, because Pi rewrites its process title. A live identity (for example a suspended Pi), or one whose SIGTERM fails while it is still alive, leaves termination `unconfirmed` even if the pane is gone. An identity that was not captured (including on non-Linux hosts), is unreadable, or whose PID now names another process is never signalled and leaves termination `unconfirmed` unless pane absence confirms it. Every Herdr query and capture wait is bounded by the cancel's deadline (5 seconds); an answer that arrives after the deadline is ignored, even if it settles before the timer runs, and never changes a reported outcome. A retry re-checks, and if the launch capture expired it captures the identity again within its own deadline. The manifest becomes `cancelled` only after confirmed termination (a parent shutdown while unconfirmed records the plain shutdown state), and the normal worktree handoff is delivered. No Git cleanup is performed. See [Worktree subagents](docs/worktree-subagents.md).
644
764
 
645
- Role frontmatter `tools:` is the only enforced allowlist. `read,bash` is not a
646
- read-only boundary because Bash can mutate files. The skill uses ordinary public child launches only; it does not create a private
647
- checkout, execute scripts, or request approval.
648
- Its adversarial branch adds risk-based discovery and cross-family verification;
649
- malformed reports, failures, and unresolved serious candidates propagate
650
- `INCOMPLETE`.
765
+ Do not poll after cancelling; the cancelled result arrives as a steer message. Design rationale: [ADR-0014](docs/adr/0014-operator-cancel-terminal-intent.md).
766
+
767
+ The package ships one host-owned skill, `pi-herdr-agents`, a general operating guide covering launching, lifecycle control, persistent specialists, worktrees, and configuration. Live tool descriptions and this README remain authoritative.
768
+
769
+ ---
651
770
 
652
771
  ## caller_ping — Child-to-Parent Help Request
653
772
 
@@ -689,50 +808,24 @@ await caller_ping({
689
808
 
690
809
  ---
691
810
 
692
- ## The `/plan` Workflow
693
-
694
- The `/plan` command orchestrates a full planning-to-implementation pipeline.
695
-
696
- ```
697
- /plan Add a dark mode toggle to the settings page
698
- ```
699
-
700
- ```
701
- Phase 1: Investigation → Autonomous scout maps the codebase
702
- Phase 2: Planning → Interactive planner subagent (user collaborates)
703
- Phase 3: Review Plan → Confirm ordered tasks, adjust if needed
704
- Phase 4: Execute → Shared-checkout sequential workers by default; isolated parallel workers for independent tasks
705
- Phase 5: Integrate → Parent reviews and integrates worktree branches one at a time, only when worktrees are used
706
- Phase 6: Review → Reviewer subagent checks the integrated changes
707
- ```
708
-
709
- The parent workspace and tab names stay unchanged. Subagents use the configured placement policy; grouped mode reuses available space in owned Agents tabs.
710
-
711
- ---
712
-
713
- ## The `/iterate` Workflow
714
-
715
- For quick, focused work without polluting the main session's context.
716
-
717
- ```
718
- /iterate Fix the off-by-one error in the pagination logic
719
- ```
720
-
721
- This always forks the current session into a subagent with full conversation context. It does not inherit an agent default `session-mode`. Make the fix, verify it, and exit to return. The main session gets a summary of what was done.
722
-
723
- ---
724
-
725
- ## The `/btw` Workflow
726
-
727
- Use `/btw` for a quick side question without adding a turn to the main session:
728
-
729
- ```text
730
- /btw What did we decide about session cleanup?
731
- ```
732
-
733
- The extension snapshots the current active conversation branch, opens a non-focused Herdr tab, and starts an interactive Pi session with the same model and thinking level. The answer stays in that tab and is never delivered as a subagent result. A second `/btw` replaces the previous one; `/btw-close` closes it explicitly.
734
-
735
- BTW shares the current working directory. It treats inherited work as reference context and modifies the workspace only when the side question explicitly requests it. Cleanup is best effort; if closing fails, the tab remains available for manual recovery.
811
+ ## Child-context hint (`PI_SUBAGENT_ID`)
812
+
813
+ Every fresh or resumed child launched by this extension, including `fork: true`
814
+ children and persistent specialists, runs with `PI_SUBAGENT_ID` set to its run
815
+ ID. The extension uses it to register the child protocol tools and to omit
816
+ parent-only surfaces (`worktree_list`, `worktree_remove`,
817
+ `subagents_write_task_models`, and `/subagents-init`). A `/worktree <name>`
818
+ handoff starts an ordinary interactive Pi session and does not set it. Pi's own
819
+ `/fork` and `/clone` run in the same process and keep that process's
820
+ environment: the variable is absent in a top-level session and still present
821
+ inside a child.
822
+
823
+ Role packs may read `PI_SUBAGENT_ID` as a context hint, for example to avoid
824
+ restoring parent-only session state inside a delegated child. It is not an
825
+ authentication or security boundary: any process can set it, and shell commands
826
+ and nested processes a child runs inherit it, including a `pi` process started
827
+ from the child's Bash tool. Do not grant or deny privileges based on it. There
828
+ is no other parent/child protocol.
736
829
 
737
830
  ---
738
831
 
@@ -765,7 +858,6 @@ not disguise a workflow as an agent definition.
765
858
  | Project | `.pi/agents/<name>.md` | The role belongs to one repository |
766
859
  | Global | `$PI_CODING_AGENT_DIR/agents/<name>.md` | The role should be available everywhere; the default root is `~/.pi/agent` |
767
860
  | Role pack | An installed Pi package's registered `roles/` directory | The role should be independently installable and shareable |
768
- | Bundled | This package's `agents/<name>.md` | Contributing a fallback role maintained with `pi-herdr-agents` |
769
861
 
770
862
  The filename stem is the launch key. `name` frontmatter is optional because it
771
863
  defaults to the filename stem. If supplied, keep it identical so overrides remain
@@ -886,9 +978,10 @@ the files, derives package name/version from the nearest `package.json`, and
886
978
  reports invalid paths, missing descriptions, filename/name mismatches, and
887
979
  package-layer collisions in the listing surfaces.
888
980
 
889
- Role packs cannot replace an enabled bundled role, and duplicate role names
890
- from multiple role packs are disabled rather than resolved by extension load
891
- order. Use a global or project definition for an intentional override.
981
+ Registered role packs form the whole package layer and have no priority over
982
+ one another: duplicate role names from multiple role packs are disabled with a
983
+ diagnostic rather than resolved by extension load order. Use a global or
984
+ project definition for an intentional override.
892
985
 
893
986
  See [ADR-0003](docs/adr/0003-installable-role-packs.md) for the registration seam,
894
987
  collision rules, and rejected alternatives.
@@ -930,7 +1023,7 @@ Compare definitions against the reference below and verify them with
930
1023
  | `session-mode` | string | Default child-session mode: `standalone`, `lineage-only`, or `fork` |
931
1024
  | `spawning` | boolean | Set exactly `false` to deny all subagent-spawning tools under the exact unquoted key `spawning:`. Only one `true` or `false` declaration is accepted. |
932
1025
  | `deny-tools` | string | One non-empty inline comma-separated `pi-herdr-agents` tool list to suppress under the exact unquoted key `deny-tools:`; this is not a universal cross-extension deny list. YAML lists, containers, multiline values, quotes, comments, noncanonical keys, and duplicates are rejected. |
933
- | `auto-exit` | boolean | Auto-shutdown after Pi fully settles when the latest assistant turn does not end with `stopReason: "aborted"` — no `subagent_done` call needed. User input does not permanently disable auto-exit. Recommended for autonomous agents (scout, worker); not for interactive ones (planner). Also determines the default value of `interactive` (see below). |
1026
+ | `auto-exit` | boolean | Auto-shutdown after Pi fully settles when the latest assistant turn does not end with `stopReason: "aborted"` — no `subagent_done` call needed. User input does not permanently disable auto-exit. Recommended for autonomous roles; not for interactive ones the user drives. Also determines the default value of `interactive` (see below). |
934
1027
  | `interactive` | boolean | Override whether stall/recovery transitions wake the parent session. Defaults to the inverse of `auto-exit`: autonomous agents (`auto-exit: true`) are non-interactive and get stall pings; agents without `auto-exit` are interactive and stay quiet. Explicit values take precedence. |
935
1028
  | `persistent` | boolean | Keep this role's specialist session open between tasks. Follow-up work uses `subagent_send`; persistent specialists cannot be resumed in v1. |
936
1029
  | `cwd` | string | Default working directory. Absolute paths are unambiguous; relative agent-frontmatter paths resolve from Pi's agent config directory (`PI_CODING_AGENT_DIR` or `~/.pi/agent`), not the project root |
@@ -938,7 +1031,7 @@ Compare definitions against the reference below and verify them with
938
1031
 
939
1032
  ---
940
1033
 
941
- Discovery still resolves precedence before visibility filtering. If a project-local hidden agent has the same name as a visible global or bundled agent, the hidden project agent wins and the lower-precedence agent does not appear in `subagents_list`.
1034
+ Discovery still resolves precedence before visibility filtering. If a project-local hidden agent has the same name as a visible global or role-pack agent, the hidden project agent wins and the lower-precedence agent does not appear in `subagents_list`.
942
1035
 
943
1036
  ### `session-mode`
944
1037
 
@@ -950,7 +1043,7 @@ Choose how a subagent session starts:
950
1043
 
951
1044
  `lineage-only` is useful when you want session discovery and fork lineage UX to show the relationship later, but you do **not** want the child to inherit the parent's turns.
952
1045
 
953
- `fork: true` on the tool call forces `fork` mode; `fork: false` forces `standalone` mode. Omitting `fork` inherits the agent's frontmatter `session-mode`. `/iterate` uses the explicit `true` override on purpose.
1046
+ `fork: true` on the tool call forces `fork` mode; `fork: false` forces `standalone` mode. Omitting `fork` inherits the agent's frontmatter `session-mode`.
954
1047
 
955
1048
  ```yaml
956
1049
  ---
@@ -972,8 +1065,8 @@ When set to `true`, the agent session shuts down on Pi's `agent_settled` event u
972
1065
 
973
1066
  **When to use:**
974
1067
 
975
- - ✅ Autonomous agents (scout, worker, reviewer) that run to completion
976
- - ❌ Interactive agents (planner, iterate) where the user drives the session
1068
+ - ✅ Autonomous roles, such as scouting, implementation, or review, that run to completion
1069
+ - ❌ Interactive roles or `interactive: true` forks where the user drives the session
977
1070
 
978
1071
  ```yaml
979
1072
  ---
@@ -986,7 +1079,7 @@ auto-exit: true
986
1079
 
987
1080
  Controls whether status transitions (`stalled`, `recovered`) wake the parent session with a steer message.
988
1081
 
989
- **Default:** the inverse of `auto-exit`. Autonomous agents (`auto-exit: true`) are non-interactive and ping the parent on stall/recovery; named agents without `auto-exit` are interactive and stay quiet. Bare spawns have no agent definition and default to autonomous auto-exit behavior. `/iterate` is interactive because it explicitly passes `interactive: true`.
1082
+ **Default:** the inverse of `auto-exit`. Autonomous agents (`auto-exit: true`) are non-interactive and ping the parent on stall/recovery; named agents without `auto-exit` are interactive and stay quiet. Bare spawns have no agent definition and default to autonomous auto-exit behavior; they become interactive only when the call passes `interactive: true`.
990
1083
 
991
1084
  **Why it exists:** Interactive agents can run for minutes or hours while the user thinks, types, and reads in the subagent's pane. Child snapshots still update the widget, but stalled/recovered supervision messages rarely need to wake the parent for user-driven sessions. Skipping the steer keeps the parent quiet until the child actually finishes.
992
1085
 
@@ -1016,7 +1109,7 @@ Without a restrictive `tools` allowlist or spawning policy, a sub-agent can spaw
1016
1109
 
1017
1110
  ### `spawning: false`
1018
1111
 
1019
- Denies all subagent lifecycle tools (`subagent`, `subagent_interrupt`, `subagent_send`, `subagent_stop`, `subagents_list`, `subagent_resume`):
1112
+ Denies all subagent lifecycle tools (`subagent`, `subagent_interrupt`, `subagent_cancel`, `subagent_send`, `subagent_stop`, `subagents_list`, `subagent_resume`):
1020
1113
 
1021
1114
  ```yaml
1022
1115
  ---
@@ -1038,15 +1131,13 @@ deny-tools: subagent
1038
1131
 
1039
1132
  ### Recommended Configuration
1040
1133
 
1041
- | Agent | `spawning` | Rationale |
1134
+ | Role shape | `spawning` | Rationale |
1042
1135
  | --- | --- | --- |
1043
- | planner | *(default)* | Can spawn scouts for investigation. |
1044
- | poteto | `true` | Delegates independent work. |
1045
- | adversarial-reviewer | `true` | Compatibility coordinator; launches bounded discovery, conditional verification, and synthesis children. It sets `auto-exit: false` so automatic child-result steers can drive every wave, then calls `subagent_done`. |
1046
- | worker | `false` | Implements bounded tasks. |
1047
- | reviewer | `false` | Reviews without delegation. |
1048
- | scout | `false` | Gathers context without delegation. |
1049
- | visual-tester | `false` | Performs visual QA without delegation. |
1136
+ | Leaf (scouting, implementation, review, QA) | `false` | Performs one bounded responsibility without delegation. |
1137
+ | Coordinator | `true` | Delegates bounded children; a multi-wave coordinator sets `auto-exit: false` so automatic child-result steers drive each wave, then calls `subagent_done`. |
1138
+ | Interactive collaborator | *(default)* | May delegate factual gaps while the user drives the session. |
1139
+
1140
+ Each role pack documents the settings of the roles it ships.
1050
1141
 
1051
1142
  ---
1052
1143
 
@@ -1095,6 +1186,36 @@ Every sub-agent session displays a compact one-line tools widget summarizing ava
1095
1186
 
1096
1187
  ## Development
1097
1188
 
1189
+ ### Code map
1190
+
1191
+ The maestro seams remain inside one npm package with the same Pi extension
1192
+ entry point. Pi is the sole real harness and Herdr the sole real surface
1193
+ provider; fakes are for conformance tests only.
1194
+
1195
+ - `pi-extension/subagents/index.ts` — Pi composition root: tools/commands,
1196
+ role-pack event bridge, host policy, widgets, and parent delivery.
1197
+ - `pi-extension/subagents/model-registry.ts`, `config-path.ts` — permanent
1198
+ host-local SDK capability glue and configuration-path conventions.
1199
+ - `maestro/core/` — seam interfaces/types, activity and lifecycle projection,
1200
+ status, routing, wake-ups, and supervision.
1201
+ - `maestro/core/roles/discovery.ts`, `maestro/core/config/` — role discovery,
1202
+ config loaders with injected directories, and task-model init prompt logic.
1203
+ - `maestro/core/worktree.ts`, `maestro/core/worktree-cleanup.ts` — manifest
1204
+ schema/state, handoff types, and cleanup eligibility/formatting.
1205
+ - `maestro/adapters/pi/` — Pi launch, completion, session I/O, activity files,
1206
+ model SDK glue, and registry projection behind `PiHarnessAdapter`;
1207
+ `child/subagent-done.ts` implements the child protocol.
1208
+ - `maestro/surfaces/herdr/` — `HerdrSurfaceProvider`, Herdr CLI driver, and
1209
+ terminal scripts/placement.
1210
+ - `maestro/runtime/` — run ownership, controls/retries, observation,
1211
+ delivery-gated cleanup, Pi composition, worktree operations/handoff, and
1212
+ task-model init composition.
1213
+ - `maestro/adapters/fake/`, `maestro/surfaces/fake/`, `test/maestro/` —
1214
+ conformance fakes, seam tests, and the import dependency-rule test.
1215
+
1216
+ See [ADR-0012](docs/adr/0012-adopt-maestro-seams-in-repo.md), the
1217
+ [glossary](CONTEXT.md), and the [documentation map](docs/README.md).
1218
+
1098
1219
  Run local checks:
1099
1220
 
1100
1221
  ```bash