pi-herdr-agents 2.0.5 → 3.0.1

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 +56 -2
  3. package/CONTEXT.md +86 -32
  4. package/README.md +285 -138
  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
@@ -1,6 +1,8 @@
1
1
  # Pi Herdr Agents
2
2
 
3
- ![Pi Herdr Agents: parallel Pi agents running asynchronously in dedicated Herdr panes and managed worktrees.](https://raw.githubusercontent.com/giuseppecrj/pi-herdr-agents/main/docs/assets/pi-herdr-agents-gallery.png)
3
+ ![Pi Herdr Agents: a parent Pi session delegating to parallel child agents in dedicated Herdr panes, an isolated worktree and a retained session, with a live status widget.](https://raw.githubusercontent.com/giuseppecrj/pi-herdr-agents/main/docs/assets/pi-herdr-agents-gallery.png)
4
+
5
+ > **Agents:** the tool list is in [What's Included](#whats-included) and the operating guide is [`skills/pi-herdr-agents/SKILL.md`](skills/pi-herdr-agents/SKILL.md). Contributors: read [`AGENTS.md`](AGENTS.md).
4
6
 
5
7
  Asynchronous subagents for [Pi](https://github.com/earendil-works/pi), running exclusively in [Herdr](https://herdr.dev).
6
8
 
@@ -13,8 +15,7 @@ Delegate investigation, implementation, and review without blocking the parent s
13
15
  - **Live supervision** — track process and turn state in Pi's subagent widget; interrupt one child turn without destroying its session.
14
16
  - **Managed worktrees** — isolate writing agents in retained Herdr workspaces with explicit Git ownership and recovery details.
15
17
  - **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.
18
+ - **Pack-neutral roles** — use project or global definitions and installable role packs; this package ships no default roles or workflows.
18
19
  - **Persistent specialists** — retain one policy-bound Pi session for sequential, turn-based tasks.
19
20
 
20
21
  ## Requirements
@@ -49,8 +50,33 @@ pi
49
50
 
50
51
  Restart or `/reload` Pi after installation. Review package source before installing any Pi package.
51
52
 
53
+ > **Upgrading from 2.x?** Bundled roles and several commands moved out. See [3.0.0 release notes](#300).
54
+
55
+ ## Contents
56
+
57
+ - [Requirements](#requirements), [Install](#install), [Safety and uninstall](#safety-and-uninstall)
58
+ - [Quick start](#quick-start), [Release notes](#release-notes), [How it works](#how-it-works)
59
+ - [What's Included](#whats-included): tools, commands, the operating skill, role packs
60
+ - [Async Subagent Flow](#async-subagent-flow): status, configuration, model routing
61
+ - [Spawning Subagents](#spawning-subagents), [Persistent specialists](#persistent-specialists), [Interrupting](#interrupting-a-running-subagent), [Cancelling](#cancelling-a-running-subagent)
62
+ - [The `/worktree` Workflow](#the-worktree-workflow), [Custom Agents](#custom-agents), [Tool Access Control](#tool-access-control)
63
+ - [Development](#development), [License](#license)
64
+
65
+ ## Safety and uninstall
66
+
67
+ - Child agents are real Pi processes running with your user account's permissions, inside Herdr panes. Worktrees isolate Git checkouts, not processes or permissions.
68
+ - The extension creates Herdr panes, tabs and managed worktrees only when a launch asks for them. It never pushes, merges, opens pull requests, deletes branches or removes worktrees on its own; cleanup is an explicit parent action ([worktree cleanup](#explicit-worktree-cleanup)).
69
+ - What it writes: `$PI_CODING_AGENT_DIR/herdr-agents/config.json` (only through `/subagents-init` or the writer tool, never on startup); per-launch artifacts under the parent session's `artifacts/<session-id>/` directory beside Pi's session store, which hold the child's full task text and any `systemPrompt` as Markdown files, activity snapshots and worktree manifests; and the child's own Pi session file. A managed worktree that carries its own `.pi/agent` directory receives that child's session inside the checkout. Treat task text as potentially sensitive when you share or inspect those files.
70
+ - To uninstall: first list and remove any retained worktrees while the extension is still loaded (`/worktree list`, then `/worktree remove <target>`), because those commands leave with the package. Then run `pi remove npm:pi-herdr-agents`, and delete `$PI_CODING_AGENT_DIR/herdr-agents/` and the `artifacts/` directories above if you no longer want the configuration and launch records.
71
+
52
72
  ## Quick start
53
73
 
74
+ This package is an execution host and ships no agent roles. Named roles come
75
+ from your project or global definitions or from an installed
76
+ [role pack](#publish-a-role-pack). The `scout` examples below assume one of
77
+ those provides `scout`; see [Migrating from bundled roles](#migrating-from-bundled-roles).
78
+ A bare launch without `agent` needs no role.
79
+
54
80
  Ask Pi to delegate naturally:
55
81
 
56
82
  ```text
@@ -74,11 +100,45 @@ Pi can also call the tool directly:
74
100
  ```typescript
75
101
  subagent({ name: "Auth scout", agent: "scout", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Map the authentication flow" });
76
102
  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.
103
+ // A bare launch needs no installed role.
104
+ subagent({ name: "Auth summary", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Summarize the authentication flow" });
105
+ // All return immediately; each result comes back independently.
78
106
  ```
79
107
 
80
108
  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).
81
109
 
110
+ ## Release notes
111
+
112
+ [`CHANGELOG.md`](CHANGELOG.md) is generated from Git history on each release.
113
+ Hand-written upgrade notes for breaking releases live here.
114
+
115
+ ### 3.0.0
116
+
117
+ 3.0.0 makes the host pack-neutral. It also adds conditional task-model writes
118
+ (`expectedConfigRevision`, an advisory lock, and the reported `configRevision`),
119
+ the `pi-herdr-agents` operating skill, and `subagent_cancel`.
120
+
121
+ **Breaking changes.** The package no longer ships the seven former bundled roles,
122
+ `/plan` and its plan skill, or `/skill:orchestrate`; these moved to optional role
123
+ packs. `/iterate`, `/btw`, and `/btw-close` were removed without replacement.
124
+ `roles.bundled` is now a deprecated no-op. A named launch of a role that no
125
+ definition or installed pack supplies now fails before Herdr creates a pane or
126
+ worktree.
127
+
128
+ **Migration.**
129
+
130
+ - Install `pi-herdr-roles` for the six generic roles (`scout`, `planner`,
131
+ `worker`, `reviewer`, `adversarial-reviewer`, `visual-tester`), `/plan`, and
132
+ `/skill:orchestrate`.
133
+ - Install `pi-herdr-pstack` for the `poteto-mode` methodology skill and command.
134
+ It ships no named roles; its delegates are bare.
135
+ - Remove `roles.bundled` from `$PI_CODING_AGENT_DIR/herdr-agents/config.json`.
136
+ - Alternatively, copy a former role's definition into `.pi/agents/` or the
137
+ global agents directory to keep it without a pack.
138
+
139
+ See [Migrating from bundled roles](#migrating-from-bundled-roles) for the full
140
+ mapping and pack-compatibility notes.
141
+
82
142
  ## How it works
83
143
 
84
144
  ![Pi Herdr Agents lifecycle: spawn a child, run it in Herdr, supervise live state, and deliver one bounded result to the parent.](https://raw.githubusercontent.com/giuseppecrj/pi-herdr-agents/main/docs/assets/async-subagent-lifecycle.png)
@@ -119,19 +179,24 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
119
179
 
120
180
  ### Extensions
121
181
 
122
- **Subagents** — 9 parent-session tools + 7 commands, plus 2 child-only tools:
182
+ **Subagents** — 10 parent-session tools + 3 commands, plus 2 child-only tools:
123
183
 
124
184
  | Tool | Description |
125
185
  | -------------------- | ------------------------------------------------------------------------------------------- |
126
186
  | `subagent` | Spawn a sub-agent in a dedicated herdr pane (async — returns immediately) |
127
187
  | `subagent_interrupt` | Interrupt a running Pi-backed subagent's current turn |
188
+ | `subagent_cancel` | Cancel a running ordinary subagent: no fallback, one cancelled result after confirmed termination |
128
189
  | `subagent_send` | Deliver a follow-up task to an idle persistent specialist |
129
190
  | `subagent_stop` | Gracefully stop a persistent specialist after its active task settles |
130
191
  | `subagents_list` | List available agent definitions |
131
192
  | `worktree_list` | Parent-only inspect-only inventory of managed worktrees and cleanup blockers |
132
193
  | `worktree_remove` | Parent-only explicit removal by `target` path, branch, or workspace ID; optional `preserve: true` commits dirty state first |
133
194
  | `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 |
195
+ | `subagents_write_task_models` | Parent-only internal tool that validates and atomically writes `models.tasks` preferences, optionally conditional on `expectedConfigRevision` |
196
+
197
+ | Skill | Description |
198
+ | ----- | ----------- |
199
+ | `pi-herdr-agents` | Operating guide for this host: launching, supervising, interrupting, cancelling and resuming children, worktrees, persistent specialists, model routing and configuration. Loaded by agents on demand; see `skills/pi-herdr-agents/SKILL.md` |
135
200
 
136
201
  | Pi child-only tool | Description |
137
202
  | ---------------- | ------------------------------------------------------------------------- |
@@ -140,10 +205,6 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
140
205
 
141
206
  | Command | Description |
142
207
  | -------------------------- | ------------------------------------ |
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
208
  | `/worktree <name> [task]` | Continue this session in a new managed worktree (`/worktree list` lists them) |
148
209
  | `/subagent <agent> <task>` | Spawn a named agent directly (`/subagent list` lists available agents) |
149
210
  | `/subagents-init [preferences]` | Draft task-category model preferences from the live authenticated registry, with optional ranking preferences |
@@ -154,47 +215,70 @@ This package distinguishes directly runnable **agent roles**, Pi-native
154
215
  **skills**, and authenticated Pi **runtimes**. A multi-stage user outcome may
155
216
  be a command or skill that composes roles; it is not itself an agent role.
156
217
 
157
- The current orchestration inventory is:
218
+ The host's own orchestration surfaces are:
158
219
 
159
220
  | Surface | Entry point | Behavior |
160
221
  | --- | --- | --- |
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. |
222
+ | Delegation | `subagent`, `/subagent <agent> <task>` | Launches one bare or named child; results return automatically. |
164
223
  | 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
224
 
168
- See [ADR-0002](docs/adr/0002-agent-workflow-skill-runtime-taxonomy.md) and
169
- [ADR-0009](docs/adr/0009-remove-workflow-subsystem.md).
225
+ Planning, review, and other multi-stage workflows belong to role packs and
226
+ skills, not to this package. See
227
+ [ADR-0002](docs/adr/0002-agent-workflow-skill-runtime-taxonomy.md),
228
+ [ADR-0009](docs/adr/0009-remove-workflow-subsystem.md), and
229
+ [ADR-0013](docs/adr/0013-pack-neutral-execution-host.md).
170
230
 
171
- ### Bundled visible definitions
231
+ ### Roles and role packs
172
232
 
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. |
233
+ This package is a pack-neutral execution host: it ships no agent roles, no
234
+ `/plan` command, and no planning or review skills. Its one skill,
235
+ `pi-herdr-agents`, is a general operating guide for the host. A named launch resolves
236
+ `agent` from project definitions, global definitions, and roles registered by
237
+ installed role packs, in that precedence order (see below). An empty catalog is
238
+ valid. A bare launch without `agent` always works. An explicitly named role that
239
+ is missing or invalid fails before Herdr creates a pane or worktree; it is never
240
+ silently replaced by a bare agent.
182
241
 
183
242
  All subagents execute through Pi. Claude models remain available through normal
184
243
  Pi provider/model routing. Legacy role definitions that contain `cli` fail before
185
244
  Herdr creates a pane or worktree; remove `cli` and `cli-model`, then select an
186
245
  authenticated Pi `provider/model-id`.
187
246
 
188
- Optional prerequisites fail closed and are not bundled:
247
+ Role packs own their roles' prerequisites, such as a required skill, and must
248
+ document them. This package does not install role packs or prerequisites.
189
249
 
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.
250
+ ### Migrating from bundled roles
194
251
 
195
- This package does not install optional prerequisites.
252
+ Earlier versions bundled seven roles and two workflows. They have moved to
253
+ separately installed packs or have been removed. Nothing is installed
254
+ automatically, and your global and project role files and `config.json` are not
255
+ modified.
196
256
 
197
- Bundled agents use model defaults from `config.json` when configured; otherwise
257
+ | Former bundled surface | Status | Destination |
258
+ | --- | --- | --- |
259
+ | `scout`, `planner`, `worker`, `reviewer`, `adversarial-reviewer`, `visual-tester` roles | Moved | `pi-herdr-roles` role pack |
260
+ | `/plan` command and its plan skill | Moved | `pi-herdr-roles` |
261
+ | `/skill:orchestrate` and its adversarial-review resources | Moved | `pi-herdr-roles` |
262
+ | `poteto` role | Removed; replaced by the `poteto-mode` skill and `/poteto-mode` command | `pi-herdr-pstack` |
263
+ | `/iterate` | Removed, not relocated | Call `subagent({ name, task, fork: true, interactive: true })` directly |
264
+ | `/btw`, `/btw-close` | Removed, not relocated | None |
265
+ | `roles.bundled` setting | Deprecated no-op | Remove it from `config.json` |
266
+
267
+ Both destination packs are experimental, unpublished candidates; their install
268
+ sources and compatible host versions are not final. Install a role pack with
269
+ `pi install` like any Pi package and enable it beside this extension; a role pack
270
+ stays inert without it. Older versions of this package that still bundle these
271
+ roles, `/plan`, or `orchestrate` collide with the replacement packs: a bundled
272
+ role rejects a same-named pack role, and Pi resolves duplicate commands and
273
+ skills by discovery order. Setting `roles.bundled: false` on an older host only
274
+ removes its roles, not its command or skill. Upgrade the host instead of
275
+ combining an older host with the replacement packs.
276
+
277
+ Existing `models.agents` preferences keyed by role name keep applying when a
278
+ pack or definition supplies that name. To keep a former role without installing
279
+ a pack, copy its definition into `.pi/agents/` or the global agents directory.
280
+
281
+ Roles use model defaults from `config.json` when configured; otherwise
198
282
  they inherit the parent model. Thinking defaults still come from agent
199
283
  frontmatter or the parent level. This resolution chain remains available as a
200
284
  fallback, but orchestrators should explicitly set each child's exact
@@ -207,17 +291,16 @@ different model family than the author. For ordinary review, prefer a different
207
291
  authenticated model family. When no other authenticated model family is
208
292
  available, ordinary review may use a same-family reviewer in a fresh standalone
209
293
  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
294
+ independent. Cross-family verification must not use this fallback. A stronger
295
+ model in the same family is a quality escalation, not cross-family
213
296
  independent review. Family is the independence boundary; project policy may
214
297
  separately require a different provider.
215
298
 
216
299
  Discovery loads definitions in **package → global → project** order, so effective
217
300
  priority remains **project** (`.pi/agents/`) > **global**
218
301
  (`$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
302
+ **package**. Package definitions are the roles contributed by installed Pi role
303
+ packs; there is no bundled layer. Both `subagents_list` and `/subagent list` show each
221
304
  visible definition's source; contributed roles include their package identity,
222
305
  for example `(package:@acme/security-roles)`. A hidden higher-priority definition
223
306
  still suppresses a visible lower-priority definition.
@@ -268,6 +351,7 @@ Projected labels include:
268
351
  - `stalled` — pane inspection is unhealthy long enough that the parent can no longer trust the run
269
352
  - `running` — fallback when only coarse process presence is known (e.g. non-Pi backends)
270
353
  - `finalizing` — completion was observed and delivery is in progress; the process elapsed timer freezes here
354
+ - `cancelling…` / `cancel unconfirmed` — a `subagent_cancel` is terminating the run, or its termination could not be confirmed and the run stays live
271
355
 
272
356
  The widget header counts **active** vs **open**:
273
357
 
@@ -278,7 +362,7 @@ When `activeCount === 0` (every tracked row is open), the border uses an amber a
278
362
 
279
363
  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
364
 
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.
365
+ **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
366
 
283
367
  #### Configuration
284
368
 
@@ -298,9 +382,6 @@ or re-run `/subagents-init`.
298
382
  "models": {
299
383
  "agents": {}
300
384
  },
301
- "roles": {
302
- "bundled": true
303
- },
304
385
  "persistent": {
305
386
  "maxAgents": 3
306
387
  },
@@ -355,8 +436,8 @@ a reviewer from a different model family than the author. For ordinary review,
355
436
  prefer a different authenticated model family. When no other authenticated
356
437
  model family is available, ordinary review may use a same-family reviewer in a
357
438
  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
439
+ cross-family independent. Cross-family verification must not use this fallback.
440
+ Use an exact authenticated
360
441
  shortlist `provider/model-id` when the
361
442
  authoring family is known; `task:review` does not establish independence. Family
362
443
  is the independence boundary; project policy may separately require a different
@@ -409,11 +490,37 @@ preserving unrelated settings. Its tool schema accepts partial nonempty
409
490
  categories (omitted categories are removed), rejects empty `tasks: {}` input,
410
491
  and rejects exact duplicate refs within a category after trimming;
411
492
  IDs remain case-sensitive. Its result includes normalized saved `tasks`,
412
- `tasksMeta`, `configPath`, and `missingCategories`. Init requests all six categories
493
+ `tasksMeta`, `configPath`, `missingCategories`, and `configRevision`. Init requests all six categories
413
494
  and a before/after table based on that saved result, not the unsaved draft. It
414
495
  must explain missing categories or changed choices; with no available models,
415
496
  it must report the limitation without writing.
416
497
 
498
+ Optional `expectedConfigRevision` makes a write conditional on the config the
499
+ proposal was read from. A revision is `sha256:` followed by 64 lowercase hex
500
+ digits of the SHA-256 of the exact `config.json` bytes (not normalized JSON or
501
+ only `models.tasks`), or the literal `missing` when the file is absent. Any byte
502
+ change, including whitespace or unrelated settings, makes the revision stale; a
503
+ `missing` revision rejects a file that now exists, and an existing revision
504
+ rejects a file that was removed. A stale revision fails with `Stale task model
505
+ config revision` without replacing configuration: re-read, re-propose, and
506
+ re-approve rather than retrying. Malformed revisions, including `null` and empty
507
+ strings, fail closed. Omitting the field keeps the unconditional write. A write
508
+ to a missing file still seeds from the packaged `config.json.example`.
509
+ `configRevision` is the revision of the exact bytes written and can serve as the
510
+ next precondition.
511
+
512
+ Every writer call, conditional or not, holds an exclusive `config.json.lock`
513
+ sibling while it reads one snapshot, checks the revision, and atomically renames
514
+ a private temporary file into place. A held lock fails immediately with `Task
515
+ model config writer busy`; there are no waits or retries. The lock is never
516
+ broken automatically: after a crash, the error names the recorded owner and
517
+ reports when that process is no longer running, and you remove the lock only
518
+ after confirming that no writer is active. Each call removes only its own lock
519
+ and temporary file. This lock is advisory: it serializes cooperating writers
520
+ but cannot constrain a text editor or another process that ignores it. The
521
+ revision check detects changes made before the snapshot is read; it is not a
522
+ filesystem transaction against arbitrary external writers.
523
+
417
524
  `task:<category>` values select subagent models; they are not slash commands and
418
525
  do not change the parent model. Ordered authenticated candidate plans resolve
419
526
  before launch. Ordinary nonpersistent runs can retry later candidates after
@@ -426,16 +533,21 @@ review requires a reviewer from a different model family than the author. For
426
533
  ordinary review, prefer a different authenticated model family. When no other
427
534
  authenticated model family is available, ordinary review may use a same-family
428
535
  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
536
+ context-isolated, not cross-family independent. Cross-family verification
537
+ must not use this fallback. Another route to the same family is not
432
538
  independent review. Family is the independence boundary; project policy may
433
539
  separately require a different provider. Run `/reload` (or start a new session)
434
540
  after writing preferences.
435
541
 
436
542
  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
543
 
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.
544
+ `roles.bundled` is deprecated and has no effect because this package ships no
545
+ roles. Existing `true` and `false` values are accepted so that current
546
+ configuration keeps loading; a parent session reports one warning per extension
547
+ load naming the file and asking you to remove the key. The extension never
548
+ rewrites the file. Other values remain configuration errors, as do unknown keys
549
+ under `roles`. Registered role packs are the entire package layer, and global and
550
+ project definitions keep their precedence over them.
439
551
 
440
552
  ### Supervision transport
441
553
 
@@ -470,7 +582,8 @@ never interrupts, kills, retries, or restarts a child. It identifies `blocked-to
470
582
  `truncated-turn` (an observed `toolUse` stop with no tool call; its cause is unknown), or
471
583
  `generic-no-progress` when neither condition is established, then
472
584
  includes the session path and manual recovery options. Ordinary children can be
473
- interrupted or, after manual termination, resumed or newly spawned. Persistent
585
+ interrupted, cancelled with `subagent_cancel`, or, after termination, resumed or
586
+ newly spawned. Persistent
474
587
  ordinary-pane specialists can be interrupted or stopped with `subagent_stop` and
475
588
  replaced; they cannot be resumed. Managed-worktree children, including persistent
476
589
  ones, retain their workspace and continue there only after the previous process
@@ -490,11 +603,11 @@ was 4.82 s. The benchmark measures `/proc` CPU ticks for the supervisor and
490
603
  isolated Herdr tree, not parent-model latency; raw samples are written to
491
604
  `/tmp/issue29-bench/` by `test/bench/supervision-bench.mjs`.
492
605
 
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`.
606
+ `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
607
 
495
608
  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
609
 
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.
610
+ 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
611
 
499
612
  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
613
 
@@ -536,12 +649,15 @@ when the extension starts. Run `/reload` after changing it. Package-root
536
649
 
537
650
  ## Spawning Subagents
538
651
 
652
+ Examples that set `agent` assume a role pack or a project/global definition
653
+ supplies that role; this package ships none.
654
+
539
655
  ```typescript
540
656
  // Explicit fast-tier runtime for bounded reconnaissance
541
657
  subagent({ name: "Scout", agent: "scout", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Analyze the codebase..." });
542
658
 
543
659
  // 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..." });
660
+ subagent({ name: "Fix", fork: true, model: "<provider>/<mid-tier-id>", thinking: "medium", task: "Fix the bug where..." });
545
661
 
546
662
  // Explicit frontier-tier runtime for architecture work
547
663
  subagent({ name: "Planner", agent: "planner", model: "<provider>/<frontier-tier-id>", thinking: "high", task: "Work through the design with me" });
@@ -572,12 +688,19 @@ subagent({
572
688
  | `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
689
  | `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
690
  | `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 |
691
+ | `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
692
  | `skills` | string | — | Comma-separated skill names |
577
693
  | `tools` | string | — | Comma-separated tool names |
578
694
  | `cwd` | string | — | Working directory, or source repository when `worktree` is set (see [Role Folders](#role-folders)) |
579
695
  | `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
696
 
697
+ A bare spawn's `systemPrompt` is not passed to Pi as a system prompt. The host
698
+ prepends it as a role block to the child's first message, which is delivered
699
+ through a task artifact file referenced with `@path`. A full-context fork
700
+ (`fork: true`) receives only the raw task, so its `systemPrompt` is dropped. Set
701
+ `fork: false` when a bare child must receive reference or role text through
702
+ `systemPrompt`.
703
+
581
704
  ### Naming coordinated children
582
705
 
583
706
  Before launching a new group, choose a short task slug and label each new child
@@ -591,7 +714,15 @@ prompts, handoffs, and results.
591
714
 
592
715
  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
716
 
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.
717
+ Choose a worktree from the task, not from a role name: the extension emits no
718
+ role-specific worktree warnings. Read-only scouting and review normally use an
719
+ ordinary pane; to inspect or review an existing worker result, start an ordinary
720
+ child in that retained worktree path. Do not infer that a role cannot write
721
+ because its `tools` omit `write` or `edit`: a `read,bash` allowlist is not an
722
+ enforced read-only boundary because shell commands can mutate files. Report-only
723
+ roles must restrict Bash to safe inspection and avoid artifact-generating
724
+ verification in the reviewed checkout. Herdr worktree workspaces persist until
725
+ explicitly removed.
595
726
 
596
727
  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
728
 
@@ -627,27 +758,41 @@ This sends Escape to the child pane, cancelling the in-progress model turn. The
627
758
 
628
759
  `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
760
 
630
- This is a turn-level interrupt, not a method for forcibly terminating a subagent session.
761
+ This is a turn-level interrupt, not a method for forcibly terminating a subagent session. To end the run, use `subagent_cancel`.
631
762
 
632
- ---
763
+ ## Cancelling a running subagent
764
+
765
+ Use `subagent_cancel` to end one ordinary (non-persistent) managed run, including an interrupted one:
766
+
767
+ ```typescript
768
+ subagent_cancel({ id: "abcd1234" });
769
+ // or
770
+ subagent_cancel({ name: "Scout" });
771
+ ```
772
+
773
+ 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.
774
+
775
+ 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:
776
+
777
+ | Status | Meaning |
778
+ | --- | --- |
779
+ | `confirmed` | Termination is confirmed. One cancelled result is delivered automatically. |
780
+ | `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. |
781
+ | `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. |
782
+ | `already-terminal` | The run already took a natural result or was retired; nothing was cancelled. |
633
783
 
634
- ## Orchestrated review skill
784
+ 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.
635
785
 
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.
786
+ Termination follows surface ownership:
644
787
 
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`.
788
+ - **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.
789
+ - **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).
790
+
791
+ 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).
792
+
793
+ 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.
794
+
795
+ ---
651
796
 
652
797
  ## caller_ping — Child-to-Parent Help Request
653
798
 
@@ -689,50 +834,24 @@ await caller_ping({
689
834
 
690
835
  ---
691
836
 
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.
837
+ ## Child-context hint (`PI_SUBAGENT_ID`)
838
+
839
+ Every fresh or resumed child launched by this extension, including `fork: true`
840
+ children and persistent specialists, runs with `PI_SUBAGENT_ID` set to its run
841
+ ID. The extension uses it to register the child protocol tools and to omit
842
+ parent-only surfaces (`worktree_list`, `worktree_remove`,
843
+ `subagents_write_task_models`, and `/subagents-init`). A `/worktree <name>`
844
+ handoff starts an ordinary interactive Pi session and does not set it. Pi's own
845
+ `/fork` and `/clone` run in the same process and keep that process's
846
+ environment: the variable is absent in a top-level session and still present
847
+ inside a child.
848
+
849
+ Role packs may read `PI_SUBAGENT_ID` as a context hint, for example to avoid
850
+ restoring parent-only session state inside a delegated child. It is not an
851
+ authentication or security boundary: any process can set it, and shell commands
852
+ and nested processes a child runs inherit it, including a `pi` process started
853
+ from the child's Bash tool. Do not grant or deny privileges based on it. There
854
+ is no other parent/child protocol.
736
855
 
737
856
  ---
738
857
 
@@ -765,7 +884,6 @@ not disguise a workflow as an agent definition.
765
884
  | Project | `.pi/agents/<name>.md` | The role belongs to one repository |
766
885
  | Global | `$PI_CODING_AGENT_DIR/agents/<name>.md` | The role should be available everywhere; the default root is `~/.pi/agent` |
767
886
  | 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
887
 
770
888
  The filename stem is the launch key. `name` frontmatter is optional because it
771
889
  defaults to the filename stem. If supplied, keep it identical so overrides remain
@@ -886,9 +1004,10 @@ the files, derives package name/version from the nearest `package.json`, and
886
1004
  reports invalid paths, missing descriptions, filename/name mismatches, and
887
1005
  package-layer collisions in the listing surfaces.
888
1006
 
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.
1007
+ Registered role packs form the whole package layer and have no priority over
1008
+ one another: duplicate role names from multiple role packs are disabled with a
1009
+ diagnostic rather than resolved by extension load order. Use a global or
1010
+ project definition for an intentional override.
892
1011
 
893
1012
  See [ADR-0003](docs/adr/0003-installable-role-packs.md) for the registration seam,
894
1013
  collision rules, and rejected alternatives.
@@ -930,7 +1049,7 @@ Compare definitions against the reference below and verify them with
930
1049
  | `session-mode` | string | Default child-session mode: `standalone`, `lineage-only`, or `fork` |
931
1050
  | `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
1051
  | `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). |
1052
+ | `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
1053
  | `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
1054
  | `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
1055
  | `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 +1057,7 @@ Compare definitions against the reference below and verify them with
938
1057
 
939
1058
  ---
940
1059
 
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`.
1060
+ 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
1061
 
943
1062
  ### `session-mode`
944
1063
 
@@ -950,7 +1069,7 @@ Choose how a subagent session starts:
950
1069
 
951
1070
  `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
1071
 
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.
1072
+ `fork: true` on the tool call forces `fork` mode; `fork: false` forces `standalone` mode. Omitting `fork` inherits the agent's frontmatter `session-mode`.
954
1073
 
955
1074
  ```yaml
956
1075
  ---
@@ -972,8 +1091,8 @@ When set to `true`, the agent session shuts down on Pi's `agent_settled` event u
972
1091
 
973
1092
  **When to use:**
974
1093
 
975
- - ✅ Autonomous agents (scout, worker, reviewer) that run to completion
976
- - ❌ Interactive agents (planner, iterate) where the user drives the session
1094
+ - ✅ Autonomous roles, such as scouting, implementation, or review, that run to completion
1095
+ - ❌ Interactive roles or `interactive: true` forks where the user drives the session
977
1096
 
978
1097
  ```yaml
979
1098
  ---
@@ -986,7 +1105,7 @@ auto-exit: true
986
1105
 
987
1106
  Controls whether status transitions (`stalled`, `recovered`) wake the parent session with a steer message.
988
1107
 
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`.
1108
+ **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
1109
 
991
1110
  **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
1111
 
@@ -1016,7 +1135,7 @@ Without a restrictive `tools` allowlist or spawning policy, a sub-agent can spaw
1016
1135
 
1017
1136
  ### `spawning: false`
1018
1137
 
1019
- Denies all subagent lifecycle tools (`subagent`, `subagent_interrupt`, `subagent_send`, `subagent_stop`, `subagents_list`, `subagent_resume`):
1138
+ Denies all subagent lifecycle tools (`subagent`, `subagent_interrupt`, `subagent_cancel`, `subagent_send`, `subagent_stop`, `subagents_list`, `subagent_resume`):
1020
1139
 
1021
1140
  ```yaml
1022
1141
  ---
@@ -1038,15 +1157,13 @@ deny-tools: subagent
1038
1157
 
1039
1158
  ### Recommended Configuration
1040
1159
 
1041
- | Agent | `spawning` | Rationale |
1160
+ | Role shape | `spawning` | Rationale |
1042
1161
  | --- | --- | --- |
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. |
1162
+ | Leaf (scouting, implementation, review, QA) | `false` | Performs one bounded responsibility without delegation. |
1163
+ | 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`. |
1164
+ | Interactive collaborator | *(default)* | May delegate factual gaps while the user drives the session. |
1165
+
1166
+ Each role pack documents the settings of the roles it ships.
1050
1167
 
1051
1168
  ---
1052
1169
 
@@ -1095,6 +1212,36 @@ Every sub-agent session displays a compact one-line tools widget summarizing ava
1095
1212
 
1096
1213
  ## Development
1097
1214
 
1215
+ ### Code map
1216
+
1217
+ The maestro seams remain inside one npm package with the same Pi extension
1218
+ entry point. Pi is the sole real harness and Herdr the sole real surface
1219
+ provider; fakes are for conformance tests only.
1220
+
1221
+ - `pi-extension/subagents/index.ts` — Pi composition root: tools/commands,
1222
+ role-pack event bridge, host policy, widgets, and parent delivery.
1223
+ - `pi-extension/subagents/model-registry.ts`, `config-path.ts` — permanent
1224
+ host-local SDK capability glue and configuration-path conventions.
1225
+ - `maestro/core/` — seam interfaces/types, activity and lifecycle projection,
1226
+ status, routing, wake-ups, and supervision.
1227
+ - `maestro/core/roles/discovery.ts`, `maestro/core/config/` — role discovery,
1228
+ config loaders with injected directories, and task-model init prompt logic.
1229
+ - `maestro/core/worktree.ts`, `maestro/core/worktree-cleanup.ts` — manifest
1230
+ schema/state, handoff types, and cleanup eligibility/formatting.
1231
+ - `maestro/adapters/pi/` — Pi launch, completion, session I/O, activity files,
1232
+ model SDK glue, and registry projection behind `PiHarnessAdapter`;
1233
+ `child/subagent-done.ts` implements the child protocol.
1234
+ - `maestro/surfaces/herdr/` — `HerdrSurfaceProvider`, Herdr CLI driver, and
1235
+ terminal scripts/placement.
1236
+ - `maestro/runtime/` — run ownership, controls/retries, observation,
1237
+ delivery-gated cleanup, Pi composition, worktree operations/handoff, and
1238
+ task-model init composition.
1239
+ - `maestro/adapters/fake/`, `maestro/surfaces/fake/`, `test/maestro/` —
1240
+ conformance fakes, seam tests, and the import dependency-rule test.
1241
+
1242
+ See [ADR-0012](docs/adr/0012-adopt-maestro-seams-in-repo.md), the
1243
+ [glossary](CONTEXT.md), and the [documentation map](docs/README.md).
1244
+
1098
1245
  Run local checks:
1099
1246
 
1100
1247
  ```bash
@@ -1129,4 +1276,4 @@ This package builds on earlier open-source work by [HazAT/pi-interactive-subagen
1129
1276
 
1130
1277
  ## License
1131
1278
 
1132
- MIT. Copyright notice retained from the upstream lineage (`HazAT`).
1279
+ MIT, see [LICENSE](LICENSE). Copyright notice retained from the upstream lineage (`HazAT`).