@narumitw/pi-subagents 0.49.3 → 0.51.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 (81) hide show
  1. package/README.md +313 -53
  2. package/package.json +10 -7
  3. package/src/adaptive-scheduler.ts +196 -0
  4. package/src/admission-benchmark.ts +95 -0
  5. package/src/admission-policy.ts +78 -0
  6. package/src/agent-projection.ts +53 -0
  7. package/src/agents.ts +58 -1
  8. package/src/auto-transport.ts +114 -0
  9. package/src/blocking-status.ts +63 -0
  10. package/src/capabilities.ts +145 -0
  11. package/src/capability-grant.ts +115 -0
  12. package/src/capability-router.ts +107 -0
  13. package/src/completion-delivery.ts +257 -0
  14. package/src/config-status.ts +221 -0
  15. package/src/config-ui.ts +215 -236
  16. package/src/consult-resources.ts +4 -27
  17. package/src/consult.ts +9 -1
  18. package/src/create-stateful-transport.ts +55 -0
  19. package/src/delegation-contract.ts +417 -0
  20. package/src/execution-plan.ts +322 -0
  21. package/src/execution-profiles.ts +95 -0
  22. package/src/execution-ui.ts +320 -0
  23. package/src/execution.ts +848 -158
  24. package/src/in-process-transport.ts +269 -25
  25. package/src/inspect-render.ts +101 -1
  26. package/src/inspect.ts +296 -3
  27. package/src/integration-controller.ts +98 -0
  28. package/src/limits.ts +3 -0
  29. package/src/orchestration-metrics.ts +78 -0
  30. package/src/outcome.ts +61 -0
  31. package/src/panel-child-group.ts +35 -0
  32. package/src/panel-contract.ts +343 -0
  33. package/src/panel-evidence.ts +59 -0
  34. package/src/panel-execution.ts +772 -0
  35. package/src/panel-failure.ts +56 -0
  36. package/src/panel-planning.ts +175 -0
  37. package/src/panel-prompts.ts +132 -0
  38. package/src/panel-reconciliation.ts +57 -0
  39. package/src/panel-render.ts +103 -0
  40. package/src/parallel-limit-ui.ts +112 -0
  41. package/src/params.ts +172 -3
  42. package/src/persistence.ts +182 -32
  43. package/src/prompt-resources.ts +38 -0
  44. package/src/registry-types.ts +175 -0
  45. package/src/registry.ts +466 -143
  46. package/src/render.ts +72 -6
  47. package/src/result-contract.ts +416 -0
  48. package/src/retained-semantic-state.ts +100 -0
  49. package/src/rpc-timeout-finalization.ts +207 -0
  50. package/src/rpc-transport-metadata.ts +65 -0
  51. package/src/rpc-transport.ts +990 -0
  52. package/src/rpc-turn-capture.ts +142 -0
  53. package/src/runner-result.ts +55 -0
  54. package/src/runner-usage.ts +48 -0
  55. package/src/runner.ts +325 -73
  56. package/src/semantic-snapshot.ts +214 -0
  57. package/src/settings.ts +254 -35
  58. package/src/spawn-idempotency.ts +61 -0
  59. package/src/stateful-config.ts +13 -0
  60. package/src/stateful-guidance.ts +1 -0
  61. package/src/stateful-lifecycle.ts +45 -2
  62. package/src/stateful-limit-ui.ts +246 -0
  63. package/src/stateful-limits.ts +96 -0
  64. package/src/stateful-prompt.ts +11 -2
  65. package/src/stateful-render.ts +48 -3
  66. package/src/stateful.ts +467 -357
  67. package/src/subagents.ts +114 -46
  68. package/src/subprocess-transport.ts +64 -5
  69. package/src/supervision.ts +103 -0
  70. package/src/timeout-checkpoint.ts +305 -0
  71. package/src/timeout-finalization.ts +75 -0
  72. package/src/transport-types.ts +68 -0
  73. package/src/transport-ui.ts +169 -0
  74. package/src/transport.ts +16 -4
  75. package/src/turn-budget.ts +109 -0
  76. package/src/verification-policy.ts +17 -0
  77. package/src/work-item-ledger.ts +682 -0
  78. package/src/work-item-persistence.ts +218 -0
  79. package/src/workflow-planning.ts +150 -0
  80. package/src/workflow-ui.ts +61 -0
  81. package/src/workspace.ts +69 -12
package/README.md CHANGED
@@ -12,17 +12,25 @@ Use it to split independent research, planning, implementation, and review work
12
12
  - Adds `subagent_inspect` for bounded metadata without child launch, mailbox-content access, acknowledgement, or mutation.
13
13
  - Adds `subagent_consult` for one synchronous ephemeral child constrained to built-in `read`, `grep`, `find`, and `ls` tools (or a narrower agent allow-list).
14
14
  - Keeps batch workers isolated in `pi --mode json -p --no-session` subprocesses.
15
+ - Lets users set a blocking parallel call's maximum worker count from 1 through 64 while keeping four-at-a-time execution.
15
16
  - Registers detached stateful lifecycle tools by default; completion can stay queued for the next turn or opt into an idle root synthesis turn.
16
17
  - Supports an opt-in public-SDK `in-process` stateful transport with one reusable child `AgentSession` per `agentId`.
18
+ - Supports an opt-in persistent `rpc` transport with one isolated Pi RPC process per active retained agent and `pi-subagents:v1` lifecycle metadata.
19
+ - Supports deterministic opt-in `auto` routing: read-only built-ins use in-process, write-capable built-ins use RPC, and custom tools use the compatibility subprocess path.
17
20
  - Supports built-in `scout`, `planner`, `reviewer`, and `worker` agents.
18
21
  - Loads custom user agents from `~/.pi/agent/agents/*.md`.
19
22
  - Optionally loads project agents from `.pi/agents/*.md` with confirmation.
20
23
  - Provides a current-session-first `/subagents` manager, direct `settings|status|help` routes, and compatibility aliases for agent tools and retained agents.
21
- - Supports trust-aware per-task `cwd` policies, hard subprocess `timeoutMs`, task-selected `thinkingLevel`, abort propagation, and streaming progress.
24
+ - Supports trust-aware per-task `cwd` policies, task-selected work, workflow, idle, turn, and tool-call budgets, deterministic timeout checkpoints, bounded abort-then-summary recovery, progress telemetry, and explicit Fast, Balanced, or Deep thinking profiles.
22
25
  - Renders all seven tools with Pi-native compact/expanded transcript rows; long-running blocking and consultation calls show bounded live activity.
23
26
  - Bounds JSON lines, captured messages, stderr, final output, chain substitution, and fan-in context.
24
27
  - Enforces a recursion-depth guard and deterministic process-group termination.
25
- - Provides addressable stateful agents with follow-up, consolidated mailbox/management actions, context selection, and persistence.
28
+ - Provides addressable stateful agents with follow-up, consolidated mailbox/management actions, idempotent spawn retries, context selection and preview, versioned structured outcomes, and persistence.
29
+ - Publishes built-in and custom agent capability manifests, then records the executor-owned `ExecutionPlan` that resolves requested authority to effective tools, model, thinking, timeout, transport, trust, and workspace controls.
30
+ - Runs explicit dependency workflows through a persistent `WorkItem` ledger, dependency-aware scheduler, declared scope-conflict checks, artifact provenance, stale-result invalidation, and bounded overall deadlines.
31
+ - Runs first-class blocking panels with two or more independent reviewers, incremental bounded evidence artifacts, preserved blockers and dissent, a minimum-valid-review barrier, reserved synthesis and cleanup budgets, and one evidence-preserving synthesis.
32
+ - Supports bounded retries only for explicitly idempotent work and hedged execution only for explicitly read-only work.
33
+ - Detects retained-agent semantic skew across agent definitions, role prompts, tools, model resolution, transport, trust, repository generation, artifacts, and scheduler policy before follow-up work starts.
26
34
  - Publishes transient runtime status through Pi's generic extension status API while subagents are running.
27
35
  - Returns complete bounded worker output in tool details and a concise result for the main agent.
28
36
 
@@ -41,7 +49,7 @@ pi -e npm:@narumitw/pi-subagents
41
49
  Try this package locally from the repository root:
42
50
 
43
51
  ```bash
44
- pi -e ./extensions/pi-subagents
52
+ pi -e ./packages/pi-subagents
45
53
  ```
46
54
 
47
55
  ## 🛠️ Pi tool
