@narumitw/pi-subagents 2.0.5 → 2.1.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 (178) hide show
  1. package/README.md +152 -50
  2. package/dist/chunks/{auto-transport-SY2VHUFH.ts → auto-transport-FUUKFDIG.ts} +6 -6
  3. package/dist/chunks/{capability-grant-CGEWOEKE.ts → capability-grant-PR72SWWS.ts} +4 -4
  4. package/dist/chunks/{chunk-DPPVEQAM.ts → chunk-4AQSF7AS.ts} +1 -1
  5. package/dist/chunks/chunk-4AQSF7AS.ts.map +7 -0
  6. package/dist/chunks/chunk-6H6TBBED.ts +108 -0
  7. package/dist/chunks/chunk-6H6TBBED.ts.map +7 -0
  8. package/dist/chunks/{chunk-DSOOH73Y.ts → chunk-7AAJEUSL.ts} +3 -3
  9. package/dist/chunks/{chunk-DSOOH73Y.ts.map → chunk-7AAJEUSL.ts.map} +2 -2
  10. package/dist/chunks/{chunk-7QPPBBXZ.ts → chunk-D4CR7T73.ts} +21 -3
  11. package/dist/chunks/chunk-D4CR7T73.ts.map +7 -0
  12. package/dist/chunks/{chunk-434NII74.ts → chunk-DIHBUR2E.ts} +54 -8
  13. package/dist/chunks/chunk-DIHBUR2E.ts.map +7 -0
  14. package/dist/chunks/{chunk-NIF42QMF.ts → chunk-FEVPWRMU.ts} +7 -4
  15. package/dist/chunks/chunk-FEVPWRMU.ts.map +7 -0
  16. package/dist/chunks/{chunk-YBUWBRF7.ts → chunk-FXI45N3J.ts} +5 -5
  17. package/dist/chunks/{chunk-S2IWVK3J.ts → chunk-ILEQ27AL.ts} +3 -2
  18. package/dist/chunks/chunk-ILEQ27AL.ts.map +7 -0
  19. package/dist/chunks/{chunk-DQMN4OYM.ts → chunk-ITVWPNU4.ts} +12 -106
  20. package/dist/chunks/chunk-ITVWPNU4.ts.map +7 -0
  21. package/dist/chunks/{chunk-QDVGH2X7.ts → chunk-IWC32VPY.ts} +2 -1
  22. package/dist/chunks/{chunk-QDVGH2X7.ts.map → chunk-IWC32VPY.ts.map} +2 -2
  23. package/dist/chunks/{chunk-I2FAK44T.ts → chunk-JSZIP73U.ts} +48 -10
  24. package/dist/chunks/chunk-JSZIP73U.ts.map +7 -0
  25. package/dist/chunks/{chunk-ZHTNCZIA.ts → chunk-JU6LUNLP.ts} +2 -2
  26. package/dist/chunks/{chunk-PSK43Y6A.ts → chunk-LASD73CM.ts} +2 -2
  27. package/dist/chunks/{chunk-C4L6P266.ts → chunk-LEOYDZI3.ts} +1 -1
  28. package/dist/chunks/{chunk-C4L6P266.ts.map → chunk-LEOYDZI3.ts.map} +2 -2
  29. package/dist/chunks/{chunk-H3BFJ7HJ.ts → chunk-LL4LP2T7.ts} +5 -5
  30. package/dist/chunks/chunk-N2T5IN4X.ts +18 -0
  31. package/dist/chunks/chunk-N2T5IN4X.ts.map +7 -0
  32. package/dist/chunks/{chunk-G3RSMSXJ.ts → chunk-NTRPLF46.ts} +1 -1
  33. package/dist/chunks/chunk-NTRPLF46.ts.map +7 -0
  34. package/dist/chunks/{chunk-CBP76ARQ.ts → chunk-PABJJYP6.ts} +174 -47
  35. package/dist/chunks/chunk-PABJJYP6.ts.map +7 -0
  36. package/dist/chunks/{chunk-EFBPISNT.ts → chunk-PBZMBTNJ.ts} +104 -103
  37. package/dist/chunks/chunk-PBZMBTNJ.ts.map +7 -0
  38. package/dist/chunks/{chunk-SCZ33MYW.ts → chunk-PGLSFLYW.ts} +2 -2
  39. package/dist/chunks/{chunk-O4VO6JUJ.ts → chunk-TM2R67J3.ts} +3 -3
  40. package/dist/chunks/{chunk-QBORTI4W.ts → chunk-TMZRHIIK.ts} +32 -3
  41. package/dist/chunks/chunk-TMZRHIIK.ts.map +7 -0
  42. package/dist/chunks/chunk-TZ34IQ3M.ts +59 -0
  43. package/dist/chunks/chunk-TZ34IQ3M.ts.map +7 -0
  44. package/dist/chunks/chunk-VBDGNNLM.ts +214 -0
  45. package/dist/chunks/chunk-VBDGNNLM.ts.map +7 -0
  46. package/dist/chunks/{chunk-7OBINKFM.ts → chunk-VDG7LTYE.ts} +11 -11
  47. package/dist/chunks/chunk-VDG7LTYE.ts.map +7 -0
  48. package/dist/chunks/{chunk-AEUYS7JC.ts → chunk-X4NMONPE.ts} +1 -1
  49. package/dist/chunks/chunk-X4NMONPE.ts.map +7 -0
  50. package/dist/chunks/{chunk-HKC4ES4B.ts → chunk-YPJEN6NU.ts} +2 -2
  51. package/dist/chunks/{completion-delivery-YPOWSSV3.ts → completion-delivery-JVLNQRWX.ts} +5 -4
  52. package/dist/chunks/{config-status-J4GPWP46.ts → config-status-FKGDECZ3.ts} +7 -6
  53. package/dist/chunks/{config-ui-2YUCUEBM.ts → config-ui-DDKERQHI.ts} +297 -231
  54. package/dist/chunks/config-ui-DDKERQHI.ts.map +7 -0
  55. package/dist/chunks/{consult-IV7UBNQQ.ts → consult-PQ6PRAKC.ts} +14 -13
  56. package/dist/chunks/consult-PQ6PRAKC.ts.map +7 -0
  57. package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts → create-stateful-transport-JWC2EFYL.ts} +6 -6
  58. package/dist/chunks/{delegation-contract-WJPT4FVS.ts → delegation-contract-LA56I5DT.ts} +2 -2
  59. package/dist/chunks/{discovery-K25T3SH4.ts → discovery-MIFB2U4Y.ts} +3 -3
  60. package/dist/chunks/{execution-LA7HN5YF.ts → execution-Q2JZLKJA.ts} +19 -16
  61. package/dist/chunks/execution-Q2JZLKJA.ts.map +7 -0
  62. package/dist/chunks/{in-process-transport-4RF3J6XK.ts → in-process-transport-HJ6TZXC3.ts} +9 -9
  63. package/dist/chunks/{inspect-XV2QALMR.ts → inspect-UH2TKH6E.ts} +25 -10
  64. package/dist/chunks/inspect-UH2TKH6E.ts.map +7 -0
  65. package/dist/chunks/{persistence-VSGXAW4P.ts → persistence-XHPJBZL7.ts} +11 -7
  66. package/dist/chunks/persistence-XHPJBZL7.ts.map +7 -0
  67. package/dist/chunks/{registry-E6XPJB7L.ts → registry-XDXPECWF.ts} +136 -15
  68. package/dist/chunks/registry-XDXPECWF.ts.map +7 -0
  69. package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts → retained-semantic-state-GM75FZGE.ts} +3 -3
  70. package/dist/chunks/{rpc-transport-NEHBHWX4.ts → rpc-transport-7R7DVCEB.ts} +12 -16
  71. package/dist/chunks/rpc-transport-7R7DVCEB.ts.map +7 -0
  72. package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts → spawn-idempotency-BNHOSMZW.ts} +2 -2
  73. package/dist/chunks/{subprocess-transport-NSHOGDC4.ts → subprocess-transport-VHZJRBTW.ts} +15 -14
  74. package/dist/chunks/subprocess-transport-VHZJRBTW.ts.map +7 -0
  75. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts +164 -0
  76. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts.map +7 -0
  77. package/dist/index.ts +427 -30
  78. package/dist/index.ts.map +3 -3
  79. package/docs/async-runtime-protocol.md +69 -0
  80. package/docs/implementation-notes/pi-subagents-capability-matrix.md +62 -0
  81. package/docs/implementation-notes/pi-subagents-current-direction.md +99 -0
  82. package/docs/implementation-notes/pi-subagents-rpc-v1.md +153 -0
  83. package/docs/pi-subagents-diagrams.md +183 -0
  84. package/package.json +9 -8
  85. package/src/agents/types.ts +2 -0
  86. package/src/async-subagent-benchmark.ts +532 -0
  87. package/src/completion-delivery.ts +71 -4
  88. package/src/completion-render.ts +1 -0
  89. package/src/completion-requirement.ts +308 -0
  90. package/src/config-registration.ts +5 -5
  91. package/src/config-status.ts +66 -70
  92. package/src/config-ui.ts +244 -150
  93. package/src/consult-resources.ts +1 -1
  94. package/src/consult.ts +3 -8
  95. package/src/delegation-contract.ts +55 -9
  96. package/src/execution-plan.ts +1 -1
  97. package/src/execution-ui.ts +40 -29
  98. package/src/execution.ts +2 -3
  99. package/src/inspect.ts +24 -1
  100. package/src/orchestration-metrics.ts +1 -1
  101. package/src/panel-execution.ts +2 -3
  102. package/src/panel-failure.ts +1 -1
  103. package/src/panel-render.ts +1 -1
  104. package/src/parallel-limit-ui.ts +6 -5
  105. package/src/params.ts +2 -1
  106. package/src/persistence.ts +9 -0
  107. package/src/process-control.ts +43 -0
  108. package/src/registry-types.ts +5 -0
  109. package/src/registry.ts +162 -18
  110. package/src/render.ts +2 -1
  111. package/src/rpc-transport.ts +1 -1
  112. package/src/runner-outcome.ts +1 -1
  113. package/src/runner-result.ts +1 -1
  114. package/src/runner-types.ts +102 -0
  115. package/src/runner.ts +11 -192
  116. package/src/settings/inspection.ts +27 -0
  117. package/src/settings/schema.ts +9 -0
  118. package/src/settings-reader.ts +7 -0
  119. package/src/settings.ts +20 -0
  120. package/src/spawn-idempotency.ts +5 -0
  121. package/src/stateful-agent-view.ts +15 -19
  122. package/src/stateful-guidance.ts +14 -4
  123. package/src/stateful-limit-ui.ts +23 -20
  124. package/src/stateful-limits.ts +10 -10
  125. package/src/stateful-registration.ts +126 -9
  126. package/src/stateful-render.ts +27 -2
  127. package/src/subagent-details.ts +43 -0
  128. package/src/subagents-extension.ts +66 -8
  129. package/src/subagents.ts +2 -0
  130. package/src/subprocess-transport.ts +2 -1
  131. package/src/supervision.ts +2 -1
  132. package/src/timeout-finalization.ts +1 -1
  133. package/src/tool-schema-compatibility.ts +73 -0
  134. package/src/transport-types.ts +6 -0
  135. package/src/transport-ui.ts +18 -46
  136. package/src/usage-recording-config.ts +13 -0
  137. package/src/usage-recording-store.ts +183 -0
  138. package/src/usage-recording.ts +478 -0
  139. package/src/verification-harness.ts +1 -1
  140. package/src/workflow-ui.ts +17 -9
  141. package/dist/chunks/chunk-434NII74.ts.map +0 -7
  142. package/dist/chunks/chunk-7OBINKFM.ts.map +0 -7
  143. package/dist/chunks/chunk-7QPPBBXZ.ts.map +0 -7
  144. package/dist/chunks/chunk-AEUYS7JC.ts.map +0 -7
  145. package/dist/chunks/chunk-CBP76ARQ.ts.map +0 -7
  146. package/dist/chunks/chunk-DPPVEQAM.ts.map +0 -7
  147. package/dist/chunks/chunk-DQMN4OYM.ts.map +0 -7
  148. package/dist/chunks/chunk-EFBPISNT.ts.map +0 -7
  149. package/dist/chunks/chunk-G3RSMSXJ.ts.map +0 -7
  150. package/dist/chunks/chunk-I2FAK44T.ts.map +0 -7
  151. package/dist/chunks/chunk-NIF42QMF.ts.map +0 -7
  152. package/dist/chunks/chunk-QBORTI4W.ts.map +0 -7
  153. package/dist/chunks/chunk-S2IWVK3J.ts.map +0 -7
  154. package/dist/chunks/config-ui-2YUCUEBM.ts.map +0 -7
  155. package/dist/chunks/consult-IV7UBNQQ.ts.map +0 -7
  156. package/dist/chunks/execution-LA7HN5YF.ts.map +0 -7
  157. package/dist/chunks/inspect-XV2QALMR.ts.map +0 -7
  158. package/dist/chunks/persistence-VSGXAW4P.ts.map +0 -7
  159. package/dist/chunks/registry-E6XPJB7L.ts.map +0 -7
  160. package/dist/chunks/rpc-transport-NEHBHWX4.ts.map +0 -7
  161. package/dist/chunks/subprocess-transport-NSHOGDC4.ts.map +0 -7
  162. /package/dist/chunks/{auto-transport-SY2VHUFH.ts.map → auto-transport-FUUKFDIG.ts.map} +0 -0
  163. /package/dist/chunks/{capability-grant-CGEWOEKE.ts.map → capability-grant-PR72SWWS.ts.map} +0 -0
  164. /package/dist/chunks/{chunk-YBUWBRF7.ts.map → chunk-FXI45N3J.ts.map} +0 -0
  165. /package/dist/chunks/{chunk-ZHTNCZIA.ts.map → chunk-JU6LUNLP.ts.map} +0 -0
  166. /package/dist/chunks/{chunk-PSK43Y6A.ts.map → chunk-LASD73CM.ts.map} +0 -0
  167. /package/dist/chunks/{chunk-H3BFJ7HJ.ts.map → chunk-LL4LP2T7.ts.map} +0 -0
  168. /package/dist/chunks/{chunk-SCZ33MYW.ts.map → chunk-PGLSFLYW.ts.map} +0 -0
  169. /package/dist/chunks/{chunk-O4VO6JUJ.ts.map → chunk-TM2R67J3.ts.map} +0 -0
  170. /package/dist/chunks/{chunk-HKC4ES4B.ts.map → chunk-YPJEN6NU.ts.map} +0 -0
  171. /package/dist/chunks/{completion-delivery-YPOWSSV3.ts.map → completion-delivery-JVLNQRWX.ts.map} +0 -0
  172. /package/dist/chunks/{config-status-J4GPWP46.ts.map → config-status-FKGDECZ3.ts.map} +0 -0
  173. /package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts.map → create-stateful-transport-JWC2EFYL.ts.map} +0 -0
  174. /package/dist/chunks/{delegation-contract-WJPT4FVS.ts.map → delegation-contract-LA56I5DT.ts.map} +0 -0
  175. /package/dist/chunks/{discovery-K25T3SH4.ts.map → discovery-MIFB2U4Y.ts.map} +0 -0
  176. /package/dist/chunks/{in-process-transport-4RF3J6XK.ts.map → in-process-transport-HJ6TZXC3.ts.map} +0 -0
  177. /package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts.map → retained-semantic-state-GM75FZGE.ts.map} +0 -0
  178. /package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts.map → spawn-idempotency-BNHOSMZW.ts.map} +0 -0
