@zihanw/pi-forge 0.3.2 → 0.4.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 (231) hide show
  1. package/CHANGELOG.md +196 -0
  2. package/PUBLIC_API.md +5 -0
  3. package/README.md +93 -478
  4. package/README.zh-CN.md +88 -461
  5. package/SUBAGENT_ADAPTER_CONTRACT.md +5 -0
  6. package/dist/agent-profile.d.ts +71 -0
  7. package/dist/agent-profile.d.ts.map +1 -0
  8. package/dist/agent-profile.js +303 -0
  9. package/dist/agent-profile.js.map +1 -0
  10. package/dist/forge-config.d.ts +88 -0
  11. package/dist/forge-config.d.ts.map +1 -0
  12. package/dist/forge-config.js +290 -0
  13. package/dist/forge-config.js.map +1 -0
  14. package/dist/forge-extensions.d.ts.map +1 -1
  15. package/dist/forge-extensions.js +19 -3
  16. package/dist/forge-extensions.js.map +1 -1
  17. package/dist/index.d.ts +4 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +97 -358
  20. package/dist/index.js.map +1 -1
  21. package/dist/lifecycle.d.ts +11 -3
  22. package/dist/lifecycle.d.ts.map +1 -1
  23. package/dist/lifecycle.js +90 -4
  24. package/dist/lifecycle.js.map +1 -1
  25. package/dist/loader.d.ts.map +1 -1
  26. package/dist/loader.js +116 -5
  27. package/dist/loader.js.map +1 -1
  28. package/dist/payload-capture.d.ts.map +1 -1
  29. package/dist/payload-capture.js +27 -0
  30. package/dist/payload-capture.js.map +1 -1
  31. package/dist/payload-command.d.ts +3 -3
  32. package/dist/payload-command.d.ts.map +1 -1
  33. package/dist/payload-command.js.map +1 -1
  34. package/dist/preview.d.ts +2 -2
  35. package/dist/preview.d.ts.map +1 -1
  36. package/dist/preview.js +2 -3
  37. package/dist/preview.js.map +1 -1
  38. package/dist/profile-command.d.ts +12 -0
  39. package/dist/profile-command.d.ts.map +1 -0
  40. package/dist/profile-command.js +291 -0
  41. package/dist/profile-command.js.map +1 -0
  42. package/dist/profile-service.d.ts +103 -0
  43. package/dist/profile-service.d.ts.map +1 -0
  44. package/dist/profile-service.js +220 -0
  45. package/dist/profile-service.js.map +1 -0
  46. package/dist/runtime/profile-runtime.d.ts +13 -0
  47. package/dist/runtime/profile-runtime.d.ts.map +1 -0
  48. package/dist/runtime/profile-runtime.js +47 -0
  49. package/dist/runtime/profile-runtime.js.map +1 -0
  50. package/dist/runtime/prompt-stack-runtime.d.ts +22 -0
  51. package/dist/runtime/prompt-stack-runtime.d.ts.map +1 -0
  52. package/dist/runtime/prompt-stack-runtime.js +104 -0
  53. package/dist/runtime/prompt-stack-runtime.js.map +1 -0
  54. package/dist/runtime/subagent-runtime.d.ts +45 -0
  55. package/dist/runtime/subagent-runtime.d.ts.map +1 -0
  56. package/dist/runtime/subagent-runtime.js +335 -0
  57. package/dist/runtime/subagent-runtime.js.map +1 -0
  58. package/dist/runtime/tool-policy-runtime.d.ts +15 -0
  59. package/dist/runtime/tool-policy-runtime.d.ts.map +1 -0
  60. package/dist/runtime/tool-policy-runtime.js +170 -0
  61. package/dist/runtime/tool-policy-runtime.js.map +1 -0
  62. package/dist/runtime/web-editor-runtime.d.ts +9 -0
  63. package/dist/runtime/web-editor-runtime.d.ts.map +1 -0
  64. package/dist/runtime/web-editor-runtime.js +131 -0
  65. package/dist/runtime/web-editor-runtime.js.map +1 -0
  66. package/dist/runtime-state.d.ts +4 -0
  67. package/dist/runtime-state.d.ts.map +1 -1
  68. package/dist/runtime-state.js +2 -0
  69. package/dist/runtime-state.js.map +1 -1
  70. package/dist/storage.d.ts +4 -0
  71. package/dist/storage.d.ts.map +1 -1
  72. package/dist/storage.js +24 -1
  73. package/dist/storage.js.map +1 -1
  74. package/dist/subagent/canonical.d.ts +22 -0
  75. package/dist/subagent/canonical.d.ts.map +1 -0
  76. package/dist/subagent/canonical.js +24 -0
  77. package/dist/subagent/canonical.js.map +1 -0
  78. package/dist/subagent/context.d.ts +8 -0
  79. package/dist/subagent/context.d.ts.map +1 -0
  80. package/dist/subagent/context.js +125 -0
  81. package/dist/subagent/context.js.map +1 -0
  82. package/dist/subagent/contract.d.ts +10 -0
  83. package/dist/subagent/contract.d.ts.map +1 -0
  84. package/dist/subagent/contract.js +10 -0
  85. package/dist/subagent/contract.js.map +1 -0
  86. package/dist/subagent/index.d.ts +14 -0
  87. package/dist/subagent/index.d.ts.map +1 -0
  88. package/dist/subagent/index.js +14 -0
  89. package/dist/subagent/index.js.map +1 -0
  90. package/dist/subagent/plan.d.ts +18 -0
  91. package/dist/subagent/plan.d.ts.map +1 -0
  92. package/dist/subagent/plan.js +157 -0
  93. package/dist/subagent/plan.js.map +1 -0
  94. package/dist/subagent/preflight.d.ts +4 -0
  95. package/dist/subagent/preflight.d.ts.map +1 -0
  96. package/dist/subagent/preflight.js +108 -0
  97. package/dist/subagent/preflight.js.map +1 -0
  98. package/dist/subagent/request.d.ts +4 -0
  99. package/dist/subagent/request.d.ts.map +1 -0
  100. package/dist/subagent/request.js +122 -0
  101. package/dist/subagent/request.js.map +1 -0
  102. package/dist/subagent/response.d.ts +8 -0
  103. package/dist/subagent/response.d.ts.map +1 -0
  104. package/dist/subagent/response.js +155 -0
  105. package/dist/subagent/response.js.map +1 -0
  106. package/dist/subagent/tools.d.ts +4 -0
  107. package/dist/subagent/tools.d.ts.map +1 -0
  108. package/dist/subagent/tools.js +42 -0
  109. package/dist/subagent/tools.js.map +1 -0
  110. package/dist/subagent/types.d.ts +268 -0
  111. package/dist/subagent/types.d.ts.map +1 -0
  112. package/dist/subagent/types.js +3 -0
  113. package/dist/subagent/types.js.map +1 -0
  114. package/dist/subagent/validation.d.ts +35 -0
  115. package/dist/subagent/validation.d.ts.map +1 -0
  116. package/dist/subagent/validation.js +314 -0
  117. package/dist/subagent/validation.js.map +1 -0
  118. package/dist/subagent-command.d.ts +4 -0
  119. package/dist/subagent-command.d.ts.map +1 -0
  120. package/dist/subagent-command.js +246 -0
  121. package/dist/subagent-command.js.map +1 -0
  122. package/dist/subagent-host.d.ts +44 -0
  123. package/dist/subagent-host.d.ts.map +1 -0
  124. package/dist/subagent-host.js +292 -0
  125. package/dist/subagent-host.js.map +1 -0
  126. package/dist/subagent-profile-tool.d.ts +49 -0
  127. package/dist/subagent-profile-tool.d.ts.map +1 -0
  128. package/dist/subagent-profile-tool.js +124 -0
  129. package/dist/subagent-profile-tool.js.map +1 -0
  130. package/dist/subagent-tool.d.ts +53 -0
  131. package/dist/subagent-tool.d.ts.map +1 -0
  132. package/dist/subagent-tool.js +456 -0
  133. package/dist/subagent-tool.js.map +1 -0
  134. package/dist/web-editor/client-script.d.ts +2 -0
  135. package/dist/web-editor/client-script.d.ts.map +1 -0
  136. package/dist/web-editor/client-script.generated.d.ts +2 -0
  137. package/dist/web-editor/client-script.generated.d.ts.map +1 -0
  138. package/dist/web-editor/client-script.generated.js +3 -0
  139. package/dist/web-editor/client-script.generated.js.map +1 -0
  140. package/dist/web-editor/client-script.js +2 -0
  141. package/dist/web-editor/client-script.js.map +1 -0
  142. package/dist/web-editor/client-styles.d.ts +2 -0
  143. package/dist/web-editor/client-styles.d.ts.map +1 -0
  144. package/dist/web-editor/client-styles.generated.d.ts +2 -0
  145. package/dist/web-editor/client-styles.generated.d.ts.map +1 -0
  146. package/dist/web-editor/client-styles.generated.js +3 -0
  147. package/dist/web-editor/client-styles.generated.js.map +1 -0
  148. package/dist/web-editor/client-styles.js +2 -0
  149. package/dist/web-editor/client-styles.js.map +1 -0
  150. package/dist/web-editor/page.d.ts +2 -0
  151. package/dist/web-editor/page.d.ts.map +1 -1
  152. package/dist/web-editor/page.js +14 -3319
  153. package/dist/web-editor/page.js.map +1 -1
  154. package/dist/web-editor/server.d.ts.map +1 -1
  155. package/dist/web-editor/server.js +148 -0
  156. package/dist/web-editor/server.js.map +1 -1
  157. package/dist/web-editor/styles.d.ts +2 -0
  158. package/dist/web-editor/styles.d.ts.map +1 -0
  159. package/dist/web-editor/styles.js +1053 -0
  160. package/dist/web-editor/styles.js.map +1 -0
  161. package/dist/web-editor/types.d.ts +79 -0
  162. package/dist/web-editor/types.d.ts.map +1 -1
  163. package/dist/web-host.d.ts +16 -5
  164. package/dist/web-host.d.ts.map +1 -1
  165. package/dist/web-host.js +307 -0
  166. package/dist/web-host.js.map +1 -1
  167. package/docs/README.md +41 -0
  168. package/docs/concepts/agent-profiles.md +60 -0
  169. package/docs/concepts/prompt-stacks.md +90 -0
  170. package/docs/design/README.md +17 -0
  171. package/docs/design/roadmap-0.4-archive.md +216 -0
  172. package/docs/design/subagents/design-review.md +220 -0
  173. package/docs/design/subagents/interface-design.md +274 -0
  174. package/docs/design/subagents/sdk-spike-findings.md +117 -0
  175. package/docs/development/complexity-review.md +86 -0
  176. package/docs/development/release.md +31 -0
  177. package/docs/development/roadmap.md +42 -0
  178. package/docs/development/setup.md +75 -0
  179. package/docs/getting-started.md +93 -0
  180. package/docs/guides/custom-macros-and-slots.md +68 -0
  181. package/docs/guides/debugging.md +39 -0
  182. package/docs/guides/delegation.md +99 -0
  183. package/docs/guides/sillytavern-import.md +47 -0
  184. package/docs/guides/use-cases.md +65 -0
  185. package/docs/guides/web-editor.md +75 -0
  186. package/docs/reference/commands.md +60 -0
  187. package/docs/reference/configuration.md +64 -0
  188. package/docs/reference/features.md +279 -0
  189. package/docs/reference/macros-and-slots.md +82 -0
  190. package/docs/reference/public-api.md +28 -0
  191. package/docs/reference/stack-schema.md +167 -0
  192. package/docs/reference/subagent-adapter.md +204 -0
  193. package/docs/zh-CN/README.md +37 -0
  194. package/docs/zh-CN/concepts/agent-profiles.md +44 -0
  195. package/docs/zh-CN/concepts/prompt-stacks.md +40 -0
  196. package/docs/zh-CN/getting-started.md +79 -0
  197. package/docs/zh-CN/guides/delegation.md +66 -0
  198. package/docs/zh-CN/guides/web-editor.md +45 -0
  199. package/docs/zh-CN/reference/commands.md +58 -0
  200. package/package.json +55 -13
  201. package/src/compiler.ts +0 -578
  202. package/src/extension-registry.ts +0 -33
  203. package/src/forge-extensions.ts +0 -223
  204. package/src/index.ts +0 -445
  205. package/src/lifecycle.ts +0 -171
  206. package/src/loader.ts +0 -394
  207. package/src/macro-engine.ts +0 -358
  208. package/src/payload-capture.ts +0 -85
  209. package/src/payload-command.ts +0 -138
  210. package/src/policy.ts +0 -42
  211. package/src/preset-command.ts +0 -280
  212. package/src/preview.ts +0 -226
  213. package/src/regex.ts +0 -500
  214. package/src/render-helpers.ts +0 -169
  215. package/src/runtime-state.ts +0 -40
  216. package/src/sillytavern-importer/items.ts +0 -98
  217. package/src/sillytavern-importer/macros.ts +0 -159
  218. package/src/sillytavern-importer/prompt-order.ts +0 -54
  219. package/src/sillytavern-importer/regex.ts +0 -270
  220. package/src/sillytavern-importer/report.ts +0 -202
  221. package/src/sillytavern-importer/types.ts +0 -120
  222. package/src/sillytavern-importer.ts +0 -152
  223. package/src/slot-renderers.ts +0 -414
  224. package/src/stack-migration.ts +0 -159
  225. package/src/storage.ts +0 -45
  226. package/src/types.ts +0 -209
  227. package/src/web-editor/index.ts +0 -2
  228. package/src/web-editor/page.ts +0 -3330
  229. package/src/web-editor/server.ts +0 -294
  230. package/src/web-editor/types.ts +0 -98
  231. package/src/web-host.ts +0 -232