@@ -59,7 +67,7 @@ The preview compares the selection with the tools registered in the current sess
59
67
 
60
68
  The available tools are:
61
69
 
62
- - `subagent` — delegate blocking single, parallel, fan-in, or chained batch work. The main agent cannot process queued steering until the call returns.
70
+ - `subagent` — delegate blocking single, parallel, fan-in, chained, panel-review, or explicit dependency-workflow tasks. The main agent cannot process queued steering until the call returns.
63
71
  - `subagent_spawn` and related lifecycle tools — when enabled, start reusable detached work, return immediately, and receive bounded completion messages automatically.
64
72
  - `subagent_inspect` — inspect agent/model/run/runtime metadata without launching work or changing state.
65
73
  - `subagent_consult` — run one ephemeral read-only consultation and wait for its answer.
@@ -102,14 +110,22 @@ Execution modes:
102
110
  - **parallel** — run multiple `{ agent, task }` jobs independently.
103
111
  - **parallel + aggregator** — run parallel jobs, then pass all outputs into one fan-in agent.
104
112
  - **chain** — run sequential steps, passing prior output with `{previous}`.
113
+ - **workflow** — run named tasks only after declared `dependsOn` tasks and required `inputArtifacts` are ready; independent conflict-free tasks may run concurrently.
114
+ - **panel** — run at least two independent reviewers over one shared task and snapshot, then run one synthesizer only when `minValidReviews` valid evidence artifacts remain.
105
115
 
106
116
  Common controls:
107
117
 
108
118
  - `cwd` — choose a launch directory subject to the user-owned trust-aware target policy described below.
109
- - `timeoutMs` — set a hard subprocess timeout.
110
- - `thinkingLevel` — request `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max` thinking for the spawned Pi process or in-process child.
119
+ - `timeoutMs` — choose the per-turn work deadline for the task difficulty.
120
+ - `totalTimeoutMs` — cap an entire blocking single, parallel, chain, panel, or fan-in workflow, including queued work and reserved panel phases.
121
+ - `idleTimeoutMs` — stop work that produces no completed assistant turn or tool result within the selected interval.
122
+ - `maxTurns` / `maxToolCalls` — stop unfinished repeated work after bounded assistant turns or tool calls.
123
+ - `thinkingLevel` — request `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max` thinking for the spawned Pi process or retained child.
124
+ - `idempotencyKey` — make an exact `subagent_spawn` retry return the existing retained `agentId`; reuse with different parameters fails before confirmation, worktree creation, or child launch.
125
+ - `resultFormat` — keep bounded text by default, request legacy `structured-v1`, or request `structured-v2` with explicit outcome status, reason code, claims, artifacts, verification, limitations, and unresolved dependencies.
126
+ - `totalTimeoutMs` — bound a whole explicit blocking workflow; no new task starts after the budget is exhausted.
111
127
 
112
- For `subagent_spawn`, the root agent selects the lowest thinking level sufficient for the delegated task. This is a tool-argument decision made from the task already in context; `pi-subagents` does not run a string heuristic or an extra classifier model call.
128
+ For `subagent_spawn`, the root agent selects the lowest thinking level and shortest realistic work deadline sufficient for the delegated task. These are tool-argument decisions made from the task already in context; `pi-subagents` does not run a string heuristic or an extra classifier model call.
113
129
 
114
130
  ## 🔐 Working-directory trust policy
115
131
 
@@ -122,7 +138,7 @@ The default target policies are:
122
138
  | `cwdPolicy.consultation` | `"anywhere"`, `"current-workspace"` | `"anywhere"`: consultation may start in any existing directory, but a target without effective trust is forced to `resources: "none"` |
123
139
  | `cwdPolicy.delegation` | `"trusted-targets"`, `"current-workspace"`, `"anywhere"` | `"trusted-targets"`: blocking and detached delegation may target the current workspace or an external folder covered by a saved `true` decision |
124
140
 
125
- All paths are resolved relative to the current session workspace and canonicalized before containment and trust checks. Missing paths, non-directories, sibling paths, and symlink escapes cannot bypass the policy. Blocking parallel, chain, and fan-in calls preflight every target before any child starts. A generated `workspaceMode: "worktree"` inherits the resolved trust of its approved base cwd.
141
+ All paths are resolved relative to the current session workspace and canonicalized before containment and trust checks. Missing paths, non-directories, sibling paths, and symlink escapes cannot bypass the policy. Blocking parallel, chain, panel, and fan-in calls preflight every target before any child starts. A generated `workspaceMode: "worktree"` inherits the resolved trust of its approved base cwd.
126
142
 
127
143
  `"anywhere"` for general delegation restores the previous external-target flexibility. An external target without effective trust starts with `projectTrusted: false`, so Pi-protected project settings, packages, extensions, skills, prompts, and system resources stay disabled. General agents still have their configured tools and ordinary Pi/OS permissions, and Pi may still load `AGENTS.md` or `CLAUDE.md` because those context files are not protected by project trust. Resource-free consultation is stricter: it also passes `--no-context-files`, `--no-skills`, `--no-prompt-templates`, `--no-approve`, and `--no-extensions`.
128
144
 
@@ -163,10 +179,9 @@ Count-selection guidance:
163
179
  - Use detached `subagent_spawn` only when lifecycle tools are enabled and a bounded independent task
164
180
  has a concrete isolation or specialization benefit. After spawning, do useful non-overlapping work
165
181
  immediately. Do not poll lifecycle tools for progress or duplicate the delegated work.
166
- - Add another detached agent only for truly independent work with safe workspace concurrency. If
167
- synchronous parallel or fan-in output is genuinely required, keep blocking `subagent` tasks
168
- independent, stay within the hard max of 8, and do not parallelize implementation that may edit
169
- the same files or shared state.
182
+ - Add another detached agent only for truly independent work with safe workspace concurrency.
183
+ If synchronous parallel or fan-in output is genuinely required, keep blocking `subagent` tasks independent, stay within the configured `blocking.maxParallelTasks` limit, and do not parallelize implementation that may edit the same files or shared state.
184
+ The limit defaults to 8, accepts 1 through 64, and bounds total worker tasks in one call rather than the four-at-a-time execution concurrency.
170
185
  - Do not use project-local agents unless the user explicitly opts into them with
171
186
  `agentScope: "project"` or `"both"`; keep confirmation enabled for untrusted repositories.
172
187
 
@@ -218,12 +233,15 @@ A blocking fan-out is reserved for output that must be synthesized before the ro
218
233
  | `list_agents` | Optional `agentScope` (default `user`) and `limit` (default 32, maximum 100) | Bounded agent metadata and omission counts |
219
234
  | `get_agent` | Required `agent`; optional `agentScope` | One resolved definition, safe source path, configured tools, and consultation-effective tools; never the system prompt |
220
235
  | `list_runs` | Optional `includeClosed` and `limit` (default 50, maximum 100) | Metadata-only retained-run summaries and unread counts |
221
- | `get_run` | Required `agentId` | Safe `cwd`, current-task/error summaries, thinking level, policy, history count, and unread count |
236
+ | `get_run` | Required `agentId` | Safe `cwd`, current-task/error summaries, thinking level, context footprint, protocol, effective transport, bounded timing/usage telemetry, structured result when valid, policy, history count, and unread count |
237
+ | `list_workflows` | Optional `limit` (default 50, maximum 100) | Metadata-only persisted blocking-workflow summaries for the current session |
238
+ | `get_workflow` | Required `workflowId` | Bounded task states, generations, dependencies, plan identities, artifact metadata, verification state, and outcome reasons without artifact contents |
222
239
  | `list_models` | Optional `limit` (default 50, maximum 100) | Session-scoped models, or the already-loaded available snapshot |
223
- | `status` | No additional fields | Effective workflow, runtime counts/transport, completion delivery, consultation resources, and configured/runtime cwd policies with per-field sources |
240
+ | `preview_context` | Optional `context` and `contextEntryIds` | Selected mode, user turns, source count, UTF-8 bytes, and truncation without returning context text |
241
+ | `status` | No additional fields | Effective workflow, runtime counts/transport, detached limit values, completion delivery, consultation resources, and configured/runtime settings with per-field sources |
224
242
  | `diagnose` | No additional fields | Structured `pass`, `warning`, and `fail` checks; failed checks are report data rather than a tool error |
225
243
 