package/README.md CHANGED
@@ -6,7 +6,7 @@ Delegate bounded research or implementation work to isolated specialist agents w
6
6
 
7
7
  Use the built-in `explorer` for read-only evidence and `worker` for a clearly owned implementation slice.
8
8
 
9
- The compatibility default exposes every delegation method, while **Async only** is the recommended smaller surface for normal parallel work.
9
+ The compatibility default exposes background and blocking methods, while **Keep Pi available (async)** is an optional smaller background-only surface.
10
10
 
11
11
  ## ✨ Features
12
12
 
@@ -19,6 +19,7 @@ The compatibility default exposes every delegation method, while **Async only**
19
19
  - Routes nested completion and peer communication through authenticated session-scoped channels.
20
20
  - Provides `/subagents` settings, status, help, tool-surface selection, and recovery diagnostics.
21
21
  - Returns concise model-visible results with complete bounded details and sanitized terminal rendering.
22
+ - Optionally records content-free local lifecycle and timing events for evaluating delegation behavior.
22
23
  - Loads a generated split runtime while preserving lazy execution, UI, inspection, and transport chunks.
23
24
 
24
25
  ## 📦 Install
@@ -45,57 +46,93 @@ An unbuilt checkout intentionally has no declared generated entrypoint.
45
46
 