@@ -0,0 +1,60 @@
1
+ # Agent profiles
2
+
3
+ [Documentation](../README.md) · [中文](../zh-CN/concepts/agent-profiles.md)
4
+
5
+ An agent profile is a project-local, schema-versioned preset that references one exact model, thinking level, and prompt stack. It is deliberately small and portable.
6
+
7
+ ## Schema
8
+
9
+ Profiles live in `.pi/forge/agent-profiles/*.json`:
10
+
11
+ ```json
12
+ {
13
+ "schemaVersion": 1,
14
+ "type": "pi-forge.agent-profile",
15
+ "id": "reviewer",
16
+ "name": "Reviewer",
17
+ "description": "Reviews code without making changes.",
18
+ "autoActivate": true,
19
+ "model": {
20
+ "provider": "provider-id",
21
+ "id": "model-id"
22
+ },
23
+ "thinkingLevel": "high",
24
+ "promptStack": "reviewer"
25
+ }
26
+ ```
27
+
28
+ `promptStack` may be `null`. Unsupported fields are errors: generation settings, tools, skills, backend selection, and runner policy are intentionally not profile-v1 data. The referenced prompt stack is the sole source of tool policy and model-visible skill filtering.
29
+
30
+ ## Capture and application
31
+
32
+ ```text
33
+ /profile save reviewer
34
+ /profile preview reviewer
35
+ /profile use reviewer
36
+ ```
37
+
38
+ Save captures the current provider/model, thinking level, and stack without secrets, history, tools, or provenance. `--overwrite` is required to replace an existing file; existing display metadata is preserved.
39
+
40
+ Application is transactional and one-shot. pi-forge first validates the profile, model, configured authentication, thinking-level support, prompt stack, and tool allow patterns. It changes nothing when preflight fails. If an application step fails, it attempts rollback and does not record successful provenance.
41
+
42
+ After a successful application, later manual changes are respected. The profile does not continuously own model or thinking state, although the selected prompt stack continues enforcing its policy.
43
+
44
+ ## Auto-activation
45
+
46
+ At most one profile may set `autoActivate: true`. It applies once when Pi starts a fresh session and takes precedence over standalone prompt-stack autoload, including when `promptStack` is `null`.
47
+
48
+ Restored branch selections take precedence over auto-activation. Invalid or ambiguous profile auto-activation fails closed: pi-forge will not partially apply it or silently fall back to a stack.
49
+
50
+ ## Provenance and drift
51
+
52
+ `/profile status` compares the current runtime with the last-applied resolved snapshot. It reports source-definition changes separately from runtime drift in model, thinking level, or stack.
53
+
54
+ Provenance is branch-scoped status metadata, not ownership. Reload, resume, tree navigation, and compaction never reapply a profile. `/profile forget` removes provenance without changing runtime state.
55
+
56
+ ## Delegation is separate
57
+
58
+ Ordinary profiles cannot be delegated by default. The trusted project's `.pi/forge/config.json` separately authorizes eligible profile IDs and host-specific backend/timeout choices. Deleting a profile removes its delegation policy so a later same-ID profile cannot inherit authority.
59
+
60
+ Read the [experimental delegation guide](../guides/delegation.md) before enabling it.
@@ -0,0 +1,90 @@
1
+ # Prompt stacks
2
+
3
+ [Documentation](../README.md) · [中文](../zh-CN/concepts/prompt-stacks.md)
4
+
5
+ A prompt stack is an ordered, declarative description of the prompt and policy Pi should use. It combines static **blocks** with dynamic **slots**.
6
+
7
+ ## Blocks and slots
8
+
9
+ A block inserts static text with a role:
10
+
11
+ ```json
12
+ {
13
+ "kind": "block",
14
+ "id": "review-rules",
15
+ "name": "Review rules",
16
+ "enabled": true,
17
+ "role": "system",
18
+ "content": "Prioritize correctness, regressions, security, and missing tests."
19
+ }
20
+ ```
21
+
22
+ A slot renders current Pi data at that position:
23
+
24
+ ```json
25
+ {
26
+ "kind": "slot",
27
+ "id": "history",
28
+ "name": "Conversation",
29
+ "enabled": true,
30
+ "role": "user",
31
+ "slot": "chat-history",
32
+ "options": { "includeLastUserMessage": false }
33
+ }
34
+ ```
35
+
36
+ Slots cover conversation history, tools, tool guidance, skills, project context, appended system text, variables, model, date, and working directory. See [macros and slots](../reference/macros-and-slots.md).
37
+
38
+ ## Compilation order
39
+
40
+ For each new user turn, pi-forge:
41
+
42
+ 1. Orders enabled blocks and slots exactly as written.
43
+ 2. Builds `system` content and applies the stack's `replace`, `append`, or `prepend` mode.
44
+ 3. Inserts synthetic user/assistant messages around the movable `chat-history` slot.
45
+ 4. Expands built-in, variable, and trusted custom macros.
46
+ 5. Applies the stack's tool policy to Pi and filters skills rendered by pi-forge.
47
+ 6. Applies outgoing history/compiled regex rules.
48
+ 7. Optionally applies destructive finalize rules when an assistant message completes.
49
+
50
+ The context rewrite happens only on the first provider request for a user-submitted turn. Pi can then continue its normal tool loop without repeatedly rebuilding the same context.
51
+
52
+ ## System modes
53
+
54
+ - `replace` is the default and gives the stack complete control. An empty replacement falls back to Pi's base prompt.
55
+ - `append` adds stack system content after Pi's base prompt.
56
+ - `prepend` adds stack system content before Pi's base prompt.
57
+
58
+ Use `replace` when the model-visible skill list must be controlled. With `append` or `prepend`, Pi's base prompt may already contain an unfiltered skill listing.
59
+
60
+ ## History placement
61
+
62
+ `chat-history` is movable. A useful task-focused layout is:
63
+
64
+ 1. Long-lived system rules.
65
+ 2. Runtime tools and project context.
66
+ 3. Chat history with `includeLastUserMessage: false`.
67
+ 4. A final user block containing `{{lastUserMessage}}`.
68
+
69
+ This preserves prior context while presenting the current request once, in an explicit final position. History can also filter summaries and roles, drop previous tool traffic, strip assistant thinking, and limit recent messages or characters. pi-forge repairs dangling tool-call/result pairs after filtering.
70
+
71
+ ## Tool and skill policy
72
+
73
+ Stacks may use either `allow` or `deny` patterns for each resource. Tool policy changes Pi's active tools and is guarded at tool-call time; it remains enforced while the stack is selected. Skill policy only filters skills rendered by pi-forge—it does not prevent explicit skill invocation and is not a security boundary.
74
+
75
+ External tool additions are preserved in the baseline restored when a restrictive stack is disabled. See the exact behavior in [stack policy reference](../reference/stack-schema.md#tool-and-skill-policy).
76
+
77
+ ## Activation and session behavior
78
+
79
+ - `default.json` auto-activates unless its metadata opts out.
80
+ - Another stack may set `autoActivate: true`; conflicting auto-activation is invalid.
81
+ - `/preset use none` records an explicit session opt-out.
82
+ - Active stack and session variables follow Pi's session-tree branch.
83
+ - Restored branch state takes precedence over fresh-session auto-activation.
84
+ - An auto-activated agent profile takes precedence over standalone stack autoload.
85
+
86
+ ## Extensions and transforms
87
+
88
+ Static, turn, and session variables support nested macros and lazy conditionals. Trusted JavaScript/TypeScript registration modules can add macros and slots without putting executable code in stack JSON. Deterministic regex rules can transform model-bound prompt text or, with an explicit warning, replace finalized assistant transcript text.
89
+
90
+ See [custom macros and slots](../guides/custom-macros-and-slots.md), [macro reference](../reference/macros-and-slots.md), and [regex schema](../reference/stack-schema.md#regex-transforms).
@@ -0,0 +1,17 @@
1
+ # Design archive
2
+
3
+ [Documentation](../README.md)
4
+
5
+ These documents preserve decisions, reviews, spikes, and implementation history. They are not the authoritative description of current user behavior; use the [guides](../README.md#guides) and [reference](../README.md#reference) for that.
6
+
7
+ ## Subagent design history
8
+
9
+ - [Request/response design](subagents/interface-design.md) — accepted architecture and completed implementation iterations.
10
+ - [Design review](subagents/design-review.md) — issues that drove preflight, task preservation, policy, fingerprint, and response revisions.
11
+ - [Pi SDK spike findings](subagents/sdk-spike-findings.md) — historical 0.80.6 investigation; its harness was removed after findings were productized.
12
+
13
+ ## Project planning history
14
+
15
+ - [0.4 roadmap and implementation log](roadmap-0.4-archive.md)
16
+
17
+ The current exported semantics are in the [subagent adapter contract](../reference/subagent-adapter.md); forward-looking work is in the [roadmap](../development/roadmap.md).
@@ -0,0 +1,216 @@
1
+ # Historical 0.4 roadmap and implementation log
2
+
3
+ > **Archive:** This document preserves the planning record through the 0.4 development cycle. Completed behavior belongs in the [feature inventory](../reference/features.md); current plans belong in the [roadmap](../development/roadmap.md).
4
+
5
+ This file was the forward-looking product roadmap during 0.4 development. Completed capability now belongs in the [feature inventory](../reference/features.md), release history in the root [changelog](../../CHANGELOG.md), and current plans in the [roadmap](../development/roadmap.md).
6
+
7
+ ## Documentation Map
8
+
9
+ - [Root README](../../README.md) and [Chinese README](../../README.zh-CN.md): short project landing pages.
10
+ - [Feature inventory](../reference/features.md): implemented profile, prompt-stack, web-editor, payload, extension, packaging, and experimental subagent behavior.
11
+ - [Changelog](../../CHANGELOG.md): release and unreleased change history.
12
+ - [Subagent interface design](subagents/interface-design.md): accepted request/response architecture, context model, responsibility boundaries, and implementation history.
13
+ - [Subagent adapter contract](../reference/subagent-adapter.md): current exported contract, validation, enforcement receipts, and adapter responsibilities.
14
+ - [SDK spike findings](subagents/sdk-spike-findings.md): historical real Pi SDK findings for model/auth resolution, exact prompt preparation, dynamic tools, media, timeout, and cleanup.
15
+ - [Subagent design review](subagents/design-review.md): issues that drove resolution, preflight, enforcement, task-preservation, fingerprint, and response revisions.
16
+ - [Public API policy](../reference/public-api.md): stable, experimental, and internal compatibility surfaces.
17
+
18
+ ## Current Objective
19
+
20
+ Harden the completed approval-gated foreground subagent path without turning pi-forge into a general orchestrator. Work should proceed in this order:
21
+
22
+ 1. Dogfood the shared-user read-only path and tighten report, cancellation, and sensitive-path behavior found in real use.
23
+ 2. Evaluate an optional bubblewrap-style backend that can enforce allowed roots, subprocess limits, and network policy honestly.
24
+ 3. Design any future write access as an inspectable staged patch with a separate approval boundary.
25
+ 4. Expose agent profiles in the existing browser editor.
26
+ 5. Harden the workflows and prepare the release.
27
+
28
+ The current tool and commands already share the same request, preflight, host preparation, immutable plan, execution, and response-projection path. Further safety work should strengthen the backend boundary rather than introduce a second runner. Profile UI remains a bounded user-facing iteration independent of sandbox development.
29
+
30
+ ## Recently Completed: Approval-Gated Foreground Subagent
31
+
32
+ The `pi-subprocess-readonly` and `pi-rpc-readonly` paths send one requested text task through profile eligibility and resolution, backend preflight, exact backend-assisted prompt preparation, immutable plan validation, interactive review by default, a foreground Pi process (text/print or RPC), and normalized response handling without owning a general runner. Backend registration, preflight binding, plan sealing, lifecycle arbitration, and both process backends are owned by `@zihanw/pi-subagent-runtime`; pi-forge keeps profiles, execution policy, compilation, approval, and presentation. Backend and timeout defaults are layered global/project configuration, while explicit `subagents.profiles.<id>` delegation opt-in and per-profile overrides are trusted-project-only; interactive runs may override the backend, there is no fallback, and a trusted-project option can explicitly authorize the model-callable tool without per-run review pinned to the effective configured profile backend. The former in-package `SubagentBackendRegistry`, `PiSubprocessBackend`, and `PiSdkIsolatedBackend` exports were removed in the migration; the SDK spike harness was removed after its findings were productized in the runtime's shared preparation gate.
33
+
34
+ User test surface:
35
+
36
+ - Explicitly enable intended delegation profiles under the trusted project's `subagents.profiles`, then ask the main agent to discover them with `forge_subagent_profiles` and execute with `forge_subagent`; restrictive tool policy must permit both names.
37
+ - `/forge-agent backends`
38
+ - `/forge-agent plan <profile> <task>` prepares the exact request behind a provider gate, reports its plan, and discards it without transport.
39
+ - `/forge-agent run <profile> <task>` reviews the same exact prepared plan in the TUI and executes it only after approval.
40
+
41
+ Current boundary:
42
+
43
+ - Use Pi's existing model registry, authentication, streaming, and in-memory session primitives.
44
+ - Support one-shot sequential foreground text execution with an existing agent profile and clean context.
45
+ - Expose only stack-filtered `read`, `grep`, `find`, and `ls`; load no write/edit/shell tools, skills, prompt templates, context files, or third-party Pi extensions.
46
+ - Declare `executionBoundary: shared-user`: read-only is model-tool policy, not mount, path, process, or network isolation. The child retains the invoking user's OS permissions.
47
+ - Load trusted pi-forge macro/slot registrations only in the host compiler and preserve the delegated task as the final protected user message.
48
+ - Treat timeout and abort as host best-effort enforcement.
49
+ - Keep provider execution opt-in through interactive approval bound to the exact execution fingerprint or the explicit trusted-project unattended-tool setting. Ordinary automated tests use only an offline faux provider.
50
+ - Let the main agent inspect only delegation-enabled profile IDs/descriptions, effective execution settings, and current resolution status locally without approval, provider transport, or exact prompt preparation.
51
+ - Return bounded model-visible output and expandable human-visible plan, approval, diagnostics, transcript, tool-event, usage, and response details. Advertise no artifact or contract trace storage until those implementations exist.
52
+
53
+ ## 0.4.0 Exit Plan (agreed 2026-07-26)
54
+
55
+ Decisions and scope for taking 0.4.0 out of beta. This section supersedes older subagent-status prose elsewhere in this file (notably the retained `pi-sdk-isolated` wording, which no longer matches the code); aligning those documents is work item 4 below.
56
+
57
+ ### Decisions
58
+
59
+ - **Backend selection is configuration, not profile schema.** Agent profiles remain execution-environment-agnostic personas (model, thinking level, prompt stack). Defaults are configured through `subagents.backend` in global `~/.pi/forge/config.json` with a trusted-project override in `.pi/forge/config.json`; trusted-project `subagents.profiles.<id>` entries gate delegation and may override backend/timeout per profile, and interactive runs may override backend with `--backend`. Global profile entries are ignored until global profiles and prompt stacks have explicit source scope. The unattended model-callable tool path pins the effective configured profile backend; the interactive approval dialog always displays the bound backend. There are no fallback chains: the runtime contract forbids silent fallback, and a fallback that downgrades the execution boundary would overstate enforcement.
60
+ - **Depth over orchestration breadth.** pi-forge's delegation niche is policy-bound, reviewable execution: sealed exact prompts, fingerprint-bound approval, and honest enforcement receipts. Background agents, parallel fan-out, chains/pipelines, nested delegation, and inter-agent messaging stay deferred (see Deferred Product Backlog); general orchestration is deliberately left to dedicated packages. The runtime's run-handle model already permits host-composed concurrency, so a future parallel approval UX needs no runtime change.
61
+ - **pi-forge 0.4.0 does not require pi-subagent-runtime 0.1-stable.** Pin an exact runtime version and keep the subagent surface labelled experimental per Milestone 3. The runtime's own stabilization still waits for a second consumer or backend author per its VISION.md.
62
+
63
+ ### Work items, in order
64
+
65
+ 1. **Finish the runtime integration in pi-forge.**
66
+ - ~~Expose backend selection as decided above~~ **(done 2026-07-29):** global/trusted-project defaults plus explicit trusted-project `subagents.profiles.<id>` delegation eligibility and backend/timeout overrides, `/forge-agent plan|run --backend <id>`, interactive `forge_subagent` `backend` parameter, unattended pinning to the effective configured profile backend, and resolved-setting reporting in `forge_subagent_profiles` and `/forge-agent backends`.
67
+ - ~~Resolve the fingerprint-semantics contradiction~~ **(done 2026-07-26):** `AgentExecutionPlan` now carries the runtime-issued `conversationFingerprint` and `executionFingerprint` as required inputs to `createAgentExecutionPlan()`; the host never computes either value. `subagentExecutionFingerprint` and the host-side recomputation check in `validateAgentExecutionPlan()` were removed; substitution detection remains the runtime's sealed-plan binding.
68
+ - ~~Surface the sealed `conversationFingerprint`~~ **(done 2026-07-26):** shown in `/forge-agent plan` output, the approval summary, the full-prompt viewer, and the tool's plan details.
69
+ - ~~Deduplicate validation toward runtime core~~ **(done 2026-07-26):** `src/subagent/validation.ts` re-exports and adapts the runtime core validators; only host-specific artifacts keep local implementations. The host access-receipt validator intentionally stays richer than the runtime's (mount uniqueness, level consistency, boundary-claim cross-checks); porting those checks into the runtime core is a runtime-side follow-up.
70
+ 2. **Land small runtime-side API additions** **(done 2026-07-28):** `compile` receives the validated accepted preflight and `prepare` accepts an `AbortSignal`; pi-forge now consumes both directly without `hostCompilePreflight()` or `prepareWithAbort()`. Media materialization remains deferred unless delegated media tasks enter 0.4 scope.
71
+ 3. **Resolve the runtime publish story** **(done 2026-07-28):** published `@zihanw/pi-subagent-runtime@0.1.0-beta.1` and pinned that exact prerelease in pi-forge. The subagent surface remains experimental and does not require runtime 0.1-stable.
72
+ 4. **Legacy cleanup and documentation alignment** **(done 2026-07-26):** removed the SDK spike scripts/test, the `src/subagent-contract.ts` compatibility barrel, and the `subagentExecutionFingerprint` host shim; aligned stale `pi-sdk-isolated`/registry claims in `SUBAGENT_INTERFACE_DESIGN.md`, `SUBAGENT_ADAPTER_CONTRACT.md`, `SUBAGENT_SDK_SPIKE_FINDINGS.md`, and `FEATURES.md`; recorded the removed legacy exports as breaking changes in `CHANGELOG.md`. Coverage debt accepted: the removed spike was the only live media-preparation and trusted-extension preparation diagnostic; re-establish that coverage when delegated media tasks are productized (work item 2).
73
+ 5. **Milestone 1 step 1 dogfooding** of the subprocess backend against representative providers, cancellation timing, long prompts, large read results, and rejection/full-prompt review flows. The bubblewrap sandbox evaluation and staged-write proposal remain Milestone 1 design work and do not gate 0.4.0; any sandbox backend lands as a separate runtime backend entry point with honest receipts.
74
+ 6. **Milestone 2: profile UI** **(done 2026-07-31):** the browser editor now manages profiles end to end — navigation, list/badges, create/edit/validate/save/apply/delete, single auto-activation enforcement, registry-driven model controls, provenance/drift display, and a per-profile delegation card that writes `subagents.profiles` policy with backend/timeout overrides. A viewport-layout regression from the Vue shell migration (clipped content with no scroll path) was repaired with flex `min-height: 0` chains, a collapsible diagnostics panel, narrow-mode layout fixes, and a layout-invariant browser test.
75
+ 7. **Milestone 3: release readiness**, plus explicit release-note non-goals: no runner, no background execution, no chains, no profile schema expansion, no macro portability hints, no chat-history lifecycle controls.
76
+
77
+ ## 0.4.1 Candidate: Scoped Global Profiles and Stacks
78
+
79
+ If cross-project presets are added, introduce global profiles and prompt stacks together rather than treating a project-local profile ID as a global identity. Load them from explicit global directories, retain source scope on every loaded resource, let a same-ID project resource shadow its global counterpart, and apply global/project `subagents.profiles` policy only to profiles from the matching scope. Define discovery, auto-activation, stack-reference, and editor behavior against that scoped identity before implementation.
80
+
81
+ ## Milestone 1: Sandbox and Write-Safety Evaluation
82
+
83
+ Goal: determine whether stronger isolation and useful write workflows can be added without obscuring the current honest shared-user boundary.
84
+
85
+ Implementation sequence:
86
+
87
+ 1. Exercise the current subprocess against representative local and remote providers, cancellation timing, long prompts, large read results, and rejection/full-prompt review flows.
88
+ 2. Define an optional sandbox-driver interface and prototype bubblewrap on supported Linux hosts with explicit allowed roots, a minimal environment, process restrictions, and configurable network policy.
89
+ 3. Keep shared-user as an explicitly unsafe compatibility mode; never report sandbox enforcement when the selected host cannot provide it.
90
+ 4. Specify a staged-write result containing proposed patches/change metadata that the human can inspect and approve separately before host application.
91
+
92
+ Initial scope:
93
+
94
+ - One foreground text task at a time, with no background execution or automatic retries.
95
+ - Clean context and explicit task only; no automatic parent history.
96
+ - Preserve read-only defaults until a separate staged-write approval/apply path exists.
97
+ - No generic shell merely to obtain file writes; sandbox claims require enforcement tests and receipts.
98
+
99
+ Done criteria:
100
+
101
+ - The optional sandbox can demonstrate and test allowed-root, process, symlink, and requested network behavior, or the product continues to label execution shared-user without ambiguity.
102
+ - A proposed write cannot affect the workspace before a second, human-visible approval and has a clear failure/partial-application strategy.
103
+ - User cancellation and host timeout settle once and clean up preparation sessions, child processes, and temporary bridge data.
104
+ - Documentation and receipts remain accurate on unsupported platforms and when falling back to shared-user execution.
105
+
106
+ ## Milestone 2: Profile UI (landed 2026-07-31)
107
+
108
+ Goal: make profile v1 fully manageable from the existing localhost editor while preserving the exact behavior of the shared profile service and `/profile` commands.
109
+
110
+ Scope:
111
+
112
+ - Add clear top-level navigation between prompt stacks and agent profiles.
113
+ - List profiles with ID, name, exact provider/model, thinking level, prompt-stack reference, auto-activation, and validation state.
114
+ - Support create, edit, validate, save, delete, and one-shot apply operations.
115
+ - Populate model/thinking controls from available model-registry data and prompt-stack selection from the shared stack repository.
116
+ - Show resolution diagnostics for missing models, authentication, unsupported thinking levels, invalid stacks, and unmatched tool policy.
117
+ - Distinguish source-definition changes, last-applied provenance, and current runtime drift; never imply that a profile continuously owns runtime state.
118
+ - Retain a raw JSON recovery path for invalid or future fields without silently accepting unsupported profile fields.
119
+ - Reuse the existing profile repository, application, preview, provenance, and drift services rather than duplicating command behavior in web handlers.
120
+
121
+ Done criteria:
122
+
123
+ - A user can create, edit, validate, save, apply once, and delete a profile without editing JSON or using `/profile` commands.
124
+ - At most one auto-activation profile is accepted, and profile precedence remains identical to the command/runtime path.
125
+ - Applying a profile performs full preflight and best-effort rollback on failure.
126
+ - The UI does not duplicate prompt-stack item, tool-policy, or skill-policy editing.
127
+ - Browser tests cover token protection, empty and invalid states, model/stack selection, validation, save, apply, drift display, deletion, and lifecycle host refresh.
128
+
129
+ ## Milestone 3: Release Readiness
130
+
131
+ Goal: make the user-visible profile and experimental delegation surfaces understandable, reproducible, and safe to release.
132
+
133
+ Scope:
134
+
135
+ - Update English and Chinese user documentation with profile UI workflows, profile-versus-stack ownership, delegation consent, and concrete backend limitations.
136
+ - Clearly label the subagent API/backend as experimental and keep installation and ordinary non-delegation use independent of backend execution.
137
+ - Run command/event and browser workflows across extension reload, session navigation, fresh sessions, compaction, and editor reuse.
138
+ - Verify npm and Git delivery through compiled `dist` while clone-based development continues to load `src/index.ts` explicitly.
139
+ - Run `npm run verify` before every release candidate and reject stale browser-client or `dist` output.
140
+
141
+ Done criteria:
142
+
143
+ - Documentation and UI do not overstate skill filtering, tool filtering, filesystem isolation, timeout enforcement, or profile ownership.
144
+ - Release-like package checks contain no physical `src/` files and both package entry points resolve to compiled output.
145
+ - All core, browser, type, generated-client, `dist`, and package checks pass from a clean checkout.
146
+
147
+ ## Deferred Product Backlog
148
+
149
+ ### Broader or Owned Subagent Runner
150
+
151
+ Do not build a full runner in 0.4. The current subprocess path should remain fresh-context, profile-backed, foreground, approval-gated, and sequential rather than expanding into chains or pipelines.
152
+
153
+ Requirements before implementation:
154
+
155
+ - Project trust behavior for local profiles and agents.
156
+ - Cancellation, timeout, and cleanup semantics.
157
+ - Budget, turn, token, output, and cost limits.
158
+ - Tool/model/profile inheritance and provider fallback rules.
159
+ - Artifact and trace storage, authorization, retention, redaction, pagination, and cleanup.
160
+ - Failure and retry formats, priorities, queues, and concurrency.
161
+ - Secret/environment injection and structured-output policy.
162
+ - Protection against recursive delegation loops.
163
+
164
+ Build native orchestration only if stored profiles need behavior external runners cannot provide without taking over pi-forge's product surface. Otherwise keep the adapter boundary and let dedicated packages own orchestration.
165
+
166
+ ### Profile Schema Expansion
167
+
168
+ Keep generation parameters, model fallbacks, tools, skills, global profile storage, secrets, and runner limits out of profile v1. Revisit them only when a concrete consumer can validate and enforce their semantics consistently across supported backends.
169
+
170
+ ### Custom Macro and Slot Portability
171
+
172
+ - Add optional dependency hints for required slots, macros, or extension package names only after real stack sharing demonstrates portability friction.
173
+ - Surface missing custom dependencies in validation and the editor without allowing executable code in stack JSON.
174
+ - Preserve parser, filter, conditional, slot, and unknown-policy compatibility.
175
+ - Continue deferring general expressions, boolean algebra, loops, arithmetic, regex conditions, and arbitrary stack-authored code.
176
+
177
+ ### SillyTavern Import Fidelity
178
+
179
+ - Preserve additional useful original metadata under `import` when real presets require it.
180
+ - Add fixtures when real presets reveal unsupported field shapes.
181
+ - Keep macro and regex conversion warnings in their focused importer modules.
182
+ - Preserve existing behavior unless a real fixture demonstrates the need for a change.
183
+
184
+ ### Chat-History and Prompt Lifecycle Controls
185
+
186
+ Potential history controls include omitting the last N user messages, selecting only the branch after the latest compaction, explicitly including or omitting hidden/synthetic/custom messages, and eventually summarizing old history. Each option needs a concrete use case and dangling tool-call/result repair tests.
187
+
188
+ Potential lifecycle configuration may include:
189
+
190
+ ```json
191
+ {
192
+ "lifecycle": {
193
+ "contextRewrite": "first-provider-request"
194
+ }
195
+ }
196
+ ```
197
+
198
+ Only add alternatives to the current `first-provider-request` behavior when users demonstrate a need for repeated rewriting, tool-follow-up-aware rewriting, or disabled message-layout rewriting.
199
+
200
+ ### Payload and Regex Expansion
201
+
202
+ Continue deferring provider-payload rewriting, true display-only regex transforms, and streaming display cleanup. Near-term diagnostics may broaden provider-payload shape coverage and explain precisely what regex changed and where. Add a new stage only for a concrete use case with a stable hook and a non-destructive preview path.
203
+
204
+ ## Product and Engineering Guardrails
205
+
206
+ - Keep prompt-stack JSON declarative. Trusted executable customization belongs in `~/.pi/forge/extensions`, `.pi/forge/extensions`, or reusable packages.
207
+ - Treat profiles as one-shot presets. Manual use or fresh-session auto-activation configures Pi once; later user changes must not be continuously overwritten.
208
+ - Keep tool names out of profiles. The referenced prompt stack remains the single source of truth for strict active-tool policy.
209
+ - Treat skill policy as model-visible prompt filtering only, not explicit invocation control or a security boundary.
210
+ - Drive new prompt-stack behavior from demonstrated prompt-authoring pain rather than complete SillyTavern compatibility.
211
+ - Avoid expanding browser behavior without browser-level workflow coverage.
212
+ - Keep pi-forge install and ordinary use independent of `pi-subagents`, `@gotgenes/pi-subagents`, Archimedes, or another orchestration package; delegation remains opt-in and additional backends remain optional integrations.
213
+ - Verify any future event-bus adapter against the supported Pi version range before adopting it.
214
+ - Do not expose delegation merely because a dispatcher exists. A concrete adapter must prove its actual isolation, preparation, projection, cleanup, and authorization semantics end to end.
215
+ - Keep Node's built-in test runner for core tests and separate compiler, loader, importer, regex, policy, profile, and subagent-contract tests from integration-style command tests.
216
+ - Extend the command/event harness for command or lifecycle changes, run browser smoke tests for material editor workflows, and run `npm run verify` before commits and releases.
@@ -0,0 +1,220 @@
1
+ # Historical subagent design review
2
+
3
+ Status: historical pre-implementation review. Its blocking findings were resolved by the exported contract, validated backend registry, immutable preparation binding, concrete backends, and approval-gated foreground integration; the text below records the issues that shaped that design.
4
+
5
+ ## Verdict
6
+
7
+ `NEXT_STEPS.md` is directionally sound and mostly suits pi-forge's current architecture. The profile CLI to shared profile service to profile UI progression is appropriate, and deferring an owned runner is the right call.
8
+
9
+ `SUBAGENT_INTERFACE_DESIGN.md` is a good requirements draft, but it is not yet an implementable backend-neutral contract. Its status should remain draft rather than accepted until the blocking issues below are resolved.
10
+
11
+ ## Findings
12
+
13
+ ### 1. Blocker: a serialized prompt-stack definition is not an executable snapshot
14
+
15
+ The proposed `AgentProfileSnapshot` carries only the declarative `PromptStack`. Current compilation also depends on:
16
+
17
+ - Dynamic `BuildSystemPromptOptions`, the current model, time, variables, and the base system prompt supplied through Pi's lifecycle.
18
+ - Executable custom slot and macro registrations.
19
+ - Pi tool snippets, guidelines, skills, and context files represented by `PromptRuntime`.
20
+ - Pi's default system prompt when the stack is `null`, `append`, or `prepend`.
21
+
22
+ Two backends receiving the same proposed snapshot can therefore compile different prompts or fail to compile custom slots entirely.
23
+
24
+ Recommended design: separate two artifacts:
25
+
26
+ - `AgentProfileSnapshot`: immutable declarative provenance.
27
+ - `AgentExecutionPlan`: a host-prepared system prompt, initial messages, effective tool names, runtime inputs, diagnostics, and an execution fingerprint.
28
+
29
+ The alternative is to require every backend to run an identical Pi/pi-forge runtime and custom-extension set, but that would not be genuinely backend-neutral.
30
+
31
+ Relevant code:
32
+
33
+ - `SUBAGENT_INTERFACE_DESIGN.md:86`
34
+ - `src/lifecycle.ts:86`
35
+ - `src/types.ts:178`
36
+ - `src/slot-renderers.ts:125`
37
+ - `src/macro-engine.ts:122`
38
+
39
+ ### 2. Blocker: profile resolution currently means valid in the parent Pi runtime
40
+
41
+ The current resolver checks models and authentication against the active Pi model registry. A remote, subprocess, or package backend may have different models and credentials.
42
+
43
+ Resolution should be split into:
44
+
45
+ - Host resolution: profile syntax, stack lookup, and trusted extension dependencies.
46
+ - Backend preflight: model availability/authentication, tool availability, media support, policy enforcement, and supported limits.
47
+
48
+ Without that split, the advertised native/subprocess/remote portability is not achievable.
49
+
50
+ Relevant code:
51
+
52
+ - `src/agent-profile.ts:156`
53
+ - `src/agent-profile.ts:172`
54
+ - `src/index.ts:179`
55
+
56
+ ### 3. High: tool negotiation and enforcement are underspecified
57
+
58
+ `NEXT_STEPS.md` says the runner supplies a baseline and the stack filters it, but the request contains neither the backend's tool catalog nor the resolved effective tools. Current pi-forge filters a dynamic active-tool baseline.
59
+
60
+ The backend contract needs a discovery or preflight phase that exposes:
61
+
62
+ - Available tool names or stable capability IDs.
63
+ - The access and limit policies it can enforce.
64
+ - Exact effective tools after stack policy.
65
+ - Required tool patterns that matched nothing.
66
+ - Adapter-specific tool-name mappings, if any.
67
+
68
+ A stack tool allowlist is selection policy, not filesystem or network isolation.
69
+
70
+ Relevant code:
71
+
72
+ - `NEXT_STEPS.md:62`
73
+ - `SUBAGENT_INTERFACE_DESIGN.md:86`
74
+ - `SUBAGENT_INTERFACE_DESIGN.md:167`
75
+ - `src/index.ts:270`
76
+
77
+ ### 4. High: the access contract is not portable or sufficiently enforceable
78
+
79
+ The contract combines remote backends with host absolute paths in `access.cwd` and `access.roots`, while validation requires host-side canonicalization and symlink checks. Those paths may not exist in a remote or container namespace, and host preflight cannot prevent backend-side symlink races.
80
+
81
+ The capability booleans are too coarse to determine whether roots, read-only mounts, output limits, token budgets, or turn limits are enforceable.
82
+
83
+ Recommended changes:
84
+
85
+ - Define access using backend-visible mounts or opaque workspace handles.
86
+ - Require the backend to canonicalize paths within its own namespace immediately before access.
87
+ - Specify whether `cwd` must be contained in an allowed root.
88
+ - Define the behavior of `level: "none"` when roots are also supplied.
89
+ - Represent granular enforcement support rather than broad booleans.
90
+ - Distinguish model/control-plane network traffic from agent-accessible network tools.
91
+ - Treat remote-backend data egress as a separate trust/consent decision.
92
+
93
+ Project trust is not, by itself, consent to send project context to a remote backend.
94
+
95
+ Relevant design sections:
96
+
97
+ - `SUBAGENT_INTERFACE_DESIGN.md:108`
98
+ - `SUBAGENT_INTERFACE_DESIGN.md:167`
99
+ - `SUBAGENT_INTERFACE_DESIGN.md:216`
100
+
101
+ ### 5. Medium: clean-context assembly conflicts with unrestricted prompt-stack layouts
102
+
103
+ The design requires the final task to survive truncation, while existing `compileMessages()` behavior permits a stack to remove the latest user message, filter user roles, or omit history. Such a stack can accidentally remove the delegated task.
104
+
105
+ The contract needs one explicit rule:
106
+
107
+ - Reject stacks whose compiled delegation layout omits the task; or
108
+ - Reserve a delegation-task insertion point that cannot be filtered; or
109
+ - State that intentional omission is allowed, weakening the guarantee that the actionable task is always preserved.
110
+
111
+ Additional context concerns:
112
+
113
+ - "Selected context is data" is an instruction-hierarchy convention, not a security guarantee. Delimiters do not prevent prompt injection.
114
+ - Tool-result excerpts should normally be rendered as quoted background evidence rather than native tool-result messages without matching tool calls.
115
+ - A summary should carry provenance just as other selected context does.
116
+ - `maxTokens` cannot be deterministically portable without defining the tokenizer or estimator. A byte/character bound or recorded estimator/version would be clearer.
117
+
118
+ Relevant code and design:
119
+
120
+ - `SUBAGENT_INTERFACE_DESIGN.md:28`
121
+ - `SUBAGENT_INTERFACE_DESIGN.md:41`
122
+ - `SUBAGENT_INTERFACE_DESIGN.md:223`
123
+ - `src/compiler.ts:88`
124
+ - `src/compiler.ts:161`
125
+
126
+ ### 6. Medium: the real adapter spike comes too late
127
+
128
+ The implementation plan first publishes contract types and builds four slices around fake backends, then validates the design against a real runner in Slice 6. Fake conformance tests can prove internal consistency, but cannot establish that the boundary fits a real backend.
129
+
130
+ The installed Pi SDK already supports session construction with model, thinking level, tools, custom tools, and resource loaders. A minimal in-memory or subprocess prototype should happen before the contract becomes a public export.
131
+
132
+ Move the current concrete-adapter decision/spike before contract stabilization. Keep experimental types internal until that spike validates the boundary.
133
+
134
+ Relevant design and API:
135
+
136
+ - `SUBAGENT_INTERFACE_DESIGN.md:227`
137
+ - `SUBAGENT_INTERFACE_DESIGN.md:262`
138
+ - `node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.d.ts:11`
139
+
140
+ ### 7. Medium: profile UI needs a shared service extraction first
141
+
142
+ The profile UI priority is appropriate, but save, status/drift calculation, deletion, and application are not yet presented as one shared typed service. Save and drift rendering are still command-oriented.
143
+
144
+ Before UI work, extract shared operations for:
145
+
146
+ - Save/update/delete.
147
+ - Resolution and typed preview.
148
+ - Application.
149
+ - Typed provenance and runtime-drift status.
150
+
151
+ This prevents the UI from duplicating command behavior and directly supports the stated done criteria.
152
+
153
+ Relevant code:
154
+
155
+ - `NEXT_STEPS.md:34`
156
+ - `src/profile-command.ts:258`
157
+ - `src/profile-command.ts:455`
158
+
159
+ ### 8. Medium: fingerprints need explicit stable semantics
160
+
161
+ Execution-facing fingerprints should use canonical serialization and a named digest algorithm/version, for example `sha256:v1:<digest>`. A raw `JSON.stringify()` value is useful for current provenance comparison but is not an ideal portable fingerprint.
162
+
163
+ The execution fingerprint should cover all behavior-affecting prepared inputs, not only the source profile and stack. This includes the compiled prompt/messages, effective tools, relevant runtime data, and required custom registrations.
164
+
165
+ Avoid silently changing the semantics of existing stored provenance fingerprints; introduce a separate execution/snapshot fingerprint format if compatibility matters.
166
+
167
+ Relevant code:
168
+
169
+ - `src/agent-profile.ts:243`
170
+ - `SUBAGENT_INTERFACE_DESIGN.md:222`
171
+
172
+ ### 9. Medium: response, trace, and limit semantics need tightening
173
+
174
+ Before parent integration, clarify:
175
+
176
+ - Which statuses require or forbid `error`.
177
+ - Whether `output` may be empty for failures and cancellations.
178
+ - Whether `effectiveAccess` is merely echoed or is a backend-produced enforcement receipt.
179
+ - Effective tool and enforced-limit metadata in the response.
180
+ - Currency and units for `usage.cost`.
181
+ - Artifact and change-path namespace, authorization, lifetime, and cleanup.
182
+ - How an opaque trace reference routes back to the correct backend and how inspection is authorized.
183
+ - Cancellation before a remote backend has exposed its `runId`.
184
+ - Whether limits are hard execution limits or only response/projection truncation.
185
+
186
+ The current capability interface cannot indicate support for `maxTurns`, `maxOutputBytes`, or `tokenBudget`, so the dispatcher cannot reliably apply the rule that unsupported required policies must be rejected.
187
+
188
+ ## Recommended ordering
189
+
190
+ 1. Complete real-provider and real-extension-tool profile CLI compatibility testing.
191
+ 2. Extract the shared profile repository/application/status service.
192
+ 3. Build profile UI on that service with browser workflow coverage.
193
+ 4. Prototype one actual Pi SDK or subprocess backend.
194
+ 5. Revise the subagent design around backend preflight plus a host-prepared execution plan.
195
+ 6. Add pure validators, stable fingerprints, fake-backend conformance tests, and optional backend registration.
196
+ 7. Add parent run/inspect tools only after enforcement and task-preservation semantics are demonstrated.
197
+ 8. Continue deferring an owned full runner, resumable agents, chains, pipelines, retries, queues, and concurrency orchestration.
198
+
199
+ Custom macro/slot portability can remain broadly deferred, but dependency detection cannot. A subagent export must identify required registrations or reject stacks that cannot be reproduced by the chosen backend.
200
+
201
+ ## Parts of the plan worth retaining
202
+
203
+ - Profiles remain reusable one-shot presets rather than continuously owning runtime state.
204
+ - Prompt stacks remain the profile-level source of tool-selection policy.
205
+ - Per-run access and limits remain outside reusable profiles.
206
+ - Parent context selection is explicit, bounded, and provenance-preserving.
207
+ - Parent-visible results remain compact, with full normalized history behind an inspectable trace.
208
+ - No concrete subagent package is required to install or use pi-forge.
209
+ - A full owned runner remains deferred.
210
+ - Initial runner work avoids chains and pipelines.
211
+ - Browser workflows and public contract behavior receive dedicated tests.
212
+
213
+ ## Validation performed during review
214
+
215
+ - Core tests: 126 passed.
216
+ - TypeScript typecheck: passed.
217
+ - Real-browser editor smoke test: passed.
218
+ - Tracked `dist/` consistency check: passed.
219
+
220
+ The review itself did not modify implementation code or either source design document.