226
- The schema rejects fields that do not belong to the selected action. Explicit `project` or `both` scope fails before project-agent discovery unless Pi already trusts the project. Run inspection never returns history output, stored context, or mailbox content; unread counts come from a metadata-only snapshot and do not acknowledge messages. Paths beneath the Pi agent directory use `~`, project paths are workspace-relative, model objects are projected through an allow-list, and model-facing text is bounded to 50 KiB or 2,000 lines.
244
+ The schema rejects fields that do not belong to the selected action. Explicit `project` or `both` scope fails before project-agent discovery unless Pi already trusts the project. Run inspection never returns history output, stored context, or mailbox content; unread counts come from a metadata-only snapshot and do not acknowledge messages. Workflow inspection reads validated, redacted snapshots without quarantining or rewriting invalid files. Paths beneath the Pi agent directory use `~`, project paths are workspace-relative, model objects are projected through an allow-list, and model-facing text is bounded to 50 KiB or 2,000 lines.
227
245
 
228
246
  Compatibility: `subagent_manage({ "action": "list" })` remains supported with its existing behavior. Prefer `subagent_inspect` when a whole tool must be safe to activate on a read-only surface.
229
247
 
@@ -261,7 +279,7 @@ Extensions remain disabled for all three values. Pi core owns system-prompt sour
261
279
 
262
280
  Both settings are user-owned in `~/.pi/agent/pi-subagents.json`; projects cannot override them. `cwdPolicy.consultation: "current-workspace"` rejects every canonical external target before agent discovery or launch even when that target is saved-trusted. This is not a path sandbox: read-only tools can still read an explicitly requested accessible absolute path.
263
281
 
264
- Result details report the canonical safe cwd, current/external boundary, bounded target-trust decision/source/warning, requested and effective tools/resources, downgrade reason, agent/model/thinking/timeout metadata, and the facts that extensions, session persistence, and retained-agent state are disabled. They never dump prompt contents or the full trust store. Nested model usage is returned through Pi's usage field, so footer, `/session`, and RPC totals include consultation cost. Validation, disallowed targets, and launch failures throw. Failures after model launch preserve bounded partial evidence and usage while the finalized Pi tool result is marked as an error. Abort, timeout, session replacement, and shutdown use the existing process-tree termination and temporary-file cleanup path.
282
+ Result details report the canonical safe cwd, current/external boundary, bounded target-trust decision/source/warning, requested and effective tools/resources, downgrade reason, agent/model/thinking/timeout metadata, and the facts that extensions, session persistence, and retained-agent state are disabled. They never dump prompt contents or the full trust store. Nested model usage is returned through Pi's usage field, so footer, `/session`, and RPC totals include consultation cost. Validation, disallowed targets, and launch failures throw. Failures after model launch preserve bounded partial evidence and usage while the finalized Pi tool result is marked as an error. Explicit abort, session replacement, and shutdown use the existing process-tree termination and temporary-file cleanup path; a work timeout additionally makes one separately bounded, tool-less summary attempt after abort.
265
283
 
266
284
  ## 🚀 Blocking batch examples
267
285
 
@@ -334,6 +352,73 @@ Run a chain where each step receives the previous output:
334
352
  }
335
353
  ```
336
354
 
355
+ Run an evidence-preserving panel:
356
+
357
+ ```json
358
+ {
359
+ "panel": {
360
+ "id": "auth-panel",
361
+ "preset": "code-review",
362
+ "task": "Review the authentication change for correctness and regressions.",
363
+ "context": "Inspect the current repository snapshot and existing test evidence.",
364
+ "reviewers": [
365
+ { "id": "correctness", "agent": "reviewer", "focus": "Control flow and edge cases" },
366
+ { "id": "tests", "agent": "reviewer", "focus": "Coverage and regression risk" }
367
+ ],
368
+ "synthesizer": { "agent": "reviewer" },
369
+ "minValidReviews": 2
370
+ },
371
+ "totalTimeoutMs": 120000
372
+ }
373
+ ```
374
+
375
+ Every reviewer receives the same shared task, context, target snapshot, and scope, but never receives sibling output.
376
+ Reviewer-specific `focus` text is appended after the shared block.
377
+ The executor accepts only strict `pi-subagents:panel-review:v1` artifacts, stamps reviewer provenance, and starts synthesis only after the valid-review barrier.
378
+ Agreement is corroboration rather than proof, and a vote cannot clear a correctness, safety, security, or explicit-requirement blocker.
379
+ If too few valid reviews remain, the tool returns `insufficient-panel` with bounded partial evidence and failure classes without running synthesis or claiming consensus.
380
+ Review, evidence-finalization, synthesis, and cleanup receive explicit phase allocations, and reviewer work cannot consume the synthesis or cleanup reserve.
381
+ Only transient launch or transport failures receive one bounded retry; invalid contracts, semantic stalls, permission failures, exhausted budgets, cancellation, and deterministic task failures do not.
382
+ Read-only reviewers share the approved target, while conservatively write-capable reviewers receive separate disposable Git worktrees from one clean base.
383
+ Worktrees isolate repository writes but do not isolate processes, the network, secrets, credentials, or the rest of the filesystem.
384
+ The blocking panel owns every reviewer, synthesizer, timer, generation, transport, and worktree and closes them when the call settles or Pi emits graceful session replacement or shutdown.
385
+ An uncatchable host kill or forced process termination cannot guarantee cleanup; inspect `git worktree list`, remove any confirmed generated `pi-subagent-worktree-*` entry, and run `git worktree prune` if the host terminated before Pi dispatched lifecycle cleanup.
386
+ Panel WorkItem snapshots persist metadata and artifact references for current-session inspection without storing raw review bodies.
387
+
388
+ Run an explicit dependency workflow:
389
+
390
+ ```json
391
+ {
392
+ "workflow": {
393
+ "id": "auth-review",
394
+ "tasks": [
395
+ {
396
+ "id": "inventory",
397
+ "agent": "scout",
398
+ "task": "Produce the auth inventory artifact.",
399
+ "resultFormat": "structured-v2",
400
+ "readPaths": ["src/auth"]
401
+ },
402
+ {
403
+ "id": "review",
404
+ "agent": "reviewer",
405
+ "task": "Review the inventory and report verification evidence.",
406
+ "dependsOn": ["inventory"],
407
+ "inputArtifacts": ["auth-inventory"],
408
+ "resultFormat": "structured-v2"
409
+ }
410
+ ]
411
+ },
412
+ "totalTimeoutMs": 120000
413
+ }
414
+ ```
415
+
416
+ Cycles, missing dependencies, conflicting integration owners, recursive workflow grandchildren, and unsafe retry or hedge policies fail before child launch.
417
+ Workflow scheduling starts at most two mutating tasks concurrently, while declared read-only work may use the existing four-child ceiling.
418
+ Set `workflow.honorAdmission: true` only when explicit contract admission metadata should be allowed to decline parent-owned or insufficient-evidence work before launch; admission never silently widens the requested architecture.
419
+ Workflow result details include the final ledger, scheduling decisions, artifact versions, task generations, attempts, hedge use, accepted plan identity, and bounded capability-grant metadata.
420
+ Explicit workflow transitions are also atomically persisted as mode-0600, private-text-redacted snapshots for current-session `list_workflows` and `get_workflow` inspection; in-flight tasks inspect as `interrupted`, and no prior side effect is automatically resumed.
421
+
337
422
  ## 🔁 Stateful agents
338
423
 
339
424
  Stateful lifecycle tools are available by default. `subagent_spawn` is detached: it schedules work, returns immediately with an opaque `agentId`, and later injects a bounded `pi-subagent-completion` custom message. Completions that settle in the same dispatch window are batched, and the broker allows at most one in-flight root wake until that parent turn starts.
@@ -349,24 +434,35 @@ A detached agent additionally needs a concrete isolation or specialization benef
349
434
 
350
435
  Auto-resume is best-effort because Pi's custom-message API is fire-and-forget. Session-generation checks, shutdown cleanup, batching, and the in-flight wake guard prevent stale or duplicate scheduling pressure, but they do not make completion delivery durable across process exit.
351
436
 
352
- The default `subprocess` transport preserves compatibility: each turn starts a fresh isolated `pi --mode json -p --no-session` child and receives sanitized, bounded history. Set `transport` to `in-process` to retain one public Pi SDK `AgentSession` per stateful `agentId`, avoiding repeated process startup while preserving native child history in memory.
353
-
354
- Run `/subagents` in TUI mode to open the standard primary manager. It leads with the current
355
- delegation workflow, human-readable async completion behavior, consultation/delegation target policies, consultation-resource policy, and active/retained counts. **Change delegation**, **Current agents**, and **Settings** cover the common workflows; agent permissions, transport/runtime details, source, and settings path remain under **Advanced settings**.
356
- Escape returns from a nested screen to a newly refreshed manager; Ctrl+C closes the full flow.
357
- Exact workflow/reload and project-agent safety confirmations remain extension-owned because they
358
- guard live agent and trust-boundary policy rather than ordinary navigation.
437
+ The default `subprocess` transport preserves compatibility: each turn starts a fresh isolated `pi --mode json -p --no-session` child and receives sanitized, bounded history.
438
+ Set `transport` to `in-process` to retain one public Pi SDK `AgentSession` per stateful `agentId`, avoiding repeated process startup while preserving native child history in memory.
439
+ Set it to `rpc` to retain one `pi --mode rpc --no-session --no-extensions` process per active retained agent, preserving native child history with a separate process boundary.
440
+ Set it to `auto` for deterministic preflight selection: read-only built-in tools use in-process, write-capable built-in tools use RPC, and extension/custom tools use subprocess.
441
+ Automatic selection never falls back after child creation or prompt acceptance.
442
+
443
+ Run `/subagents` in TUI mode to open the standard primary manager.
444
+ It leads with the current delegation workflow, human-readable async completion behavior, consultation/delegation target policies, consultation-resource policy, parallel-worker limit, and active/retained counts.
445
+ **Change delegation**, **Current agents**, and **Settings** cover the common workflows.
446
+ Agent permissions, **Maximum parallel workers**, **Detached agent limits**, **Performance and execution**, transport/runtime details, source, and settings path remain under **Advanced settings**.
447
+ **Performance and execution** provides responsiveness guidance, transport previews, Fast/Balanced/Deep thinking profiles, and per-agent model/thinking/timeout defaults.
448
+ Profiles are explicit atomic thinking patches, preserve model/tool/timeout/context settings, never select `max`, and can be customized afterward.
449
+ The parallel-worker input rejects invalid values without discarding the draft and applies a successful save immediately.
450
+ The detached-limit screen edits retained capacity, active-turn concurrency, direct children, tree depth, and stored-record capacity.
451
+ Detached-limit saves are durable immediately but apply to the runtime after `/reload` or the next Pi session.
452
+ Escape returns from a nested screen to a newly refreshed manager, while Ctrl+C closes the full flow.
453
+ Exact workflow/reload and project-agent safety confirmations remain extension-owned because they guard live agent and trust-boundary policy rather than ordinary navigation.
359
454
 
360
455
  The direct routes remain predictable: `/subagents settings` changes both target policies, consultation resources, and completion delivery and applies them immediately, including refreshing model-facing tool guidance; `/subagents status` reports current-session runtime values separately from configured values, per-field sources, and path; `/subagents help` summarizes the single-command interface and the non-sandbox limitation. In RPC mode, bare `/subagents` emits the same bounded status through Pi's notification protocol instead of opening a custom TUI. JSON and print modes do not emit ad hoc command output. Manual edits use `~/.pi/agent/pi-subagents.json` and take effect after reloading Pi:
361
456
 
362
457
  ```json