46
47
  ## 🚀 Quick start
47
48
 
48
- For normal async-first use, run `/subagents`, choose **Change delegation**, select **Async only · Recommended**, confirm the exact tool changes, and reload.
49
+ Run `/subagents`, choose **How subagents run**, and review the tools registered by each workflow.
49
50
 
50
- This registers `subagent_spawn`, `subagent_send`, `subagent_manage`, `subagent_mailbox`, and `subagent_inspect` while keeping the main agent responsive.
51
+ The compatibility default includes background agents and blocking compatibility methods.
52
+
53
+ Select **Keep Pi available (async)** to register `subagent_spawn`, `subagent_send`, `subagent_manage`, `subagent_mailbox`, and `subagent_inspect` without the blocking methods.
54
+
55
+ Confirm any change and reload to apply it.
51
56
 
52
57
  Default `next-turn` delivery is for work the current response does not require.
53
- When the final answer depends on detached work, use `/subagents settings` to select **Resume automatically when finished**.
58
+ When the final answer depends on background work, use `/subagents settings` → **Completion and privacy** to select **Continue automatically when work finishes**.
59
+ That mode steers completions into active parent work before its next model call, or wakes an idle parent once when no user or extension input is pending.
54
60
 
55
- Keep **All delegation methods** when an explicit blocking workflow or synchronous read-only `subagent_consult` is still required.
61
+ **Background plus compatibility methods (async + sync)** also provides the deprecated blocking `subagent`, supported `subagent_await` join, and synchronous read-only `subagent_consult`.
62
+ The blocking `subagent` tool is deprecated for new work.
56
63
 
57
- Async-first delegation still requires useful parallel main-agent work, clear worker ownership, and a supported completion path.
64
+ Background delegation still requires useful parallel main-agent work, clear worker ownership, and a supported completion path.
58
65
 
59
66
  ## 💬 Commands
60
67
 
61
68
  - `/subagents` opens the current-session manager in TUI mode and reports bounded status in RPC mode.
62
- - `/subagents settings` configures target locations, trusted resources, and async completion delivery.
63
- - `/subagents status` shows current-session and configured values with their sources.
64
- - `/subagents help` summarizes the command surface and isolation limits.
69
+ - `/subagents settings` opens the same grouped settings hub used by the main menu.
70
+ - `/subagents status` shows detailed current-session and configured diagnostics with their sources.
71
+ - `/subagents help` explains first steps, settings behavior, commands, and safety limits.
65
72
 
66
73
  ## ⚙️ Settings
67
74
 
68
- Use `/subagents settings` for target location, trust, consultation resource, and detached-completion preferences.
69
- Use `/subagents` → **Advanced settings** for delegation workflow, agent tool permissions, and runtime limits.
75
+ Use `/subagents settings` for **Folders and trusted resources**, **Completion and privacy**, **Agent defaults**, and **Advanced runtime settings**.
76
+ Use `/subagents` → **How subagents run** to change the registered delegation tools.
70
77
  Settings are stored in `~/.pi/agent/pi-subagents.json`; the detailed sections below document precedence, reload requirements, and safety behavior.
71
78
 
79
+ ## 📊 Local usage recording
80
+
81
+ Local usage recording is disabled by default and creates no usage storage until the user selects **On · local only** in `/subagents settings`.
82
+ The setting applies immediately and persists as `usageRecording.enabled` in the user settings file.
83
+ No network connection, upload, remote identifier, or project attribution is used.
84
+
85
+ Records are stored below `<pi-agent-directory>/pi-subagents-usage/` as private per-runtime JSONL writer files.
86
+ Directories use mode `0700` and files use mode `0600` on POSIX systems.
87
+ Each event is versioned, bounded to 8 KiB, and ends with a newline so a crash-truncated final frame can be distinguished from completed records.
88
+ Concurrent Pi processes use separate opaque writer files and never append to one shared file.
89
+ Validated writer files older than 30 days are removed after recording starts.
90
+ Disabling recording stops new events immediately; existing files remain until the retention window expires or the user removes the directory while Pi is stopped.
91
+
92
+ Stored fields are limited to extension-generated runtime, session, turn, tool, child, run, and completion ordinals; the effective delegation surface; lifecycle and typed outcome states; bounded executor-owned termination reasons; runtime-versus-explicit budget-source labels; completion-delivery transitions; bounded usage numbers; errors as booleans; and monotonic timing or durations.
93
+ The recorder does not store prompts, delegated tasks, responses, thinking, tool arguments or results, code, paths, commands, mailbox or steering content, raw errors, provider/model identity, credentials, Pi session identifiers, or a persistent device identifier.
94
+ Raw child, run, completion, and provider tool-call identifiers are replaced with runtime-local ordinals before publication.
95
+
96
+ The events can describe blocking versus async tool selection, operational errors, parent/child overlap, child terminal states, completion attempts and visibility, turns, tokens, and wall-clock durations within one runtime.
97
+ They cannot establish semantic task success, whether delegation was appropriate, whether parent work was useful, or whether a completion was understood by the model.
98
+ Opt-in field data describes only users who enabled recording and does not prove causal effects between tool surfaces.
99
+ Use a controlled benchmark before interpreting future `subagent_await` immediate-join or blocking-choice hypotheses causally.
100
+
101
+ `/subagents status` reports whether recording is active, the current-session event count, retention, and the local path.
102
+ A failed write drops that event, reports one bounded warning, and retries on later events without exposing filesystem details.
103
+
72
104
  ## 🛠️ Tools
73
105
 
74
- `pi-subagents` registers seven tools by default.
75
- Run `/subagents`, choose **Change delegation**, review the concrete tool changes, then select **Save and reload** to apply one of these workflows:
106
+ `pi-subagents` registers eight tools by default.
107
+ Run `/subagents`, choose **How subagents run**, review the concrete tool changes, then select **Save and reload** to apply one of these workflows:
76
108
 
77
109
  | Workflow | Registered tools |
78
110
  | --- | --- |
79
- | **All delegation methods** (compatibility default) | `subagent`, `subagent_spawn`, `subagent_send`, `subagent_manage`, `subagent_mailbox`, `subagent_inspect`, and `subagent_consult` |
80
- | **Async only** (recommended) | `subagent_spawn`, `subagent_send`, `subagent_manage`, `subagent_mailbox`, and `subagent_inspect` |
81
- | **Blocking only** (compatibility) | `subagent`, `subagent_inspect`, and `subagent_consult` |
82
- | **Disabled** | `subagent_inspect` only; delegation is disabled |
83
-
84
- `subagent` and `subagent_consult` remain explicit compatibility routes with no current deprecation deadline.
111
+ | **Background plus compatibility methods (async + sync)** (compatibility default) | `subagent`, `subagent_spawn`, `subagent_send`, `subagent_await`, `subagent_manage`, `subagent_mailbox`, `subagent_inspect`, and `subagent_consult` |
112
+ | **Keep Pi available (async)** | `subagent_spawn`, `subagent_send`, `subagent_manage`, `subagent_mailbox`, and `subagent_inspect` |
113
+ | **Compatibility blocking methods (sync)** | `subagent`, `subagent_inspect`, and `subagent_consult` |
114
+ | **Subagents disabled** | `subagent_inspect` only; delegation is disabled |
115
+
116
+ `subagent` is deprecated for new work but remains registered in compatibility workflows with its existing schema and execution behavior.
117
+ No removal release or date is currently set because chain, fan-in, panel, and explicit workflow callers do not yet have one-for-one detached replacements.
118
+ `subagent_consult` and `subagent_await` remain supported and are not deprecated.
85
119
  The four async lifecycle tools stay separate because starting work, sending follow-ups, managing lifecycle, and queueing mailbox messages have different contracts.