363
458
  {
364
459
  "blocking": {
365
- "enabled": false
460
+ "enabled": false,
461
+ "maxParallelTasks": 8
366
462
  },
367
463
  "stateful": {
368
464
  "enabled": true,
369
- "transport": "in-process",
465
+ "transport": "auto",
370
466
  "completionDelivery": "auto-resume",
371
467
  "maxAgents": 16,
372
468
  "maxActiveTurns": 4,
@@ -388,12 +484,31 @@ The direct routes remain predictable: `/subagents settings` changes both target
388
484
  }
389
485
  ```
390
486
 
391
- The settings UI patches the raw JSON atomically and preserves unknown fields; it refuses to overwrite malformed or invalid settings. Supported Pi writers serialize the latest-document read and same-directory temporary-file rename through `pi-subagents.json.mutation-lock`. Editors and older extension versions do not participate in that lock, so avoid manual edits while a settings save is in progress. `blocking.enabled` defaults to `true`; set it to `false` for async-only delegation. `stateful.enabled` also defaults to `true`; its existing `false` value remains the blocking-only workflow. `cwdPolicy.consultation` defaults to `"anywhere"`, `cwdPolicy.delegation` defaults to `"trusted-targets"`, and `consult.resources` defaults to `"project-context"`. The Settings UI applies a saved change immediately to subsequent launches and refreshes the affected tool descriptions; manual edits take effect on session start or `/reload`. The UI explicitly states that target/trust settings are not filesystem sandboxing and directs trust changes to Pi `/trust`. When stateful tools are enabled, their membership stays fixed across spawn, completion, interrupt, close, and mailbox transitions. This avoids lifecycle-driven tool-schema churn and preserves a stable provider prompt prefix for KV caching.
487
+ The settings UI patches the raw JSON atomically and preserves unknown fields.
488
+ It refuses to overwrite malformed or invalid settings.
489
+ Supported Pi writers serialize the latest-document read and same-directory temporary-file rename through `pi-subagents.json.mutation-lock`.
490
+ Editors and older extension versions do not participate in that lock, so avoid manual edits while a settings save is in progress.
491
+ `blocking.enabled` defaults to `true`; set it to `false` for async-only delegation.
492
+ `blocking.maxParallelTasks` defaults to `8` and accepts positive integers from `1` through `64`.
493
+ It limits worker tasks in one blocking parallel call, while execution still starts at most four workers at once and treats an optional aggregator separately.
494
+ `stateful.enabled` also defaults to `true`; its existing `false` value remains the blocking-only workflow.
495
+ The detached defaults are `maxAgents: 16`, `maxActiveTurns: 4`, `maxChildrenPerAgent: 8`, `maxDepth: 3`, and `maxStoredAgents: 50`.
496
+ `maxDepth` accepts zero or a positive safe integer, while the other four detached limits accept positive safe integers.
497
+ Use `/subagents` → **Advanced settings** → **Detached agent limits** to edit them without replacing unknown JSON fields.
498
+ The screen shows current-session and configured values separately because changes apply after `/reload`.
499
+ It never reloads automatically, because reload can interrupt retained detached work.
500
+ Lowering retained, depth, or stored capacity shows a projected recovery warning when current records would be omitted.
501
+ Restored parents that already exceed a lowered `maxChildrenPerAgent` remain available, but they cannot gain another child until they fall below the configured limit.
502
+ `cwdPolicy.consultation` defaults to `"anywhere"`, `cwdPolicy.delegation` defaults to `"trusted-targets"`, and `consult.resources` defaults to `"project-context"`.
503
+ The Settings UI applies a saved change immediately to subsequent launches and refreshes the affected tool descriptions; manual edits take effect on session start or `/reload`.
504
+ The UI explicitly states that target/trust settings are not filesystem sandboxing and directs trust changes to Pi `/trust`.
505
+ When stateful tools are enabled, their membership stays fixed across spawn, completion, interrupt, close, and mailbox transitions.
506
+ This avoids lifecycle-driven tool-schema churn and preserves a stable provider prompt prefix for KV caching.
392
507
 
393
508
  | Tool | Purpose |
394
509
  | --- | --- |
395
- | `subagent_spawn` | Start detached work with an optional task-selected thinking level, return an opaque `agentId` immediately, and deliver completion asynchronously. |
396
- | `subagent_send` | Send follow-up work and trigger a new turn on a reusable agent; shared-workspace write conflicts are guarded unless explicitly overridden. |
510
+ | `subagent_spawn` | Start detached work with optional task-selected thinking and retained timeout, exact-retry `idempotencyKey`, and `text`, `structured-v1`, or `structured-v2` result format; return an opaque `agentId` immediately and deliver completion asynchronously. |
511
+ | `subagent_send` | Send follow-up work with an optional one-turn timeout override and trigger a new turn on a reusable agent; semantic skew requires explicit `revalidate: true`, and shared-workspace write conflicts are guarded unless explicitly overridden. |
397
512
  | `subagent_manage` | Use `action: "list"` to inspect agents, `"interrupt"` to retain an agent after aborting active work, or `"close"` to release it; interrupt/close accept optional `subtree`. |
398
513
  | `subagent_mailbox` | Use `action: "send"` for queue-only messages that do not start a turn, or `"read"` to read and optionally acknowledge unread messages. |
399
514
 
@@ -415,7 +530,12 @@ The action schemas are flat for provider compatibility and reject parameters tha
415
530
  }
416
531
  ```
417
532
 
418
- Use the **Current agents** action in `/subagents` to inspect the indented agent tree, lifecycle state, unread count, and available actions, or to confirm clearing retained agents. Active turns are FIFO-limited by `maxActiveTurns`; excess retained work remains in `starting` state until a slot is available. `maxAgents` separately bounds running, queued, and idle records. `parentId` creates a bounded child relationship; subtree interrupt and close operate child-first.
533
+ Use the **Current agents** action in `/subagents` to inspect the indented agent tree, lifecycle state, unread count, and available actions, or to confirm clearing retained agents.
534
+ Active turns are FIFO-limited by `maxActiveTurns`; excess retained work remains in `starting` state until a slot is available.
535
+ `maxAgents` separately bounds running, queued, and idle records.
536
+ `maxChildrenPerAgent` bounds direct children, while `maxDepth` counts nested levels below a depth-zero root.
537
+ `maxStoredAgents` bounds sanitized records persisted per session and does not increase live runtime capacity.
538
+ `parentId` creates a bounded child relationship; subtree interrupt and close operate child-first.
419
539
 
420
540
  ### Migrating from the previous seven-tool lifecycle surface
421
541
 
@@ -441,7 +561,26 @@ A spawn can request a thinking level explicitly:
441
561
  }
442
562
  ```
443
563
 
444
- The requested level is stored with the stateful agent and remains in effect for all follow-ups and after persisted restore. `subagent_send` does not provide a per-turn thinking override; create a new agent when a later task needs a different level.
564
+ The requested level and spawn `timeoutMs`, `idleTimeoutMs`, `maxTurns`, and `maxToolCalls` are stored with the stateful agent and remain in effect for all follow-ups and after persisted restore. The same fields on `subagent_send` override only that follow-up turn. `subagent_send` does not provide a per-turn thinking override; create a new agent when a later task needs a different level.
565
+
566
+ An exact retry can use a bounded session-owned idempotency key:
567
+
568
+ ```json
569
+ {
570
+ "agent": "worker",
571
+ "task": "Implement the approved change",
572
+ "idempotencyKey": "approved-change-1"
573
+ }
574
+ ```
575
+
576
+ The same key and canonical request returns the existing retained `agentId` without another confirmation, worktree, or child.
577
+ Reusing the key with different behavior-affecting parameters fails.
578
+ Closing the retained record releases the key.
579
+
580
+ Set `resultFormat: "structured-v1"` to ask for legacy `summary`, `evidence`, `changes`, `verification`, and `risks` fields.
581
+ Prefer `resultFormat: "structured-v2"` when orchestration must distinguish `completed`, `partial`, `blocked`, `needs-input`, `failed`, `interrupted`, `abstained`, `stale`, or `contract-invalid` outcomes and consume typed artifact evidence.
582
+ Valid structured data and deterministic recovery classification appear in completion and inspection details, while malformed structured output becomes `contract-invalid` instead of being treated as success.
583
+ The executor stamps task generation, cancellation lineage, and accepted `ExecutionPlan` identity after parsing, so model output cannot forge the provenance used for stale-result containment.
445
584
 
446
585
  `subagent_spawn.context` accepts:
447
586
 
@@ -450,21 +589,31 @@ The requested level is stored with the stateful agent and remains in effect for
450
589
  - `"summary"` — a bounded earlier-context checkpoint plus recent messages verbatim.
451
590
  - A positive number — the most recent N user turns and related assistant text.
452
591
 
453
- Use `contextEntryIds` to select exact session entries. Supplying IDs without `context` implies `context: "all"`; an explicit `context: "none"` still disables parent context. Stable source IDs are retained so repeated follow-ups do not need to duplicate parent context.
592
+ Use `contextEntryIds` to select exact session entries.
593
+ Supplying IDs without `context` implies `context: "all"`; an explicit `context: "none"` still disables parent context.
594
+ Stable source IDs are retained so repeated follow-ups do not need to duplicate parent context.
595
+ Use `subagent_inspect` with `action: "preview_context"` to inspect selected turns, source count, UTF-8 bytes, and truncation before spawning without returning the context text.
596
+ The byte count is not a provider token estimate.
454
597
 
455
598
  Reasoning, tool results, custom transport messages, and non-text parts are excluded. Text inside `<private>...</private>` and lines containing `[subagent-private]` are omitted before context, mailbox content, or history is persisted.
456
599
 
457
600
  Stateful execution uses a transport boundary:
458
601
 
459
- - `subprocess` is the default compatibility and rollback path.
602
+ - `subprocess` is the default compatibility and rollback path and starts a fresh child for every turn.
460
603
  - `in-process` uses only public Pi SDK APIs: `createAgentSessionServices()`, `createAgentSessionFromServices()`, `SessionManager.inMemory()`, and normal session lifecycle methods. It isolates conversation/tool selection, not memory or crashes; child failures share the parent Node.js process.
461
- - Child resource loading sets `noExtensions: true`, preventing recursive `pi-subagents` loading and duplicate extension side effects while retaining trust-eligible context/skill resources and the selected agent prompt. Both transports receive the same resolved target-trust boolean: subprocess children get explicit `--approve`/`--no-approve`, and in-process children set the same `SettingsManager.projectTrusted` value.
604
+ - `rpc` uses strict bounded JSONL over one lazy child process per active retained agent. A `get_state` response proves readiness, prompt response means accepted only, and `agent_settled` is the completion boundary after retry or compaction.
605
+ - `auto` selects one transport before launch and retains the choice for that agent's runtime lifetime. It never retries through another transport after startup or accepted work.
606
+ - In-process and RPC child resource loading disables extensions to prevent recursive `pi-subagents` loading and duplicate extension side effects while retaining trust-eligible context/skill resources and the selected agent prompt. The compatibility subprocess path retains its recursion-depth guard and configured tool behavior. Transports receive the same resolved target-trust boolean through their public SDK or explicit CLI trust controls.
462
607
  - Agent model strings use Pi core's CLI resolver, including provider/model patterns, fuzzy matching, custom provider model IDs, and `:<thinking>` suffixes. Thinking level and built-in tool allow-list overrides are applied when the child is created. Parent model/thinking changes are snapshotted for subsequently created children; an existing child keeps its own session configuration.
463
- - Extension/custom tool names are rejected in-process with an actionable recommendation to use `subprocess`; permissions are never silently widened.
464
- - Timeout, parent abort, close, expiry, and session shutdown abort/dispose owned child sessions. A child that does not settle after abort grace is discarded rather than reused.
608
+ - Extension/custom tool names are rejected by in-process and RPC v1 before child creation; automatic mode selects `subprocess` for them, and permissions are never silently widened.
609
+ - Timeout, parent abort, close, expiry, and session shutdown abort/dispose owned child sessions or process groups. A child that does not settle after abort grace is discarded rather than reused.
610
+ - RPC progress uses `pi-subagents:v1` metadata and reports only bounded phase, queue, timing, effective model/thinking, and validated usage fields; it never exposes raw prompts, reasoning, credentials, environment values, or full RPC events.
611
+ - A successful RPC prompt response is never treated as completion, and accepted or ambiguously accepted work is never replayed automatically.
465
612
  - In-process startup failures do not silently retry through subprocesses, preventing duplicate side effects. If the loaded Pi core lacks public `createAgentSessionServices()`, `createAgentSessionFromServices()`, or `resolveCliModel()` support, startup fails with an actionable instruction to select `stateful.transport: "subprocess"`.
466
613
 
467
- No private Pi imports, runtime casts, or `ExtensionAPI` monkey-patching are used. Approval policy, sandbox profile, provider-header hooks, extension state, global scheduling, and parent/child transcript switching are not inherited or provided by the in-process transport.
614
+ No private Pi imports, runtime casts, or `ExtensionAPI` monkey-patching are used.
615
+ The package uses public Pi root RPC types but owns exact CLI resolution, bounded framing, readiness, stderr, cancellation, and process-group cleanup because the stock client does not provide those package-specific guarantees.
616
+ Approval policy, sandbox profile, provider-header hooks, extension state, global scheduling, and parent/child transcript switching are not inherited or provided by in-process or RPC transport.
468
617
 
469
618
  Write-capable agents share the workspace by default. Concurrent write-capable starts in the same cwd are rejected unless `allowConcurrentWrites` is explicitly set. Classification is intentionally conservative: an agent with `bash`, `write`, or `edit` is write-capable even when its task prompt says “read only,” because prompt wording is not a filesystem sandbox. Prefer one detached agent when asynchronous work can be combined. If concurrent work is genuinely required, use the blocking batch only when synchronous outputs justify making the root unavailable, explicitly accept safe detached overlap with `allowConcurrentWrites`, or use isolated worktrees when repository isolation is needed.
470
619
 
@@ -472,19 +621,26 @@ Set `workspaceMode: "worktree"` to opt into a disposable detached Git worktree;
472
621
 
473
622
  ## 📜 Compatibility and failure contract
474
623
 
475
- Existing `subagent` input schemas remain unchanged. The intentional compatibility change is that an external target without saved trust is rejected by the new default `cwdPolicy.delegation: "trusted-targets"`; set the user-owned policy to `"anywhere"` to restore the preceding target flexibility.
624
+ Existing accepted `subagent` payload shapes remain unchanged.
625
+ `subagent_spawn` adds optional `idempotencyKey` and `resultFormat` fields without changing omitted behavior.
626
+ Older releases do not recognize `stateful.transport: "rpc"` or `"auto"`; change the value to `"subprocess"` and reload before downgrading.
627
+ Retained records remain transport-neutral, and older readers ignore the additive idempotency and context-footprint fields while the state version remains compatible.
628
+ The `tasks` schema now advertises the absolute 64-item safety bound, while the effective `blocking.maxParallelTasks` value may be lower.
629
+ The intentional compatibility change is that an external target without saved trust is rejected by the new default `cwdPolicy.delegation: "trusted-targets"`; set the user-owned policy to `"anywhere"` to restore the preceding target flexibility.
476
630
 
477
631
  | Mode | Ordering | Failure behavior |
478
632
  | --- | --- | --- |
479
633
  | Single | One result. | A failed/aborted/timed-out worker is marked as a tool error while preserving bounded details. |
480
634
  | Chain | Input order. | Stops at the first failed step; completed steps remain in details. |
481
- | Parallel | Input order, with at most four active children. | Collects all task results; partial worker failure is reported in summaries but does not discard successful results. |
482
- | Parallel + aggregator | Source input order, then aggregator. | The aggregator runs with both successful outputs and failure descriptions; aggregator failure marks the tool result as an error. |
635
+ | Parallel | Input order, up to `blocking.maxParallelTasks` total workers and at most four active children. | Rejects calls above the configured limit; otherwise collects all task results, and partial worker failure does not discard successful results. |
636
+ | Parallel + aggregator | Source input order, then aggregator. | The aggregator runs with successful outputs and failure descriptions only when total budget remains; aggregator failure or orchestration expiry marks the tool result as an error. |
637
+ | Workflow | Deterministic dependency-ready and critical-path order, with results returned in declared task order. | Invalid graphs fail before launch; blocked or failed dependencies prevent downstream start; bounded retry and hedging require explicit side-effect contracts. |
638
+ | Panel | Reviewer declaration order, then at most one synthesizer. | Invalid or failed reviews remain visible; synthesis requires `minValidReviews`; insufficient panels preserve partial evidence without a consensus claim; synthesis contract failure marks the tool result as an error. |
483
639
 
484
640
  An aggregator whose `agent` or `task` is empty or whitespace-only is treated as absent, so successful
485
641
  parallel outputs remain available instead of being replaced by a malformed fan-in failure.
486
642
 
487
- Timeout precedence remains: task/step/aggregator → call → agent setting → `PI_SUBAGENT_TIMEOUT_MS` → 600000 ms. Blocking thinking precedence remains: task/step/aggregator → call → agent setting → child default. Stateful spawn thinking precedence is: `subagent_spawn.thinkingLevel` → agent setting → transport fallback. Project-agent resolution and confirmation behavior is unchanged after target preflight. Blocking and retained result/inspection details add bounded target boundary and effective trust metadata.
643
+ Blocking work-timeout precedence remains: task/step/aggregator → call → agent setting → `PI_SUBAGENT_TIMEOUT_MS` → 600000 ms, then `totalTimeoutMs` caps the effective remaining time. Blocking idle, turn, and tool-call precedence is task/step/aggregator → call → omitted. Stateful budget precedence is the explicit `subagent_send` field for one follow-up → retained `subagent_spawn` field → timeout-only agent/environment fallback where applicable. Blocking thinking precedence remains: task/step/aggregator → call → agent setting → child default. Stateful spawn thinking precedence is: `subagent_spawn.thinkingLevel` → agent setting → transport fallback. Project-agent resolution and confirmation behavior is unchanged after target preflight. Blocking and retained result/inspection details add bounded target, budget, termination, and effective trust metadata.
488
644
 
489
645
  ## 🤖 Built-in agents
490
646
 
@@ -500,12 +656,24 @@ Built-in agents are available without setup and can be overridden by user or pro
500
656
 
501
657
  The built-in `reviewer` does not run tests, builds, benchmarks, or formatters. It recommends additional verification commands for the main agent to run instead. Custom agents can override this behavior.
502
658
 
503
- Built-in agents inherit the active/default Pi model instead of forcing a provider-specific model alias, which keeps subprocesses usable across different Pi setups.
659
+ Built-in agents inherit the active/default Pi model instead of forcing a provider-specific model alias, which keeps every transport usable across different Pi setups.
660
+ Built-ins also have no fixed thinking override until a caller, frontmatter, per-agent setting, or execution profile selects one.
661
+
662
+ The optional profiles apply these provider-neutral thinking defaults:
663
+
664
+ | Profile | `scout` | `planner` | `reviewer` | `worker` and aliases |
665
+ | --- | --- | --- | --- | --- |
666
+ | Fast | `low` | `low` | `medium` | `low` |
667
+ | Balanced | `low` | `medium` | `medium` | `medium` |
668
+ | Deep | `medium` | `high` | `high` | `high` |
669
+
670
+ Profiles preserve model, timeout, tools, transport, completion delivery, and parent-context behavior.
504
671
 
505
672
  ## ⚙️ Configure agent tools
506
673
 
507
674
  Open `/subagents`, choose **Advanced settings**, then **Agent tool permissions** in an interactive
508
- Pi session to edit the tools each subagent may use. The standard bounded multi-select keeps a
675
+ Pi session to edit the tools each subagent may use.
676
+ Choose **Performance and execution** → **Agent execution defaults** to edit provider-neutral inherited model patterns, thinking levels, and timeouts without changing tools. The standard bounded multi-select keeps a
509
677
  one-save draft: toggles do not write until **Save changes**, Escape leaves the draft without writing,
510
678
  and unavailable configured tool names remain visible and preserved. In TUI mode, type to fuzzy-search
511
679
  tool names and availability metadata; Save and Discard remain pinned below the matches. These are user
@@ -538,6 +706,17 @@ description: Review API changes for compatibility and tests
538
706
  tools: read, grep, find, ls, bash
539
707
  model: sonnet
540
708
  thinkingLevel: high
709
+ capabilityManifest:
710
+ version: pi-subagents:capabilities:v1
711
+ capabilities: [code-review, evidence-review]
712
+ modalities: [text]
713
+ resultFormats: [text, structured-v2]
714
+ authority:
715
+ filesystem: read
716
+ verificationRoles: [independent-review]
717
+ contextStrengths: [repository]
718
+ costHint: medium
719
+ latencyHint: medium
541
720
  ---
542
721
 
543
722
  You are an API review subagent. Do not edit files. Check compatibility,
@@ -546,6 +725,10 @@ test coverage, and migration risks. Report PASS/FAIL/PARTIAL with evidence.
546
725
 
547
726
  `tools` accepts either the comma-separated form above or a YAML string array such as `tools: [read, grep]`. An omitted field keeps the agent's default tools; blank, `null`, or `[]` explicitly selects no tools.
548
727
 
728
+ `capabilityManifest` is optional for legacy custom agents and never grants authority by itself.
729
+ Explicit workflow routing can match declared capabilities, configured tools, filesystem authority, verification roles, and low/medium/high cost or latency hints.
730
+ A missing or malformed manifest remains unknown and cannot satisfy a capability-routed task.
731
+
549
732
  `agentScope` is a top-level tool argument supplied per invocation. It is not a setting in
550
733
  `~/.pi/agent/pi-subagents.json` and does not belong in agent frontmatter. The parent-facing tool
551
734
  metadata discovers these definitions after session start and labels their source and required scope.
@@ -588,12 +771,21 @@ argument skips that confirmation dialog, but it does not bypass the project trus
588
771
 
589
772
  ## ⏱️ Runtime limits and thinking levels
590
773
 
591
- Each subprocess has a hard timeout to avoid runaway workers.
774
+ Every turn can combine main-agent-selected wall-clock, idle, assistant-turn, and tool-call budgets with an extension-owned hard-bounded finalization deadline.
592
775
 
593
- - Set `timeoutMs` on the top-level call to apply a default for all jobs.
776
+ - Set `blocking.maxParallelTasks` in `~/.pi/agent/pi-subagents.json`, or use `/subagents` → **Advanced settings** → **Maximum parallel workers**, to allow 1 through 64 worker tasks in one blocking parallel call.
777
+ - The worker-count limit defaults to 8 and does not change the fixed four-at-a-time execution concurrency.
778
+ - Set `timeoutMs` on the top-level blocking call to apply a work deadline to all jobs.
594
779
  - Set `timeoutMs` on a task, chain step, or aggregator to override it locally.
595
- - Valid timeout values range from 1 to 2,147,483,647 milliseconds, matching the runtime timer limit.
596
- - If omitted, the default is `PI_SUBAGENT_TIMEOUT_MS`, or `600000` milliseconds (10 minutes) when unset.
780
+ - Set top-level blocking `totalTimeoutMs` to cap model work across the whole call; each child receives at most the remaining budget, queued work is not started after expiry, fan-in receives only remaining time, and an orchestration-expired child skips model finalization. Bounded process-cleanup grace may follow the deadline.
781
+ - Set `idleTimeoutMs` to stop a turn that has produced no completed assistant turn or tool result within that interval.
782
+ - Set `maxTurns` or `maxToolCalls` to stop unfinished repeated work; a terminal answer at the exact turn limit remains successful.
783
+ - Set spawn budgets as retained defaults, or the same fields on `subagent_send` to override one follow-up turn.
784
+ - Top-level blocking turn budgets apply to every job, while a task, chain step, or aggregator can override them locally.
785
+ - Choose the shortest realistic budgets for the task difficulty; split an oversized task instead of extending limits merely to compensate for broad scope.
786
+ - Valid time values range from 1 to 2,147,483,647 milliseconds, matching the runtime timer limit.
787
+ - `maxTurns` and `maxToolCalls` accept integers from 1 through 1,000,000.
788
+ - If `timeoutMs` is omitted, the default is the retained or agent setting, then `PI_SUBAGENT_TIMEOUT_MS`, or `600000` milliseconds (10 minutes) when unset; the other new budgets remain opt-in.
597
789
 
598
790
  Set `thinkingLevel` to request one of Pi's supported levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. Blocking subprocess calls pass the resolved value through `--thinking <level>`.
599
791
 
@@ -610,11 +802,17 @@ For `subagent_spawn`, the root agent should choose the lowest sufficient level:
610
802
 
611
803
  Blocking thinking precedence is: task/chain step/aggregator `thinkingLevel` → top-level `thinkingLevel` → agent default from config or frontmatter → Pi subprocess default.
612
804
 
613
- Stateful spawn precedence is: `subagent_spawn.thinkingLevel` → agent default from config or frontmatter → transport fallback. The subprocess transport then uses spawned Pi model/default resolution. The in-process transport delegates configured model parsing to the loaded Pi core and uses its model thinking suffix before the parent thinking snapshot captured when the child is created. An explicit spawn value is retained for the agent lifecycle and wins over all of those fallbacks.
805
+ Stateful spawn precedence is: `subagent_spawn.thinkingLevel` → agent default from settings or frontmatter → model suffix transport fallback.
806
+ Subprocess uses spawned Pi model/default resolution.
807
+ In-process delegates configured model parsing to loaded Pi core and then uses the parent thinking snapshot captured at child creation.
808
+ RPC passes the selected CLI model and thinking controls before its readiness handshake and reports the effective state returned by Pi.
809
+ An explicit spawn value is retained for the agent lifecycle and wins over every fallback.
614
810
 
615
811
  Omit `thinkingLevel` to preserve existing behavior. Reported stateful details show the requested level, not a guarantee of the provider's effective value. Pi still owns model capability clamping; `pi-subagents` does not duplicate capability detection.
616
812
 
617
- On timeout, the extension sends process-group `SIGTERM`, escalates to `SIGKILL` after a five-second grace period if the process has not actually closed, and returns partial bounded messages or stderr collected so far. Parent abort uses the same cleanup path and preserves a structured result.
813
+ When any execution budget expires, the extension aborts the active run first and creates a versioned, bounded, redacted checkpoint containing partial assistant notes, completed tool evidence, changed-file hints, and whether side effects may already have occurred. After authoritative settlement it may make one concise summary attempt over that checkpoint without replaying the stopped task. The summary attempt has its own extension-owned model-work deadline of at most 45 seconds, followed only by bounded abort and process-cleanup grace. Fresh subprocess summaries run with no tools or project resources. Retained RPC and in-process summaries reuse their child context and are explicitly instructed not to call tools; the current child APIs do not support replacing an existing session's tool set for one turn, so their separate deadline and abort path remain the enforcement boundary. The deterministic checkpoint remains available when finalization or the provider fails, and results retain exit `124` plus a structured termination reason and finalization status. Explicit parent or user abort stops immediately, never starts finalization, and is not mislabeled as a budget stop.
814
+
815
+ This release does not claim a cooperative soft-wrap-up phase because print-mode subprocess children cannot receive steering while they are running. It also does not retry budget-stopped work automatically because file or external side effects may already have occurred.
618
816
 
619
817
  The child event protocol limits each JSON line to 256 KiB. Captured output uses these defaults:
620
818
 
@@ -626,11 +824,26 @@ Truncated text includes a `truncated by pi-subagents` marker and details expose
626
824
 
627
825
  ## 📡 Runtime status
628
826
 
827
+ Run the offline transport benchmark from the repository root when comparing startup overhead:
828
+
829
+ ```bash
830
+ just benchmark-subagents
831
+ ```
832
+
833
+ It reports serial median and median absolute deviation for deterministic fake fresh-subprocess and retained-RPC turns plus isolated real Pi RPC readiness, retained commands, in-process session creation, and retained in-process state access without making a provider request.
834
+ Queue time starts when the registry accepts work, transport startup starts when execution begins, RPC readiness comes from `get_state`, RPC acceptance comes from the correlated `prompt` response, first activity comes from a bounded lifecycle event, settlement comes from `agent_settled`, and delivery is recorded after the parent accepts the completion message.
835
+ Subprocess and in-process timing fields use the nearest public lifecycle boundary and may be coarser than RPC.
836
+ Timing and progress are current-session diagnostics and are not persisted.
837
+ The benchmark measures transport overhead rather than model latency or output quality.
838
+
629
839
  While the `subagent` tool is running, `pi-subagents` publishes compact activity status with `ctx.ui.setStatus("subagents", "...")`. Any statusline extension that reads Pi's generic extension status API can display it; no package-to-package dependency is required.
630
840
 
631
841
  ## 🔒 Safety notes
632
842
 
633
- Subagents have separate processes and context windows, but they are **not security sandboxes**. They run as the same OS user, share the host filesystem and network access, and may conflict if they edit the same files. Tool allow-lists reduce available Pi tools but do not reduce operating-system permissions. `subagent_consult` prevents writes through its Pi tool surface and disables extensions, but it can read accessible paths, call the configured model over the network, and incur cost; its instruction-resource policy is not a filesystem or confidentiality boundary.
843
+ Subagents have separate processes and context windows, but they are **not security sandboxes**. They run as the same OS user, share the host filesystem and network access, and may conflict if they edit the same files. Tool allow-lists reduce available Pi tools but do not reduce operating-system permissions. `subagent_consult` prevents writes through its Pi tool surface and disables extensions, but it can read accessible paths, call the configured model over the network, and incur cost; its instruction-resource policy is not a filesystem or confidentiality boundary. Panel write-capable reviewers use separate disposable Git worktrees, but those worktrees provide repository-write isolation only.
844
+
845
+ Every contracted execution records a hashed immutable `ExecutionPlan` and an executor-owned capability grant bound to its task generation, effective tools, issuance time, and expiry.
846
+ Interrupt, close, shutdown, replacement, persistence, and restore revoke active grants before signalling work or accepting another generation, and late old-plan results become `stale` diagnostic evidence.
634
847
 
635
848
  The runner explicitly reports policy continuity in result details:
636
849
 
@@ -640,12 +853,21 @@ The runner explicitly reports policy continuity in result details:
640
853
 
641
854
  Treat project-local agent prompts like executable project configuration: only enable them in trusted repositories. Stateful project agents require Pi's project trust; interactive use also keeps confirmation enabled by default.
642
855
 
643
- Stateful records are stored as versioned mode-0600 JSON under `~/.pi/agent/pi-subagents-state/` (or the configured Pi agent directory). Records contain sanitized logical history, never process IDs or credentials. Corrupt or unsupported state is quarantined, restored agents are always inert `idle` records, and no prior side effect is automatically resumed. Retention and count limits are configurable. Downgrading is safe: older extension versions ignore this separate state directory; clear **Current agents** from `/subagents` before downgrade if the histories should be removed.
856
+ Stateful records are stored as versioned mode-0600 JSON under `~/.pi/agent/pi-subagents-state/` (or the configured Pi agent directory).
857
+ Explicit blocking-workflow snapshots use separate mode-0600 files under `~/.pi/agent/pi-subagents-workflows/`, retain at most 64 workflows per session for 30 days, and are available only through current-session workflow inspection.
858
+ Records contain sanitized logical history, never process IDs or credentials.
859
+ Corrupt or unsupported state is quarantined, completed and actionable terminal outcomes are preserved, in-flight records restore as `interrupted`, and no prior side effect is automatically resumed.
860
+ Retained follow-ups compare a privacy-safe hashed semantic snapshot before model work; incompatible resource changes require explicit `revalidate: true`, while unknown snapshot versions fail closed.
861
+ Snapshots hash agent manifests, prompts, effective tools, model/thinking, transport, trust, Git tracked and untracked state, and bounded user/project skill and prompt resources without persisting their contents.
862
+ A non-Git target has no stable repository generation proof, so each later follow-up requires explicit revalidation.
863
+ Count projection keeps complete ancestor chains together when stored or restored limits omit older trees.
864
+ Retention and count limits are configurable.
865
+ Downgrading is safe: older extension versions ignore this separate state directory; clear **Current agents** from `/subagents` before downgrade if the histories should be removed.
644
866
 
645
867
  ## 🗂️ Package layout
646
868
 
647
869
  ```txt