120
+ `subagent_await` is a separate blocking join and is omitted from **Keep Pi available (async)**.
86
121
  Any default change, tool removal, or lifecycle consolidation requires a separately approved compatibility migration.
87
122
 
88
123
  The preview compares the selection with the tools registered in the current session, even when a manual settings edit is pending, and remains read-only until confirmation.
89
124
  Escape or **Cancel** leaves settings unchanged.
90
125
  Tool removal requires an extension reload because Pi does not expose extension tool unregistration.
91
- To avoid aborting work or removing isolated worktrees during `session_shutdown`, workflow changes are blocked while detached agents are retained; finish or clear them through **Current agents** first.
126
+ To avoid aborting work or removing isolated worktrees during `session_shutdown`, workflow changes are blocked while background agents are saved for follow-up; finish or clear them through **Current subagents** first.
92
127
  Pi owns reload-error reporting and does not return a success result to extensions, so the save notification also tells users to run `/reload` if the tool surface does not refresh.
93
128
 
94
129
  The available tools are:
95
130
 
96
- - `subagent` — delegate blocking single, parallel, fan-in, chained, panel-review, or explicit dependency-workflow tasks.
131
+ - `subagent` — deprecated compatibility tool for blocking single, parallel, fan-in, chained, panel-review, or explicit dependency-workflow calls.
132
+ Existing callers remain supported, but new work should prefer the main agent, detached lifecycle tools, or `subagent_consult` according to the task.
97
133
  The main agent cannot process queued steering until the call returns.
98
134
  - `subagent_spawn` and related lifecycle tools — when enabled, start reusable detached work, return immediately, and receive bounded completion messages automatically.
135
+ - `subagent_await` — intentionally block until one retained turn settles or its independent wait timeout expires; timeout and cancellation never interrupt the child.
99
136
  - `subagent_inspect` — inspect agent/model/run/runtime metadata without launching work or changing state.
100
137
  - `subagent_consult` — run one ephemeral read-only consultation and wait for its answer.
101
138
 
@@ -133,10 +170,11 @@ Choose the API by lifecycle:
133
170
  | One bounded implementation slice can run beside named main-agent work | Use async `subagent_spawn` with `worker`, clear ownership, and a supported delivery and integration path |
134
171
  | Two or more independent implementation slices | Use workers with disjoint write ownership while the main agent coordinates and integrates |
135
172
  | Broad read-only evidence that can run beside main-agent work | Use async `subagent_spawn` with `explorer` |
136
- | Final-answer-dependent detached work | Enable `completionDelivery: "auto-resume"` so completion requests a synthesis turn |
173
+ | Final-answer-dependent detached work | Enable `completionDelivery: "auto-resume"` so active work receives completion by steering and an idle parent can start a synthesis turn |
137
174
  | Bounded synchronous read-only evidence whose independent perspective justifies waiting | Use `subagent_consult` when blocking delegation is enabled |
138
- | Intentional synchronous workflow, panel, chain, or fan-in | Use blocking `subagent` when making the main agent unavailable is justified |
175
+ | Existing synchronous workflow, panel, chain, or fan-in caller without a detached replacement | Keep deprecated `subagent` as a compatibility route |
139
176
  | Reusable history, follow-ups, or mailboxes | Use `subagent_spawn` and lifecycle tools when enabled |
177
+ | One retained result is now required and useful overlapping parent work is complete | Use `subagent_await` when blocking delegation is enabled |
140
178
  | Side-effect-free agent/model/run diagnostics | Use `subagent_inspect` |
141
179
 
142
180
  Execution modes:
@@ -158,6 +196,7 @@ Common controls:
158
196
  - `thinkingLevel` — request `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max` thinking for the spawned Pi process or retained child.
159
197
  - `idempotencyKey` — make an exact `subagent_spawn` retry return the existing retained `agentId`; reuse with different parameters fails before confirmation, worktree creation, or child launch.
160
198
  - `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.
199
+ - `completionRequirement` — mark one detached spawn or follow-up as `background` (default) or `required` for the parent final answer; required mode tracks the accepted run ID and generation until its exact completion is visible or terminal.
161
200
  - `totalTimeoutMs` — bound a whole explicit blocking workflow; no new task starts after the budget is exhausted.
162
201
 
163
202
  For `subagent_spawn`, the root agent selects the lowest thinking level and shortest realistic work deadline sufficient for the delegated task.
@@ -193,7 +232,7 @@ For real isolation, run Pi in a container, VM, micro-VM, or OS sandbox with only
193
232
 
194
233
  ## 🧭 Proactive use
195
234
 
196
- When registered, the blocking `subagent` tool advertises only blocking guidance.
235
+ When registered, deprecated `subagent` advertises its migration paths and limits compatibility use to existing callers or explicit requests whose orchestration semantics lack a detached replacement.
197
236
  When stateful lifecycle tools are registered, `subagent_spawn` adds detached guidance for the active completion-delivery policy.
198
237
  Changing the policy through `/subagents settings` refreshes that guidance immediately.
199
238
 
@@ -216,12 +255,14 @@ Delegation guidance:
216
255
  - If no useful main-agent work exists, perform the single-lane task directly instead of spawning one ordinary worker.
217
256
  - A single worker without concurrent main-agent work remains available when the user explicitly requests a specialist model, tool profile, or isolation boundary.
218
257
  - With default `completionDelivery: "next-turn"`, use detached work only when the current response does not depend on its result because an idle root is not awakened.
219
- - With `completionDelivery: "auto-resume"`, detached work may affect the final answer because completion requests a later synthesis turn.
258
+ - With `completionDelivery: "auto-resume"`, detached work may affect the final answer because completion steers into active work or requests a later synthesis turn from idle.
259
+ - Mark every final-answer-dependent spawn with `completionRequirement: "required"`, retain its returned ID or path, treat interim output as progress, and synthesize only after every corresponding completion is visible or terminal.
220
260
  - After `subagent_spawn` returns, immediately continue the identified local task instead of merely announcing the spawn, waiting, polling, duplicating the child task, or ending while useful local work remains.
261
+ - Do not duplicate a running child's assigned work; use a bounded parent fallback only after completion reports failure or insufficient evidence.
221
262
  - Use multiple workers only for truly independent slices with disjoint write ownership and safe workspace concurrency, and keep integration in the main agent.
222
263
  - Keep ordinary planning in the main agent or express a genuine dependency graph through an explicit caller-authored `workflow` payload.
223
264
  - Keep ordinary review in the main agent with a review skill and deterministic checks; reserve custom verifier agents or panels for consequential independent verification.
224
- - Use blocking `subagent` only when intentional synchronous output or isolation justifies making the main agent unavailable.
265
+ - Do not choose deprecated `subagent` for new work; retain it only for an existing caller or an explicit request whose chain, fan-in, panel, or workflow semantics lack a detached replacement.
225
266
  - Do not use project-local agents unless the user explicitly opts into them with `agentScope: "project"` or `"both"`; keep confirmation enabled for untrusted repositories.
226
267
 
227
268
  Examples where the main agent chooses the topology:
@@ -240,7 +281,8 @@ The main agent owns `src/parser.ts`, immediately continues that work after spawn
240
281
  ```json
241
282
  {
242
283
  "agent": "worker",
243
- "task": "Implement the approved formatter slice only in src/formatter.ts and test/formatter.test.ts. Do not edit src/parser.ts. Report changed paths, checks, and remaining risks."
284
+ "task": "Implement the approved formatter slice only in src/formatter.ts and test/formatter.test.ts. Do not edit src/parser.ts. Report changed paths, checks, and remaining risks.",
285
+ "completionRequirement": "required"
244
286
  }