648
- extensions/pi-subagents/
870
+ packages/pi-subagents/
649
871
  ├── src/
650
872
  │ ├── index.ts # Pi package entrypoint
651
873
  │ ├── subagents.ts # Extension registration and blocking tool schema
@@ -653,10 +875,44 @@ extensions/pi-subagents/
653
875
  │ ├── consult.ts # Synchronous read-only consultation tool
654
876
  │ ├── consult-policy.ts # Enforced read-only tool intersection
655
877
  │ ├── cwd-policy.ts # Canonical target and saved-trust resolution
878
+ │ ├── prompt-resources.ts # Core-selected SYSTEM and APPEND_SYSTEM resources
656
879
  │ ├── safe-text.ts # Shared byte/line/path sanitization
657
880
  │ ├── stateful.ts # Detached lifecycle registration and dispatch
881
+ │ ├── rpc-transport.ts # Persistent strict-JSONL Pi RPC child transport
882
+ │ ├── rpc-timeout-finalization.ts # RPC abort-settle-summary recovery
883
+ │ ├── rpc-transport-metadata.ts # RPC result policy and bounded metadata helpers
884
+ │ ├── rpc-turn-capture.ts # RPC evidence capture, usage, and budget events
885
+ │ ├── auto-transport.ts # Deterministic preflight transport routing
886
+ │ ├── transport-types.ts # Bounded pi-subagents:v1 progress and telemetry contract
887
+ │ ├── completion-delivery.ts # Completion batching and optional idle-root wake
888
+ │ ├── admission-policy.ts # Audit-only deterministic delegation admission
889
+ │ ├── capability-grant.ts # Generation-bound authority lifetime and revocation
890
+ │ ├── execution-plan.ts # Executor-owned authority and resource resolution
891
+ │ ├── work-item-ledger.ts # Persistent dependency and artifact state machine
892
+ │ ├── work-item-persistence.ts # Atomic redacted workflow state and inspection
893
+ │ ├── integration-controller.ts # Fail-closed canonical integration admission
894
+ │ ├── adaptive-scheduler.ts # Dependency, capacity, budget, and conflict scheduling
895
+ │ ├── semantic-snapshot.ts # Privacy-safe continuation compatibility checks
896
+ │ ├── supervision.ts # Bounded idempotent retries and read-only hedging
897
+ │ ├── panel-execution.ts # Blocking review barrier, synthesis, and lifecycle owner
898
+ │ ├── panel-contract.ts # Strict review and synthesis evidence contracts
899
+ │ ├── panel-evidence.ts # Bounded monotonic reviewer evidence ledger
900
+ │ ├── panel-planning.ts # Panel validation, phase budgets, and WorkItems
901
+ │ ├── panel-prompts.ts # Shared-task reviewer and synthesis prompts
902
+ │ ├── panel-reconciliation.ts # Objection-preserving valid-review barrier
903
+ │ ├── panel-child-group.ts # Child signals and disposable-worktree cleanup
904
+ │ ├── panel-render.ts # Compact and expanded sanitized panel rows
905
+ │ ├── execution-profiles.ts # Provider-neutral thinking profile patches
906
+ │ ├── execution-ui.ts # Profile and per-agent execution settings screens
658
907
  │ ├── stateful-guidance.ts # Detached model-facing workflow guidance
659
908
  │ ├── stateful-lifecycle.ts # Runtime disposal and spawn ownership guards
909
+ │ ├── timeout-finalization.ts # Abort-time bounded summary prompts and deadlines
910
+ │ ├── timeout-checkpoint.ts # Redacted deterministic termination evidence
911
+ │ ├── turn-budget.ts # Idle, assistant-turn, and tool-call enforcement
912
+ │ ├── runner-usage.ts # Bounded subprocess usage accumulation
913
+ │ ├── runner-result.ts # Shared subprocess result interpretation
914
+ │ ├── stateful-limit-ui.ts # Detached capacity settings and recovery previews
915
+ │ ├── stateful-limits.ts # Shared detached defaults, labels, and validation
660
916
  │ ├── stateful-safety.ts # Project-agent and shared-write safety checks
661
917
  │ ├── stateful-tool-params.ts # Consolidated action schemas and validation
662
918
  │ └── *.ts # Package-local discovery, execution, rendering, and settings modules
@@ -666,7 +922,11 @@ extensions/pi-subagents/
666
922
  └── package.json
667
923
  ```
668
924
 
669
- `index.ts` is the Pi entrypoint and forwards to `subagents.ts`; the other source modules are internal. Workflow settings remain backward compatible: older files without `blocking.enabled` receive the seven-tool default, existing `stateful.enabled: false` files expose blocking delegation plus inspection/consultation, and older package releases ignore and preserve the optional `consult` and `cwdPolicy` objects. The package exposes its Pi extension through `package.json`:
925
+ `index.ts` is the Pi entrypoint and forwards to `subagents.ts`; the other source modules are internal.
926
+ Workflow settings remain backward compatible: older files without `blocking.enabled` receive the seven-tool default, and an absent `blocking.maxParallelTasks` keeps the previous eight-worker limit.
927
+ Existing `stateful.enabled: false` files expose blocking delegation plus inspection/consultation.
928
+ Older package releases ignore and preserve the optional `blocking.maxParallelTasks`, `consult`, and `cwdPolicy` fields.
929
+ The package exposes its Pi extension through `package.json`:
670
930
 
671
931
  ```json
672
932
  {
@@ -678,7 +938,7 @@ extensions/pi-subagents/
678
938
 
679
939
  ## 🔎 Keywords
680
940
 
681
- Pi extension, Pi coding agent, subagents, agent delegation, parallel agents, fan-in aggregation, chained agents, isolated subprocesses, AI coding workflow, TypeScript Pi package.
941
+ Pi extension, Pi coding agent, subagents, agent delegation, parallel agents, review panels, evidence synthesis, fan-in aggregation, chained agents, isolated subprocesses, AI coding workflow, TypeScript Pi package.
682
942
 
683
943
  ## 📄 License
684
944