245
287
  ```
246
288
 
@@ -283,7 +325,7 @@ It never starts a child, sends or acknowledges mailbox messages, interrupts or c
283
325
  | `get_workflow` | Required `workflowId` | Bounded task states, generations, dependencies, plan identities, artifact metadata, verification state, and outcome reasons without artifact contents |
284
326
  | `list_models` | Optional `limit` (default 50, maximum 100) | Session-scoped models, or the already-loaded available snapshot |
285
327
  | `preview_context` | Optional `context` and `contextEntryIds` | Selected mode, user turns, source count, UTF-8 bytes, and truncation without returning context text |
286
- | `status` | No additional fields | Effective workflow, runtime counts/transport, detached limit values, completion delivery, consultation resources, and configured/runtime settings with per-field sources |
328
+ | `status` | No additional fields | Effective workflow, runtime counts/transport, detached limit values, completion delivery, local usage-recording state, consultation resources, and configured/runtime settings with per-field sources |
287
329
  | `diagnose` | No additional fields | Structured `pass`, `warning`, and `fail` checks; failed checks are report data rather than a tool error |
288
330
 
289
331
  The schema rejects fields that do not belong to the selected action.
@@ -601,16 +643,29 @@ Legacy v1 and v2 records without acceptance fields retain their prior completed
601
643
  Stateful lifecycle tools are available by default.
602
644
  `subagent_spawn` is detached: it schedules work, returns immediately with an opaque `agentId` plus canonical `taskPath`, and later delivers a bounded completion to its intended parent.
603
645
  Every turn receives an executor-owned `runId`, monotonically increasing agent-local generation, and unique `completionId`.
646
+ A caller can set `completionRequirement: "required"` on a spawn or follow-up to bind final-answer dependency state to that exact run and generation.
647
+ Required state moves from `pending` to `available` after durable terminal completion and to `visible` only after the intended parent context observes the exact completion ID.
648
+ Interruption, close, stale restore, and shutdown terminalize unfinished requirements explicitly instead of silently dropping them.
649
+ Tool-result details preserve fork-sensitive requirement evidence, inspection projects bounded requirement state, and one canonical hidden context block replaces older copies.
650
+ The runtime rejects a sixty-fifth unresolved required run before acceptance so every unresolved exact identity fits in the bounded parent context.
604
651
  The terminal completion and recipient are persisted before delivery, simultaneous root completions are batched, and the root broker allows at most one in-flight wake until that parent turn starts.
605
652
  In TUI mode, completion messages show a compact task and payload summary while collapsed; use the configured tool-output expansion action (`Ctrl+O` by default) to show or hide the complete message globally.
606
653
 
607
654
  Detached work follows a non-polling policy.
608
655
  Before one ordinary `subagent_spawn`, identify useful non-overlapping main-agent work that starts immediately and a supported completion integration path.
609
656
  With default `next-turn` delivery, the current response must not depend on the result because an idle root is not awakened.
610
- With opt-in `auto-resume`, detached work may affect the final answer because completion requests a synthesis turn after the main agent settles.
657
+ With opt-in `auto-resume`, detached work may affect the final answer because completion steers into an active parent before its next model call or requests a synthesis turn from idle.
658
+ Mark every final-answer-dependent spawn with `completionRequirement: "required"`, retain its returned ID or path, treat interim output as progress, and synthesize only after every corresponding completion is visible or terminal.
659
+ When local work finishes before required children, emit at most one brief progress sentence and end the turn rather than repeating waiting updates or using the requested final format, verdict, or conclusion.
611
660
  After spawning, immediately continue the identified local task instead of merely announcing the spawn, waiting, polling `subagent_inspect` or `subagent_mailbox`, duplicating the child task, or ending while useful local work remains.
661
+ Do not duplicate a running child's assigned work; use a bounded parent fallback only after completion reports failure or insufficient evidence.
662
+ Omit `contract` for ordinary `subagent_spawn` calls and use it only when explicit acceptance, authority, evidence, or admission semantics are required.
663
+ Enforced `requestedAuthority.capabilities` and `requestedAuthority.tools` can be checked and narrowed, but enforced `readPaths`, `writePaths`, network, and secret guarantees reject before child launch because the executor cannot provide those boundaries.
664
+ After that rejection, retry once without the unsupported fields or with audit enforcement only when they were advisory; stop when they represented a required security boundary.
612
665
  Add another detached agent only for truly independent work with safe workspace concurrency and disjoint write ownership.
613
- Detached lifecycle work intentionally has no `subagent_wait` tool.
666
+ When both blocking and stateful delegation are enabled, `subagent_await` may intentionally join one retained turn after useful overlapping parent work is complete.
667
+ Its `timeoutMs` defaults to 30 seconds and limits only the wait; timeout or caller cancellation does not interrupt or close the child.
668
+ The normal at-least-once completion channel remains active, so the same completion may still arrive after the await result.
614
669
 
615
670
  A detached `worker` may directly implement a bounded slice with clear ownership while the main agent handles another useful slice and retains integration and final verification.
616
671
  Without concurrent main-agent work, use one worker only for an explicit user-requested specialist model, tool profile, or isolation boundary.
@@ -620,15 +675,21 @@ Simple and immediate critical-path work should stay in the main agent.
620
675
 
621
676
  - `"next-turn"` (default) sends `deliverAs: "steer"` without a turn trigger.
622
677
  Pi queues it into an active root's context, while an idle root records it without waking.
623
- - `"auto-resume"` holds completion while the root is active, then requests one synthesis turn after the parent settles when no user or extension messages are already pending.
624
- Simultaneous completions share that turn, active work is not interrupted, and pending input suppresses the automatic wake.
625
-
678
+ - `"auto-resume"` sends completion to an active root with `deliverAs: "steer"` and no turn trigger, so Pi places it after the current assistant turn and before the next model call.
679
+ An idle root with no pending user or extension input receives at most one in-flight synthesis wake; pending input suppresses that wake, and simultaneous idle completions share one turn.
680
+
681
+ Completion delivery and required-run context make dependencies visible to the model but do not enforce model obedience, rewrite premature assistant output, or provide a hard final-answer barrier.
682
+ The supported Pi extension API exposes no hook for buffering assistant deltas before display and no replay-safe steering activity for a cross-mode interruptible join.
683
+ `message_end` replacement can repair finalized persistence but cannot retract already displayed streaming output.
684
+ The package therefore keeps `subagent_await` as the accurately documented blocking fallback and does not claim an extension-only hard barrier.
685
+ The repository protocol note at `docs/async-runtime-protocol.md` records the exact state machine and unavailable core guarantees; this work does not modify or publish Pi core packages.
626
686
  The bounded persisted completion outbox provides ordered at-least-once delivery across process restart without replaying the child turn.
627
687
  A top-level completion targets `/root`; a nested completion enters the direct retained parent's mailbox and is not duplicated into the root transcript.
628
688
  If the direct parent cannot own delivery, routing walks toward the nearest live retained ancestor and uses `/root` only as the final fallback.
629
689
  An idle parent remains asleep, and inspection exposes its unread and pending-completion counts until a later turn consumes the envelope.
630
690
  When state must be reduced to its storage bound, persistence drops roots without pending completions first and trims old history rather than discarding an outbox-owned root.
631
691
  A completion is acknowledged only after the intended recipient context observes its exact `completionId`; an injection that returns synchronously but never reaches context remains pending for retry.
692
+ The broker retains a bounded set of recently acknowledged IDs to suppress same-session re-enqueue while keeping memory bounded.
632
693
  If the process exits after context assembly but before acknowledgement is persisted, the same ID can be delivered again and consumers must deduplicate it.
633
694
  Auto-resume applies only to `/root`; nested delivery never silently starts the parent.
634
695
  Transient terminal-persistence failures retry with bounded exponential backoff and keep the run pending; shutdown cancels retry waits and reports a final persistence failure instead of silently resolving unsaved work.
@@ -643,18 +704,20 @@ Set it to `auto` for deterministic preflight selection: read-only built-in tools
643
704
  Automatic selection never falls back after child creation or prompt acceptance.
644
705
 
645
706
  Run `/subagents` in TUI mode to open the standard primary manager.
646
- 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.
647
- **Change delegation**, **Current agents**, and **Settings** cover the common workflows.
648
- Agent permissions, **Maximum parallel workers**, **Detached agent limits**, **Performance and execution**, transport/runtime details, source, and settings path remain under **Advanced settings**.
649
- **Performance and execution** provides responsiveness guidance, transport previews, and per-agent model/thinking/timeout defaults.
707
+ It leads with how subagents run, what Pi does when work finishes, and counts of working subagents and subagents saved for follow-up.
708
+ **How subagents run**, **Current subagents**, **Settings**, **Diagnostics**, and **Help** are the only top-level actions.
709
+ **Settings** groups **Folders and trusted resources**, **Completion and privacy**, **Agent defaults**, and **Advanced runtime settings** by user task.
710
+ **Diagnostics** shows detailed current-session values, configured values, sources, and the settings path.
711
+ **Advanced runtime settings** provides optional transport and capacity controls that most users can leave unchanged.
712
+ **Agent defaults** groups tool permissions with per-agent model, thinking, and time-limit defaults.
650
713
  Per-agent defaults preserve tool and context settings, and explicit tool-call values remain authoritative.
651
714
  The parallel-worker input rejects invalid values without discarding the draft and applies a successful save immediately.
652
- The detached-limit screen edits retained capacity, active-turn concurrency, direct children, tree depth, and stored-record capacity.
715
+ The background-agent limit screen edits saved-subagent capacity, concurrent work, direct children, nested levels, and stored-record capacity.
653
716
  Detached-limit saves are durable immediately but apply to the runtime after `/reload` or the next Pi session.
654
717
  Escape returns from a nested screen to a newly refreshed manager, while Ctrl+C closes the full flow.
655
718
  Exact workflow/reload and project-agent safety confirmations remain extension-owned because they guard live agent and trust-boundary policy rather than ordinary navigation.
656
719
 
657
- 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.
720
+ The direct routes remain predictable: `/subagents settings` opens the same four settings groups as the manager; `/subagents status` reports detailed current-session runtime values separately from configured values, per-field sources, and path; `/subagents help` explains first steps, reload behavior, commands, and the non-sandbox limitation.
658
721
  In RPC mode, bare `/subagents` emits the same bounded status through Pi's notification protocol instead of opening a custom TUI.
659
722
  JSON and print modes do not emit ad hoc command output.
660
723
  Manual edits use `~/.pi/agent/pi-subagents.json` and take effect after reloading Pi:
@@ -685,6 +748,9 @@ Manual edits use `~/.pi/agent/pi-subagents.json` and take effect after reloading
685
748
  },
686
749
  "consult": {
687
750
  "resources": "project-context"
751
+ },
752
+ "usageRecording": {
753
+ "enabled": false
688
754
  }
689
755
  }
690
756
  ```
@@ -693,14 +759,14 @@ The settings UI patches the raw JSON atomically and preserves unknown fields.
693
759
  It refuses to overwrite malformed or invalid settings.
694
760
  Supported Pi writers serialize the latest-document read and same-directory temporary-file rename through `pi-subagents.json.mutation-lock`.
695
761
  Editors and older extension versions do not participate in that lock, so avoid manual edits while a settings save is in progress.
696
- `blocking.enabled` defaults to `true`, so **All delegation methods** remains the compatibility default.
697
- Set it to `false` for the recommended async-only workflow.
762
+ `blocking.enabled` defaults to `true`, so **Background plus compatibility methods (async + sync)** remains the compatibility default even though `subagent` is deprecated for new work.
763
+ Set it to `false` for the **Keep Pi available (async)** workflow.
698
764
  `blocking.maxParallelTasks` defaults to `8` and accepts positive integers from `1` through `64`.
699
765
  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.
700
766
  `stateful.enabled` also defaults to `true`; its existing `false` value remains the blocking-only workflow.
701
767
  The detached defaults are `maxAgents: 16`, `maxActiveTurns: 4`, `maxChildrenPerAgent: 8`, `maxDepth: 3`, and `maxStoredAgents: 50`.
702
768
  `maxDepth` accepts zero or a positive safe integer, while the other four detached limits accept positive safe integers.
703
- Use `/subagents` → **Advanced settings** → **Detached agent limits** to edit them without replacing unknown JSON fields.
769
+ Use `/subagents settings` → **Advanced runtime settings** → **Background agent limits** to edit them without replacing unknown JSON fields.
704
770
  The screen shows current-session and configured values separately because changes apply after `/reload`.
705
771
  It never reloads automatically, because reload can interrupt retained detached work.
706
772
  Lowering retained, depth, or stored capacity shows a projected recovery warning when current records would be omitted.
@@ -737,7 +803,7 @@ For example:
737
803
  }
738
804
  ```
739
805
 
740
- 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.
806
+ Use **Current subagents** in `/subagents` to inspect the indented agent tree, lifecycle state, unread count, and current task summary, or to confirm clearing subagents saved for follow-up.
741
807
  Active turns are FIFO-limited by `maxActiveTurns`; excess retained work remains in `starting` state until a slot is available.
742
808
  `maxAgents` separately bounds running, queued, and idle records.
743
809
  `maxChildrenPerAgent` bounds direct children, while `maxDepth` counts nested levels below a depth-zero root.
@@ -939,8 +1005,8 @@ Users who need shell-assisted read-mostly work can define a custom agent, but `b
939
1005
 
940
1006
  ## ⚙️ Configure agent tools
941
1007
 
942
- Open `/subagents`, choose **Advanced settings**, then **Agent tool permissions** in an interactive Pi session to edit the tools each subagent may use.
943
- Choose **Performance and execution** **Agent execution defaults** to edit provider-neutral inherited model patterns, thinking levels, and timeouts without changing tools.
1008
+ Open `/subagents settings`, choose **Agent defaults**, then **Tool permissions** in an interactive Pi session to edit the tools each subagent may use.
1009
+ Choose **Model, thinking, and time limit** to edit provider-neutral model patterns, thinking levels, and time limits without changing tools.
944
1010
  The standard bounded multi-select keeps a one-save draft: toggles do not write until **Save changes**, Escape leaves the draft without writing, and unavailable configured tool names remain visible and preserved.
945
1011
  In TUI mode, type to fuzzy-search tool names and availability metadata; Save and Discard remain pinned below the matches.
946
1012
  These are user settings stored in `~/.pi/agent/pi-subagents.json` and affect future sessions.
@@ -999,6 +1065,7 @@ Explicit workflow routing can match declared capabilities, configured tools, fil
999
1065
  A missing or malformed manifest remains unknown and cannot satisfy a capability-routed task.
1000
1066
  The parent-facing catalog exposes contract-relevant declarations before the first delegation decision.
1001
1067
  Use those identifiers exactly; enforced `readPaths`, `writePaths`, network, and secret guarantees are currently unsupported and require an external enforcement boundary.
1068
+ A rejected enforced contract reports both contract repair and stop as recovery choices, but repair is safe only when the unsupported fields were descriptive rather than required protection.
1002
1069
 
1003
1070
  `agentScope` is a top-level tool argument supplied per invocation.
1004
1071
  It is not a setting in `~/.pi/agent/pi-subagents.json` and does not belong in agent frontmatter.
@@ -1012,7 +1079,7 @@ The scope selects which custom agent directories are loaded; built-in agents rem
1012
1079
  | `"project"` | Project-local agents only. |
1013
1080
  | `"both"` | User and project-local agents. Project definitions override same-named user definitions. |
1014
1081
 
1015
- For example, invoke a project-local agent with the blocking `subagent` tool:
1082
+ For an existing compatibility caller, invoke a project-local agent with the deprecated blocking `subagent` tool:
1016
1083
 
1017
1084
  ```json
1018
1085
  {
@@ -1043,7 +1110,7 @@ Passing `confirmProjectAgents: false` as another top-level tool argument skips t
1043
1110
 
1044
1111
  Every turn can combine main-agent-selected wall-clock, idle, assistant-turn, and tool-call budgets with an extension-owned hard-bounded finalization deadline.
1045
1112
 
1046
- - 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.
1113
+ - Set `blocking.maxParallelTasks` in `~/.pi/agent/pi-subagents.json`, or use `/subagents settings` → **Advanced runtime settings** → **Blocking worker limit**, to allow 1 through 64 worker tasks in one blocking parallel call.
1047
1114
  - The worker-count limit defaults to 8 and does not change the fixed four-at-a-time execution concurrency.
1048
1115
  - Set `timeoutMs` on the top-level blocking call to apply a work deadline to all jobs.
1049
1116
  - Set `timeoutMs` on a task, chain step, or aggregator to override it locally.
@@ -1051,6 +1118,7 @@ Every turn can combine main-agent-selected wall-clock, idle, assistant-turn, and
1051
1118
  Bounded process-cleanup grace may follow the deadline.
1052
1119
  - Set `idleTimeoutMs` to stop a turn that has produced no completed assistant turn or tool result within that interval.
1053
1120
  - Set `maxTurns` or `maxToolCalls` to stop unfinished repeated work; a terminal answer at the exact turn limit remains successful.
1121
+ - Give evidence tasks enough turn and tool-call headroom for discovery, reads, and final synthesis, or omit those optional limits instead of guessing tight values.
1054
1122
  - Set spawn budgets as retained defaults, or the same fields on `subagent_send` to override one follow-up turn.
1055
1123
  - Top-level blocking turn budgets apply to every job, while a task, chain step, or aggregator can override them locally.
1056
1124
  - Choose the shortest realistic budgets for the task difficulty; split an oversized task instead of extending limits merely to compensate for broad scope.
@@ -1091,6 +1159,10 @@ Fresh subprocess summaries run with no tools or project resources.
1091
1159
  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.
1092
1160
  Before a retained RPC summary starts, validated in-flight usage from the interrupted work attempt is committed so the summary adds to it exactly once.
1093
1161
  The deterministic checkpoint remains available when finalization or the provider fails, and results retain exit `124` plus a structured termination reason and finalization status.
1162
+ When bounded finalization succeeds with non-empty usable output, detached registry state reports a typed `partial` outcome with the exact budget reason instead of collapsing that evidence into an undifferentiated failure.
1163
+ Malformed required structured output, empty or failed finalization, and transport failure remain non-success.
1164
+ Partial evidence never satisfies mutating acceptance, required evidence, or independent verification.
1165
+ Inspection and opt-in content-free telemetry distinguish runtime-owned omitted limits from explicit per-turn limits.
1094
1166
  Explicit parent or user abort stops immediately, never starts finalization, and is not mislabeled as a budget stop.
1095
1167
 
1096
1168
  This release does not claim a cooperative soft-wrap-up phase because print-mode subprocess children cannot receive steering while they are running.
@@ -1121,6 +1193,24 @@ Subprocess and in-process timing fields use the nearest public lifecycle boundar
1121
1193
  Timing and progress are current-session diagnostics and are not persisted.
1122
1194
  The benchmark measures transport overhead rather than model latency or output quality.
1123
1195
 
1196
+ Preview the paired quality benchmark without making provider requests:
1197
+
1198
+ ```bash
1199
+ just benchmark-async-subagents --model provider/model
1200
+ ```
1201
+
1202
+ Run three paired trials with isolated sync-only and async-only tool surfaces, fixed model and thinking settings, redacted raw records, and a hard per-trial deadline:
1203
+
1204
+ ```bash
1205
+ just benchmark-async-subagents --run --mode quick --model provider/model --output /tmp/subagent-quick.json
1206
+ ```
1207
+
1208
+ Use `--mode extended` for ten paired trials before any further sync deprecation decision.
1209
+ The runner alternates arm order, starts work deadlines only after RPC readiness, runs at most three pairs concurrently, and reports completion coverage, evidence score, premature finals, terminal outcomes, median and P95 latency, and cost when available.
1210
+ Quick mode targets completion within five minutes under normal provider capacity but reports external timeouts and entitlement failures rather than silently reducing the sample.
1211
+ Live results remain provider- and model-dependent evidence rather than deterministic CI or proof of causality.
1212
+ The synchronous `subagent` tool remains available whenever a quality gate fails or detached chain, fan-in, panel, or workflow compatibility is unmatched.
1213
+
1124
1214
  While the `subagent` tool is running, `pi-subagents` publishes compact activity status with `ctx.ui.setStatus("subagents", "...")`.
1125
1215
  Any statusline extension that reads Pi's generic extension status API can display it; no package-to-package dependency is required.
1126
1216
 
@@ -1153,13 +1243,17 @@ Snapshots hash agent manifests, prompts, effective tools, model/thinking, transp
1153
1243
  A non-Git target has no stable repository generation proof, so each later follow-up requires explicit revalidation.
1154
1244
  Count projection keeps complete ancestor chains together when stored or restored limits omit older trees.
1155
1245
  Retention and count limits are configurable.
1156
- Downgrading is safe: older extension versions ignore this separate state directory; clear **Current agents** from `/subagents` before downgrade if the histories should be removed.
1246
+ Downgrading is safe: older extension versions ignore this separate state directory; clear **Current subagents** from `/subagents` before downgrade if the histories should be removed.
1157
1247
 
1158
1248
  ## 🗂️ Package layout
1159
1249
 
1160
1250
  ```txt
1161
1251
  packages/pi-subagents/
1162
1252
  ├── dist/ # Generated split TypeScript runtime loaded through Pi's Jiti loader
1253
+ ├── docs/
1254
+ │ ├── async-runtime-protocol.md # Required-run state machine and unavailable core guarantees
1255
+ │ ├── implementation-notes/ # Current direction, capabilities, and RPC contract
1256
+ │ └── pi-subagents-diagrams.md # Maintained architecture and workflow diagrams
1163
1257
  ├── scripts/
1164
1258
  │ └── build-runtime.mjs # Deterministic bundler and eager-boundary validator
1165
1259
  ├── src/
@@ -1185,7 +1279,10 @@ packages/pi-subagents/
1185
1279
  │ ├── rpc-turn-capture.ts # RPC evidence capture, usage, and budget events
1186
1280
  │ ├── auto-transport.ts # Deterministic preflight transport routing
1187
1281
  │ ├── transport-types.ts # Bounded pi-subagents:v1 progress and telemetry contract
1282
+ │ ├── usage-recording.ts # Opt-in content-free event collection and local identities
1283
+ │ ├── usage-recording-store.ts # Private per-runtime JSONL writers and retention pruning
1188
1284
  │ ├── completion-delivery.ts # Top-level completion batching and optional idle-root wake
1285
+ │ ├── completion-requirement.ts # Exact required-run tracking and canonical context contract
1189
1286
  │ ├── completion-routing.ts # Direct-parent and live-ancestor recipient selection
1190
1287
  │ ├── task-path.ts # Canonical retained-agent task identity and resolution
1191
1288
  │ ├── peer-communication.ts # Session peer routing and authenticated loopback broker
@@ -1203,6 +1300,7 @@ packages/pi-subagents/
1203
1300
  │ ├── verification-harness.ts # Disposable deterministic check execution
1204
1301
  │ ├── verification-receipt.ts # Strict executor-owned managed receipts
1205
1302
  │ ├── verified-execution-benchmark.ts # Matched offline acceptance/cost fixture
1303
+ │ ├── async-subagent-benchmark.ts # Paired live-quality planning, scoring, and summaries
1206
1304
  │ ├── workflow-tree-identity.ts # Bounded exact Git-visible tree identities
1207
1305
  │ ├── integration-controller.ts # Fail-closed canonical integration admission
1208
1306
  │ ├── adaptive-scheduler.ts # Dependency, capacity, budget, and conflict scheduling
@@ -1222,6 +1320,10 @@ packages/pi-subagents/
1222
1320
  │ ├── timeout-finalization.ts # Abort-time bounded summary prompts and deadlines
1223
1321
  │ ├── timeout-checkpoint.ts # Redacted deterministic termination evidence
1224
1322
  │ ├── turn-budget.ts # Idle, assistant-turn, and tool-call enforcement
1323
+ │ ├── runner.ts # Blocking subprocess execution and progress capture
1324
+ │ ├── runner-types.ts # Shared subprocess result and launch contracts
1325
+ │ ├── subagent-details.ts # Composed tool-result and panel detail contracts
1326
+ │ ├── process-control.ts # Reusable child-process termination and escalation
1225
1327
  │ ├── runner-usage.ts # Bounded subprocess usage accumulation
1226
1328
  │ ├── runner-result.ts # Shared subprocess result interpretation
1227
1329
  │ ├── stateful-limit-ui.ts # Detached capacity settings and recovery previews
@@ -1239,8 +1341,8 @@ packages/pi-subagents/
1239
1341
  The package build bundles that source graph into split `.ts` files under `dist` for Pi's Jiti loader.
1240
1342
  `subagents.ts` and `stateful.ts` preserve existing source-level utility imports without making those utility graphs part of Pi startup.
1241
1343
  Workflow settings remain backward compatible: older files without `blocking.enabled` receive the eight-tool default, and an absent `blocking.maxParallelTasks` keeps the previous eight-worker limit.
1242
- Existing `stateful.enabled: false` files expose blocking delegation plus inspection/consultation.
1243
- Older package releases ignore and preserve the optional `blocking.maxParallelTasks`, `consult`, and `cwdPolicy` fields.
1344
+ Existing `stateful.enabled: false` files expose deprecated blocking `subagent` plus supported inspection and consultation.
1345
+ Older package releases ignore and preserve the optional `blocking.maxParallelTasks`, `consult`, `cwdPolicy`, and `usageRecording` fields.
1244
1346
  The package exposes its Pi extension through `package.json`:
1245
1347
 
1246
1348
  ```json
@@ -2,14 +2,14 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  isWriteCapable
5
- } from "./chunk-O4VO6JUJ.ts";
5
+ } from "./chunk-TM2R67J3.ts";
6
6
  import {
7
7
  discoverAgents
8
- } from "./chunk-PSK43Y6A.ts";
8
+ } from "./chunk-LASD73CM.ts";
9
9
  import "./chunk-RSUXZD6S.ts";
10
- import "./chunk-QBORTI4W.ts";
11
- import "./chunk-7OBINKFM.ts";
12
- import "./chunk-DPPVEQAM.ts";
10
+ import "./chunk-TMZRHIIK.ts";
11
+ import "./chunk-VDG7LTYE.ts";
12
+ import "./chunk-4AQSF7AS.ts";
13
13
  import "./chunk-SWGQLFSD.ts";
14
14
  import "./chunk-H3FP6DLR.ts";
15
15
 
@@ -106,4 +106,4 @@ var AutoTransport = class {
106
106
  export {
107
107
  AutoTransport
108
108
  };
109
- //# sourceMappingURL=auto-transport-SY2VHUFH.ts.map
109
+ //# sourceMappingURL=auto-transport-FUUKFDIG.ts.map
@@ -6,9 +6,9 @@ import {
6
6
  isCapabilityGrantActive,
7
7
  issueCapabilityGrant,
8
8
  revokeCapabilityGrant
9
- } from "./chunk-HKC4ES4B.ts";
10
- import "./chunk-DSOOH73Y.ts";
11
- import "./chunk-DPPVEQAM.ts";
9
+ } from "./chunk-YPJEN6NU.ts";
10
+ import "./chunk-7AAJEUSL.ts";
11
+ import "./chunk-4AQSF7AS.ts";
12
12
  export {
13
13
  CAPABILITY_GRANT_VERSION,
14
14
  isCapabilityGrant,
@@ -16,4 +16,4 @@ export {
16
16
  issueCapabilityGrant,
17
17
  revokeCapabilityGrant
18
18
  };
19
- //# sourceMappingURL=capability-grant-CGEWOEKE.ts.map
19
+ //# sourceMappingURL=capability-grant-PR72SWWS.ts.map
@@ -26,4 +26,4 @@ export {
26
26
  CONSULTATION_CWD_POLICIES,
27
27
  DELEGATION_CWD_POLICIES
28
28
  };
29
- //# sourceMappingURL=chunk-DPPVEQAM.ts.map
29
+ //# sourceMappingURL=chunk-4AQSF7AS.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/agents/types.ts"],
4
+ "sourcesContent": ["/**\n * Foundational agent and settings types with dependency-light validation helpers.\n */\n\nimport type { AgentCapabilityManifest } from \"../capabilities.js\";\nimport type { SubagentUsageRecordingSettings } from \"../usage-recording-config.js\";\n\nexport const THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\n\nexport type SubagentThinkingLevel = (typeof THINKING_LEVELS)[number];\n\nexport function isThinkingLevel(value: unknown): value is SubagentThinkingLevel {\n\treturn typeof value === \"string\" && THINKING_LEVELS.includes(value as SubagentThinkingLevel);\n}\n\nexport type AgentScope = \"user\" | \"project\" | \"both\";\n\nexport type AgentSource = \"built-in\" | \"user\" | \"project\";\n\nexport const DEFAULT_PI_TOOL_NAMES = [\"read\", \"bash\", \"edit\", \"write\"] as const;\n\nexport function resolveAgentToolNames(tools: readonly string[] | undefined): string[] {\n\treturn [...new Set(tools ?? DEFAULT_PI_TOOL_NAMES)];\n}\n\nexport interface AgentConfig {\n\tname: string;\n\tdescription: string;\n\ttools?: string[];\n\tmodel?: string;\n\tthinkingLevel?: SubagentThinkingLevel;\n\ttimeoutMs?: number;\n\tcapabilityManifest?: AgentCapabilityManifest;\n\tsystemPrompt: string;\n\tsource: AgentSource;\n\tfilePath: string;\n}\n\nexport interface SubagentAgentConfig {\n\ttools?: string[];\n\tmodel?: string | null;\n\tthinkingLevel?: SubagentThinkingLevel | null;\n\ttimeoutMs?: number | null;\n}\n\nexport type SubagentTransportKind = \"subprocess\" | \"in-process\" | \"rpc\" | \"auto\";\n\nexport type CompletionDelivery = \"next-turn\" | \"auto-resume\";\n\nexport const CONSULT_RESOURCE_POLICIES = [\"project-context\", \"none\", \"all\"] as const;\n\nexport type ConsultResourcePolicy = (typeof CONSULT_RESOURCE_POLICIES)[number];\n\nexport interface SubagentConsultSettings {\n\tresources?: ConsultResourcePolicy;\n}\n\nexport const CONSULTATION_CWD_POLICIES = [\"anywhere\", \"current-workspace\"] as const;\nexport type ConsultationCwdPolicy = (typeof CONSULTATION_CWD_POLICIES)[number];\n\nexport const DELEGATION_CWD_POLICIES = [\n\t\"trusted-targets\",\n\t\"current-workspace\",\n\t\"anywhere\",\n] as const;\nexport type DelegationCwdPolicy = (typeof DELEGATION_CWD_POLICIES)[number];\n\nexport interface SubagentCwdPolicySettings {\n\tconsultation?: ConsultationCwdPolicy;\n\tdelegation?: DelegationCwdPolicy;\n}\n\nexport interface SubagentBlockingSettings {\n\tenabled?: boolean;\n\tmaxParallelTasks?: number;\n}\n\nexport interface SubagentRuntimeSettings {\n\tenabled?: boolean;\n\ttransport?: SubagentTransportKind;\n\tcompletionDelivery?: CompletionDelivery;\n\tmaxAgents?: number;\n\tmaxActiveTurns?: number;\n\tmaxDepth?: number;\n\tmaxChildrenPerAgent?: number;\n\tmaxMailboxMessages?: number;\n\tmaxMailboxMessageBytes?: number;\n\tidleTtlMs?: number;\n\tretentionDays?: number;\n\tmaxStoredAgents?: number;\n}\n\nexport interface SubagentSettings {\n\tagents?: Record<string, SubagentAgentConfig>;\n\tblocking?: SubagentBlockingSettings;\n\tstateful?: SubagentRuntimeSettings;\n\tconsult?: SubagentConsultSettings;\n\tcwdPolicy?: SubagentCwdPolicySettings;\n\tusageRecording?: SubagentUsageRecordingSettings;\n}\n"],
5
+ "mappings": ";;;;AAOO,IAAM,kBAAkB,CAAC,OAAO,WAAW,OAAO,UAAU,QAAQ,SAAS,KAAK;AAIlF,SAAS,gBAAgB,OAAgD;AAC/E,SAAO,OAAO,UAAU,YAAY,gBAAgB,SAAS,KAA8B;AAC5F;AAMO,IAAM,wBAAwB,CAAC,QAAQ,QAAQ,QAAQ,OAAO;AAE9D,SAAS,sBAAsB,OAAgD;AACrF,SAAO,CAAC,GAAG,IAAI,IAAI,SAAS,qBAAqB,CAAC;AACnD;AA0BO,IAAM,4BAA4B,CAAC,mBAAmB,QAAQ,KAAK;AAQnE,IAAM,4BAA4B,CAAC,YAAY,mBAAmB;AAGlE,IAAM,0BAA0B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACD;",
6
+ "names": []
7
+ }