@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.75048e7

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 (452) hide show
  1. package/dist/cli.js +3 -2
  2. package/dist/help-text.js +10 -6
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +495 -0
  5. package/dist/resources/extensions/browser-tools/engine/selection.js +16 -0
  6. package/dist/resources/extensions/browser-tools/extension-manifest.json +2 -2
  7. package/dist/resources/extensions/browser-tools/index.js +57 -9
  8. package/dist/resources/extensions/browser-tools/package.json +5 -1
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +167 -16
  10. package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
  11. package/dist/resources/extensions/gsd/auto/phases.js +4 -3
  12. package/dist/resources/extensions/gsd/auto-dashboard.js +92 -17
  13. package/dist/resources/extensions/gsd/auto-dispatch.js +55 -0
  14. package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
  15. package/dist/resources/extensions/gsd/auto-prompts.js +72 -22
  16. package/dist/resources/extensions/gsd/auto-recovery.js +7 -8
  17. package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
  18. package/dist/resources/extensions/gsd/auto-start.js +94 -15
  19. package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
  20. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +18 -65
  21. package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
  22. package/dist/resources/extensions/gsd/auto.js +31 -6
  23. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -4
  24. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +56 -20
  26. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +33 -38
  27. package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
  28. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
  29. package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
  30. package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -2
  31. package/dist/resources/extensions/gsd/commands/handlers/ops.js +9 -5
  32. package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
  33. package/dist/resources/extensions/gsd/commands-maintenance.js +172 -2
  34. package/dist/resources/extensions/gsd/commands-mcp-status.js +109 -60
  35. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
  36. package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
  37. package/dist/resources/extensions/gsd/config-overlay.js +2 -1
  38. package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  40. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
  41. package/dist/resources/extensions/gsd/error-classifier.js +2 -1
  42. package/dist/resources/extensions/gsd/escalation.js +4 -4
  43. package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
  44. package/dist/resources/extensions/gsd/forensics.js +74 -2
  45. package/dist/resources/extensions/gsd/gsd-db.js +42 -6
  46. package/dist/resources/extensions/gsd/guided-flow.js +119 -176
  47. package/dist/resources/extensions/gsd/mcp-filter.js +3 -0
  48. package/dist/resources/extensions/gsd/mcp-project-config.js +76 -84
  49. package/dist/resources/extensions/gsd/memory-store.js +4 -1
  50. package/dist/resources/extensions/gsd/migration-auto-check.js +2 -2
  51. package/dist/resources/extensions/gsd/milestone-closeout.js +3 -1
  52. package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
  53. package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
  54. package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
  55. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  56. package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
  57. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  58. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  59. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  60. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  61. package/dist/resources/extensions/gsd/prompts/run-uat.md +33 -23
  62. package/dist/resources/extensions/gsd/prompts/system.md +3 -1
  63. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  64. package/dist/resources/extensions/gsd/recovery-classification.js +20 -0
  65. package/dist/resources/extensions/gsd/rule-registry.js +428 -52
  66. package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
  67. package/dist/resources/extensions/gsd/skill-activation.js +20 -3
  68. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +4 -2
  69. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +1 -1
  70. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
  71. package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
  72. package/dist/resources/extensions/gsd/state.js +17 -14
  73. package/dist/resources/extensions/gsd/templates/plan.md +3 -1
  74. package/dist/resources/extensions/gsd/tool-contract.js +5 -0
  75. package/dist/resources/extensions/gsd/tool-presentation-plan.js +143 -0
  76. package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
  77. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
  78. package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
  79. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -9
  80. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  81. package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
  82. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +483 -6
  83. package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
  84. package/dist/resources/extensions/gsd/unit-tool-contracts.js +169 -0
  85. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  86. package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
  87. package/dist/resources/extensions/gsd/verification-gate.js +72 -1
  88. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -1
  89. package/dist/resources/extensions/gsd/workflow-mcp.js +5 -73
  90. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -0
  91. package/dist/resources/extensions/mcp-client/manager.js +31 -1
  92. package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
  93. package/dist/rtk.d.ts +7 -1
  94. package/dist/rtk.js +27 -11
  95. package/dist/update-check.d.ts +15 -1
  96. package/dist/update-check.js +87 -12
  97. package/dist/update-cmd.d.ts +1 -0
  98. package/dist/update-cmd.js +53 -2
  99. package/dist/web/standalone/.next/BUILD_ID +1 -1
  100. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  101. package/dist/web/standalone/.next/build-manifest.json +2 -2
  102. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  103. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  112. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/index.html +1 -1
  121. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  128. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  129. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  131. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  132. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  133. package/package.json +5 -3
  134. package/packages/cloud-mcp-gateway/package.json +2 -2
  135. package/packages/contracts/dist/workflow.d.ts +14 -0
  136. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  137. package/packages/contracts/dist/workflow.js +16 -0
  138. package/packages/contracts/dist/workflow.js.map +1 -1
  139. package/packages/contracts/package.json +1 -1
  140. package/packages/daemon/package.json +4 -4
  141. package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
  142. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  143. package/packages/gsd-agent-core/dist/agent-session.js +32 -0
  144. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  145. package/packages/gsd-agent-core/dist/index.d.ts +1 -0
  146. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  147. package/packages/gsd-agent-core/dist/index.js +1 -0
  148. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  149. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
  150. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
  151. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
  152. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
  153. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
  154. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  155. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  156. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  157. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
  158. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  159. package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
  160. package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
  161. package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
  162. package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
  163. package/packages/gsd-agent-core/package.json +6 -6
  164. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
  165. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
  166. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
  167. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
  168. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  169. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  170. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  171. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  172. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  173. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  174. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  175. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
  176. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  177. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +92 -31
  178. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  179. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  180. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
  181. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  182. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.d.ts.map +1 -1
  186. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -0
  187. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  188. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  190. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  192. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
  194. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  196. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
  197. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  198. package/packages/gsd-agent-modes/package.json +7 -7
  199. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
  200. package/packages/mcp-server/dist/remote-questions.js +23 -9
  201. package/packages/mcp-server/dist/remote-questions.js.map +1 -1
  202. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  203. package/packages/mcp-server/dist/workflow-tools.js +84 -2
  204. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  205. package/packages/mcp-server/package.json +3 -3
  206. package/packages/native/package.json +1 -1
  207. package/packages/pi-agent-core/dist/agent-loop.js +42 -3
  208. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  209. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  210. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  211. package/packages/pi-agent-core/dist/agent.js +2 -0
  212. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  213. package/packages/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  214. package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
  215. package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  216. package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
  217. package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  218. package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
  219. package/packages/pi-agent-core/dist/types.d.ts +6 -1
  220. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  221. package/packages/pi-agent-core/dist/types.js.map +1 -1
  222. package/packages/pi-agent-core/package.json +1 -1
  223. package/packages/pi-ai/dist/api-registry.d.ts +2 -0
  224. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  225. package/packages/pi-ai/dist/api-registry.js +23 -0
  226. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  227. package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
  228. package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  229. package/packages/pi-ai/dist/image-models.generated.js +15 -0
  230. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  231. package/packages/pi-ai/dist/models.generated.d.ts +411 -39
  232. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  233. package/packages/pi-ai/dist/models.generated.js +504 -153
  234. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  235. package/packages/pi-ai/dist/stream.js +6 -6
  236. package/packages/pi-ai/dist/stream.js.map +1 -1
  237. package/packages/pi-ai/package.json +1 -1
  238. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +3 -0
  239. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  240. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  243. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  245. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  246. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  247. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/tools/bash.js +2 -2
  249. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
  252. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
  254. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
  256. package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
  259. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  260. package/packages/pi-coding-agent/package.json +7 -7
  261. package/packages/pi-tui/dist/terminal.d.ts +1 -0
  262. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  263. package/packages/pi-tui/dist/terminal.js +8 -4
  264. package/packages/pi-tui/dist/terminal.js.map +1 -1
  265. package/packages/pi-tui/package.json +1 -1
  266. package/packages/rpc-client/package.json +2 -2
  267. package/pkg/package.json +1 -1
  268. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
  269. package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
  270. package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
  271. package/src/resources/extensions/browser-tools/index.ts +60 -9
  272. package/src/resources/extensions/browser-tools/package.json +5 -1
  273. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
  274. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
  275. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +196 -16
  276. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +239 -63
  277. package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
  278. package/src/resources/extensions/gsd/auto/phases.ts +5 -3
  279. package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
  280. package/src/resources/extensions/gsd/auto-dispatch.ts +67 -0
  281. package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
  282. package/src/resources/extensions/gsd/auto-prompts.ts +106 -15
  283. package/src/resources/extensions/gsd/auto-recovery.ts +7 -7
  284. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
  285. package/src/resources/extensions/gsd/auto-start.ts +112 -17
  286. package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
  287. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +43 -73
  288. package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
  289. package/src/resources/extensions/gsd/auto.ts +47 -5
  290. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +96 -4
  291. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
  292. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +81 -25
  293. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +70 -63
  294. package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
  295. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
  296. package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
  297. package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -2
  298. package/src/resources/extensions/gsd/commands/handlers/ops.ts +9 -5
  299. package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
  300. package/src/resources/extensions/gsd/commands-maintenance.ts +197 -2
  301. package/src/resources/extensions/gsd/commands-mcp-status.ts +136 -58
  302. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
  303. package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
  304. package/src/resources/extensions/gsd/config-overlay.ts +3 -1
  305. package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
  306. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  307. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
  308. package/src/resources/extensions/gsd/error-classifier.ts +2 -1
  309. package/src/resources/extensions/gsd/escalation.ts +4 -4
  310. package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
  311. package/src/resources/extensions/gsd/forensics.ts +99 -5
  312. package/src/resources/extensions/gsd/gsd-db.ts +46 -8
  313. package/src/resources/extensions/gsd/guided-flow.ts +215 -217
  314. package/src/resources/extensions/gsd/mcp-filter.ts +3 -0
  315. package/src/resources/extensions/gsd/mcp-project-config.ts +105 -88
  316. package/src/resources/extensions/gsd/memory-store.ts +4 -1
  317. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  318. package/src/resources/extensions/gsd/milestone-closeout.ts +3 -1
  319. package/src/resources/extensions/gsd/pending-auto-start.ts +0 -2
  320. package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
  321. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  322. package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
  323. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  324. package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
  325. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  326. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  327. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  328. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  329. package/src/resources/extensions/gsd/prompts/run-uat.md +33 -23
  330. package/src/resources/extensions/gsd/prompts/system.md +3 -1
  331. package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  332. package/src/resources/extensions/gsd/recovery-classification.ts +20 -0
  333. package/src/resources/extensions/gsd/rule-registry.ts +558 -58
  334. package/src/resources/extensions/gsd/rule-types.ts +2 -0
  335. package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
  336. package/src/resources/extensions/gsd/skill-activation.ts +20 -2
  337. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +4 -2
  338. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +1 -1
  339. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
  340. package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
  341. package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
  342. package/src/resources/extensions/gsd/state.ts +18 -14
  343. package/src/resources/extensions/gsd/templates/plan.md +3 -1
  344. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
  345. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +123 -0
  346. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +10 -2
  347. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
  348. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +143 -2
  349. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +24 -2
  350. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +12 -2
  351. package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
  352. package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
  353. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
  354. package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -0
  355. package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
  356. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
  357. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
  358. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  359. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
  360. package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
  361. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
  362. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +50 -13
  363. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
  364. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +40 -1
  365. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +60 -0
  366. package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
  367. package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
  368. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
  369. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
  370. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
  371. package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
  372. package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
  373. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +31 -79
  374. package/src/resources/extensions/gsd/tests/gsd-rebuild.test.ts +199 -0
  375. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +75 -0
  376. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
  377. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
  378. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +5 -3
  379. package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
  380. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
  381. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
  382. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +8 -0
  383. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
  384. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +72 -10
  385. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +13 -6
  386. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +15 -0
  387. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +100 -0
  388. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +179 -0
  389. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
  390. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +63 -0
  391. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
  392. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
  393. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
  394. package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
  395. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
  396. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
  397. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +39 -1
  398. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
  399. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
  400. package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
  401. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +83 -1
  402. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
  403. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
  404. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
  405. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
  406. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +79 -0
  407. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
  408. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
  409. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +4 -0
  410. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +36 -0
  411. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
  412. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
  413. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +6 -2
  414. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  415. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
  416. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  417. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
  418. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
  419. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
  420. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
  421. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
  422. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
  423. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
  424. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
  425. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +17 -2
  426. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +493 -0
  427. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +40 -0
  428. package/src/resources/extensions/gsd/tool-contract.ts +6 -0
  429. package/src/resources/extensions/gsd/tool-presentation-plan.ts +223 -0
  430. package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
  431. package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
  432. package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
  433. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -9
  434. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  435. package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
  436. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +589 -8
  437. package/src/resources/extensions/gsd/types.ts +69 -5
  438. package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
  439. package/src/resources/extensions/gsd/unit-tool-contracts.ts +186 -0
  440. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  441. package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
  442. package/src/resources/extensions/gsd/verification-gate.ts +87 -1
  443. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -1
  444. package/src/resources/extensions/gsd/workflow-mcp.ts +5 -73
  445. package/src/resources/extensions/gsd/worktree-lifecycle.ts +26 -0
  446. package/src/resources/extensions/mcp-client/manager.ts +33 -1
  447. package/src/resources/extensions/mcp-client/tests/manager.test.ts +35 -0
  448. package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
  449. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
  450. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
  451. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_buildManifest.js +0 -0
  452. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_ssgManifest.js +0 -0
@@ -1,14 +1,17 @@
1
- import { createHash } from "node:crypto";
2
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
- import { createRequire } from "node:module";
4
- import { basename, resolve } from "node:path";
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
5
3
  import { fileURLToPath } from "node:url";
6
4
 
5
+ import {
6
+ GSD_BROWSER_MCP_SERVER_NAME,
7
+ resolveBundledGsdBrowserCliPath,
8
+ resolveGsdBrowserMcpLaunchConfig,
9
+ } from "../shared/gsd-browser-cli.js";
7
10
  import { assertSafeDirectory } from "./validate-directory.js";
8
11
  import { detectWorkflowMcpLaunchConfig } from "./workflow-mcp.js";
9
12
 
10
13
  export const GSD_WORKFLOW_MCP_SERVER_NAME = "gsd-workflow";
11
- export const GSD_BROWSER_MCP_SERVER_NAME = "gsd-browser";
14
+ export { GSD_BROWSER_MCP_SERVER_NAME, resolveBundledGsdBrowserCliPath };
12
15
 
13
16
  export interface ProjectMcpServerConfig {
14
17
  command?: string;
@@ -36,6 +39,12 @@ interface McpConfigFile {
36
39
  [key: string]: unknown;
37
40
  }
38
41
 
42
+ interface ClaudeCodeLocalSettingsFile {
43
+ enabledMcpjsonServers?: unknown;
44
+ disabledMcpjsonServers?: unknown;
45
+ [key: string]: unknown;
46
+ }
47
+
39
48
  export function resolveBundledGsdCliPath(env: NodeJS.ProcessEnv = process.env): string | null {
40
49
  const explicit = env.GSD_CLI_PATH?.trim() || env.GSD_BIN_PATH?.trim();
41
50
  if (explicit) return explicit;
@@ -53,31 +62,6 @@ export function resolveBundledGsdCliPath(env: NodeJS.ProcessEnv = process.env):
53
62
  return null;
54
63
  }
55
64
 
56
- export function resolveBundledGsdBrowserCliPath(env: NodeJS.ProcessEnv = process.env): string | null {
57
- const explicit = env.GSD_BROWSER_CLI_PATH?.trim() || env.GSD_BROWSER_BIN_PATH?.trim();
58
- if (explicit) return explicit;
59
-
60
- try {
61
- const requireFromHere = createRequire(import.meta.url);
62
- const packageJsonPath = requireFromHere.resolve("@opengsd/gsd-browser/package.json");
63
- const candidate = resolve(packageJsonPath, "..", "bin", "gsd-browser");
64
- if (existsSync(candidate)) return candidate;
65
- } catch {
66
- // Fall through to path candidates for source/dist layouts.
67
- }
68
-
69
- const candidates = [
70
- resolve(fileURLToPath(new URL("../../../../node_modules/@opengsd/gsd-browser/bin/gsd-browser", import.meta.url))),
71
- resolve(fileURLToPath(new URL("../../../../node_modules/.bin/gsd-browser", import.meta.url))),
72
- ];
73
-
74
- for (const candidate of candidates) {
75
- if (existsSync(candidate)) return candidate;
76
- }
77
-
78
- return null;
79
- }
80
-
81
65
  export function buildProjectWorkflowMcpServerConfig(
82
66
  projectRoot: string,
83
67
  env: NodeJS.ProcessEnv = process.env,
@@ -113,31 +97,12 @@ function buildProjectWorkflowMcpServerSpec(
113
97
  };
114
98
  }
115
99
 
116
- function parseJsonEnv<T>(env: NodeJS.ProcessEnv, name: string): T | undefined {
117
- const raw = env[name];
118
- if (!raw) return undefined;
119
- try {
120
- return JSON.parse(raw) as T;
121
- } catch {
122
- throw new Error(`Invalid JSON in ${name}`);
123
- }
124
- }
125
-
126
100
  function isEnvDisabled(value: string | undefined): boolean {
127
101
  if (!value) return false;
128
102
  const normalized = value.trim().toLowerCase();
129
103
  return normalized === "0" || normalized === "false" || normalized === "off";
130
104
  }
131
105
 
132
- function buildBrowserSessionName(projectRoot: string): string {
133
- const resolvedProjectRoot = resolve(projectRoot);
134
- const base = basename(resolvedProjectRoot)
135
- .replace(/[^a-zA-Z0-9._-]+/g, "-")
136
- .replace(/^-+|-+$/g, "") || "project";
137
- const hash = createHash("sha1").update(resolvedProjectRoot).digest("hex").slice(0, 8);
138
- return `gsd-${base}-${hash}`;
139
- }
140
-
141
106
  export function buildProjectBrowserMcpServerConfig(
142
107
  projectRoot: string,
143
108
  env: NodeJS.ProcessEnv = process.env,
@@ -151,39 +116,15 @@ function buildProjectBrowserMcpServerSpec(
151
116
  ): ProjectMcpServerSpec | null {
152
117
  if (isEnvDisabled(env.GSD_BROWSER_MCP_ENABLED)) return null;
153
118
 
154
- const resolvedProjectRoot = resolve(projectRoot);
155
- const serverName = env.GSD_BROWSER_MCP_NAME?.trim() || GSD_BROWSER_MCP_SERVER_NAME;
156
- const explicitArgs = parseJsonEnv<unknown>(env, "GSD_BROWSER_MCP_ARGS");
157
- const explicitEnv = parseJsonEnv<Record<string, string>>(env, "GSD_BROWSER_MCP_ENV");
158
- const explicitCommand = env.GSD_BROWSER_MCP_COMMAND?.trim();
159
- const explicitCliPath = env.GSD_BROWSER_CLI_PATH?.trim() || env.GSD_BROWSER_BIN_PATH?.trim();
160
- const bundledCliPath = !explicitCommand && !explicitCliPath ? resolveBundledGsdBrowserCliPath(env) : null;
161
- const command =
162
- explicitCommand
163
- || explicitCliPath
164
- || (bundledCliPath ? process.execPath : undefined)
165
- || "gsd-browser";
166
- const args = Array.isArray(explicitArgs) && explicitArgs.length > 0
167
- ? explicitArgs.map(String)
168
- : [
169
- ...(bundledCliPath ? [bundledCliPath] : []),
170
- "mcp",
171
- "--session",
172
- buildBrowserSessionName(resolvedProjectRoot),
173
- "--identity-scope",
174
- "project",
175
- "--identity-project",
176
- resolvedProjectRoot,
177
- ];
178
- const cwd = env.GSD_BROWSER_MCP_CWD?.trim() || resolvedProjectRoot;
119
+ const launch = resolveGsdBrowserMcpLaunchConfig(projectRoot, env);
179
120
 
180
121
  return {
181
- serverName,
122
+ serverName: launch.serverName,
182
123
  server: {
183
- command,
184
- args,
185
- cwd,
186
- ...(explicitEnv ? { env: explicitEnv } : {}),
124
+ command: launch.command,
125
+ args: launch.args,
126
+ cwd: launch.cwd,
127
+ ...(launch.env ? { env: launch.env } : {}),
187
128
  },
188
129
  };
189
130
  }
@@ -223,6 +164,78 @@ function readExistingConfig(configPath: string): McpConfigFile {
223
164
  }
224
165
  }
225
166
 
167
+ function readExistingClaudeCodeSettings(settingsPath: string): ClaudeCodeLocalSettingsFile {
168
+ if (!existsSync(settingsPath)) return {};
169
+
170
+ const raw = readFileSync(settingsPath, "utf-8");
171
+ try {
172
+ const parsed = JSON.parse(raw) as ClaudeCodeLocalSettingsFile;
173
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
174
+ } catch (err) {
175
+ throw new Error(
176
+ `Failed to parse ${settingsPath}: ${err instanceof Error ? err.message : String(err)}`,
177
+ );
178
+ }
179
+ }
180
+
181
+ export function ensureClaudeCodeMcpJsonServersEnabled(
182
+ projectRoot: string,
183
+ serverNames: string[],
184
+ ): boolean {
185
+ const resolvedProjectRoot = resolve(projectRoot);
186
+ assertSafeDirectory(resolvedProjectRoot);
187
+
188
+ const targetServerNames = [...new Set(serverNames.filter((name) => name.trim().length > 0))];
189
+ if (targetServerNames.length === 0) return false;
190
+
191
+ const settingsDir = resolve(resolvedProjectRoot, ".claude");
192
+ const settingsPath = resolve(settingsDir, "settings.local.json");
193
+ const existing = readExistingClaudeCodeSettings(settingsPath);
194
+
195
+ const enabled = Array.isArray(existing.enabledMcpjsonServers)
196
+ ? [...existing.enabledMcpjsonServers]
197
+ : [];
198
+ const enabledNames = new Set(enabled.filter((value): value is string => typeof value === "string"));
199
+ let changed = !Array.isArray(existing.enabledMcpjsonServers);
200
+
201
+ for (const serverName of targetServerNames) {
202
+ if (!enabledNames.has(serverName)) {
203
+ enabled.push(serverName);
204
+ enabledNames.add(serverName);
205
+ changed = true;
206
+ }
207
+ }
208
+
209
+ let nextDisabled = existing.disabledMcpjsonServers;
210
+ if (Array.isArray(existing.disabledMcpjsonServers)) {
211
+ const blockedNames = new Set(targetServerNames);
212
+ const filtered = existing.disabledMcpjsonServers.filter((value) => !blockedNames.has(String(value)));
213
+ if (filtered.length !== existing.disabledMcpjsonServers.length) {
214
+ nextDisabled = filtered;
215
+ changed = true;
216
+ }
217
+ }
218
+
219
+ if (!changed) return false;
220
+
221
+ const nextSettings: ClaudeCodeLocalSettingsFile = {
222
+ ...existing,
223
+ enabledMcpjsonServers: enabled,
224
+ ...(Array.isArray(existing.disabledMcpjsonServers) ? { disabledMcpjsonServers: nextDisabled } : {}),
225
+ };
226
+
227
+ mkdirSync(settingsDir, { recursive: true });
228
+ writeFileSync(settingsPath, `${JSON.stringify(nextSettings, null, 2)}\n`, "utf-8");
229
+ return true;
230
+ }
231
+
232
+ export function ensureClaudeCodeMcpJsonServerEnabled(
233
+ projectRoot: string,
234
+ serverName: string,
235
+ ): boolean {
236
+ return ensureClaudeCodeMcpJsonServersEnabled(projectRoot, [serverName]);
237
+ }
238
+
226
239
  export function ensureProjectWorkflowMcpConfig(
227
240
  projectRoot: string,
228
241
  env: NodeJS.ProcessEnv = process.env,
@@ -241,14 +254,25 @@ export function ensureProjectWorkflowMcpConfig(
241
254
  const desiredServerNames = Object.keys(desiredServers);
242
255
 
243
256
  const alreadyPresent = existsSync(configPath);
244
- const unchanged =
257
+ const mcpConfigUnchanged =
245
258
  desiredServerNames.every((serverName) => (
246
259
  JSON.stringify(previousServers[serverName] ?? null)
247
260
  === JSON.stringify(desiredServers[serverName])
248
261
  ))
249
262
  && existing.mcpServers !== undefined;
250
263
 
251
- if (unchanged) {
264
+ if (!mcpConfigUnchanged) {
265
+ const nextConfig: McpConfigFile = {
266
+ ...existing,
267
+ mcpServers: nextServers,
268
+ };
269
+
270
+ writeFileSync(configPath, `${JSON.stringify(nextConfig, null, 2)}\n`, "utf-8");
271
+ }
272
+
273
+ const localSettingsChanged = ensureClaudeCodeMcpJsonServersEnabled(resolvedProjectRoot, desiredServerNames);
274
+
275
+ if (mcpConfigUnchanged && !localSettingsChanged) {
252
276
  return {
253
277
  configPath,
254
278
  serverName: workflowServerName,
@@ -257,13 +281,6 @@ export function ensureProjectWorkflowMcpConfig(
257
281
  };
258
282
  }
259
283
 
260
- const nextConfig: McpConfigFile = {
261
- ...existing,
262
- mcpServers: nextServers,
263
- };
264
-
265
- writeFileSync(configPath, `${JSON.stringify(nextConfig, null, 2)}\n`, "utf-8");
266
-
267
284
  return {
268
285
  configPath,
269
286
  serverName: workflowServerName,
@@ -777,7 +777,10 @@ export function decayStaleMemories(thresholdUnits = 20): string[] {
777
777
  const cutoff = row['processed_at'] as string;
778
778
  const affected = adapter.prepare(
779
779
  `SELECT id FROM memories
780
- WHERE superseded_by IS NULL AND updated_at < :cutoff AND confidence > 0.1`,
780
+ WHERE superseded_by IS NULL
781
+ AND updated_at < :cutoff
782
+ AND confidence > 0.1
783
+ AND (structured_fields IS NULL OR structured_fields NOT LIKE '%"sourceDecisionId"%')`,
781
784
  ).all({ ':cutoff': cutoff }).map((r) => r['id'] as string);
782
785
 
783
786
  decayMemoriesBefore(cutoff, new Date().toISOString());
@@ -118,10 +118,10 @@ export async function checkMarkdownHierarchyAgainstDb(
118
118
  markdown,
119
119
  beforeDb,
120
120
  afterDb: beforeDb,
121
- recoveryCommand: "/gsd recover",
121
+ recoveryCommand: "/gsd recover --confirm",
122
122
  message:
123
123
  `Markdown planning artifacts (${markdown.milestones}M/${markdown.slices}S/${markdown.tasks}T) ` +
124
124
  `do not match the authoritative DB (${beforeDb.milestones}M/${beforeDb.slices}S/${beforeDb.tasks}T). ` +
125
- "Runtime startup will not import markdown automatically; run `/gsd recover` if markdown should repopulate the database.",
125
+ "Runtime startup will not import markdown automatically; run `/gsd recover --confirm` if markdown should repopulate the database.",
126
126
  };
127
127
  }
@@ -16,6 +16,7 @@ import { extractVerdict, isAcceptableUatVerdict } from "./verdict-parser.js";
16
16
  import { logWarning } from "./workflow-logger.js";
17
17
  import { hasImplementationArtifacts } from "./milestone-implementation-evidence.js";
18
18
  import { buildCompleteMilestonePrompt } from "./auto-prompts.js";
19
+ import { checkCloseoutConsistencyGate } from "./closeout-consistency-gate.js";
19
20
  import type { DispatchAction, DispatchContext } from "./auto-dispatch.js";
20
21
  import {
21
22
  commitPendingMilestoneCloseoutChanges,
@@ -37,7 +38,8 @@ export async function isMilestoneCloseoutSettled(mid: string, basePath: string):
37
38
  if (isDbAvailable()) {
38
39
  const milestone = getMilestone(mid);
39
40
  if (milestone && isClosedStatus(milestone.status)) {
40
- if (verifyExpectedArtifact("complete-milestone", mid, basePath)) {
41
+ const closeoutGate = checkCloseoutConsistencyGate(mid, { refreshFromDisk: true });
42
+ if (closeoutGate.ok && verifyExpectedArtifact("complete-milestone", mid, basePath)) {
41
43
  return true;
42
44
  }
43
45
  }
@@ -14,7 +14,6 @@ export interface PendingAutoStartEntry {
14
14
  createdAt: number;
15
15
  readyRejectCount?: number;
16
16
  scope: MilestoneScope;
17
- planBlockedRecoveryCount: number;
18
17
  r3bRecoveryCount: number;
19
18
  }
20
19
 
@@ -51,7 +50,6 @@ export function setPendingAutoStart(basePath: string, entry: PendingAutoStartInp
51
50
  const scope = scopeMilestone(ws, entry.milestoneId);
52
51
  pendingAutoStartMap.set(basePath, {
53
52
  createdAt: Date.now(),
54
- planBlockedRecoveryCount: 0,
55
53
  r3bRecoveryCount: 0,
56
54
  ...entry,
57
55
  scope,
@@ -9,6 +9,7 @@ import type {
9
9
  HookDispatchResult,
10
10
  PreDispatchResult,
11
11
  HookStatusEntry,
12
+ PostUnitGateBlock,
12
13
  } from "./types.js";
13
14
  import { getOrCreateRegistry, resolveHookArtifactPath } from "./rule-registry.js";
14
15
 
@@ -33,10 +34,22 @@ export function isRetryPending(): boolean {
33
34
  return getOrCreateRegistry().isRetryPending();
34
35
  }
35
36
 
36
- export function consumeRetryTrigger(): { unitType: string; unitId: string; retryArtifact: string } | null {
37
+ export function consumeRetryTrigger(): { unitType: string; unitId: string; retryArtifact?: string } | null {
37
38
  return getOrCreateRegistry().consumeRetryTrigger();
38
39
  }
39
40
 
41
+ export function consumeHookFailure(): { hookName: string; unitType: string; unitId: string; reason: string } | null {
42
+ return getOrCreateRegistry().consumeHookFailure();
43
+ }
44
+
45
+ export function isGateBlockPending(): boolean {
46
+ return getOrCreateRegistry().isGateBlockPending();
47
+ }
48
+
49
+ export function consumeGateBlock(): PostUnitGateBlock | null {
50
+ return getOrCreateRegistry().consumeGateBlock();
51
+ }
52
+
40
53
  export function resetHookState(): void {
41
54
  getOrCreateRegistry().resetState();
42
55
  }
@@ -423,7 +423,7 @@ export interface GSDPreferences {
423
423
  search_provider?: "brave" | "tavily" | "ollama" | "native" | "auto";
424
424
  /** Context selection mode for file inlining. "full" inlines entire files, "smart" uses semantic chunking. Default derived from token profile. */
425
425
  context_selection?: ContextSelectionMode;
426
- /** Default widget display mode for auto-mode dashboard. "full" | "small" | "min" | "off". Default: "full". */
426
+ /** Default widget display mode for auto-mode dashboard. "full" | "small" | "min" | "off". Default: "small". */
427
427
  widget_mode?: "full" | "small" | "min" | "off";
428
428
  /** Reactive (graph-derived parallel) task execution within slices. Disabled by default. */
429
429
  reactive_execution?: ReactiveExecutionConfig;
@@ -29,6 +29,14 @@ const VALID_UOK_TURN_ACTIONS = new Set<"commit" | "snapshot" | "status-only">([
29
29
  "snapshot",
30
30
  "status-only",
31
31
  ]);
32
+ const VALID_POST_UNIT_HOOK_CRITICALITIES = new Set(["advisory", "blocking"]);
33
+ const VALID_POST_UNIT_HOOK_ON_BLOCK_ACTIONS = new Set([
34
+ "retry-unit",
35
+ "retry-task",
36
+ "queue-task",
37
+ "queue-slice",
38
+ "pause",
39
+ ]);
32
40
 
33
41
  export function validatePreferences(preferences: GSDPreferences): {
34
42
  preferences: GSDPreferences;
@@ -486,9 +494,37 @@ export function validatePreferences(preferences: GSDPreferences): {
486
494
  if (typeof hook.artifact === "string" && hook.artifact.trim()) {
487
495
  validHook.artifact = hook.artifact.trim();
488
496
  }
497
+ if (hook.criticality !== undefined) {
498
+ const criticality = typeof hook.criticality === "string" ? hook.criticality.trim() : "";
499
+ if (VALID_POST_UNIT_HOOK_CRITICALITIES.has(criticality)) {
500
+ validHook.criticality = criticality as PostUnitHookConfig["criticality"];
501
+ } else {
502
+ errors.push(`post_unit_hooks "${name}" invalid criticality: ${String(hook.criticality)}`);
503
+ }
504
+ }
489
505
  if (typeof hook.retry_on === "string" && hook.retry_on.trim()) {
490
506
  validHook.retry_on = hook.retry_on.trim();
491
507
  }
508
+ if (hook.on_block !== undefined) {
509
+ if (!hook.on_block || typeof hook.on_block !== "object") {
510
+ errors.push(`post_unit_hooks "${name}" on_block must be an object`);
511
+ } else {
512
+ const onBlock = hook.on_block as unknown as Record<string, unknown>;
513
+ const action = typeof onBlock.action === "string" ? onBlock.action.trim() : "";
514
+ if (!VALID_POST_UNIT_HOOK_ON_BLOCK_ACTIONS.has(action)) {
515
+ errors.push(`post_unit_hooks "${name}" invalid on_block action: ${String(onBlock.action)}`);
516
+ } else {
517
+ validHook.on_block = { action: action as NonNullable<PostUnitHookConfig["on_block"]>["action"] };
518
+ if (typeof onBlock.artifact === "string" && onBlock.artifact.trim()) {
519
+ validHook.on_block.artifact = onBlock.artifact.trim();
520
+ }
521
+ }
522
+ }
523
+ }
524
+ if (validHook.criticality === "blocking" && !validHook.artifact) {
525
+ errors.push(`post_unit_hooks "${name}" criticality blocking requires artifact`);
526
+ continue;
527
+ }
492
528
  if (typeof hook.agent === "string" && hook.agent.trim()) {
493
529
  validHook.agent = hook.agent.trim();
494
530
  }
@@ -33,6 +33,10 @@ function hasRequiredExtensionAssets(rootDir: string, exists: ExistsFn = existsSy
33
33
  );
34
34
  }
35
35
 
36
+ function isSourceExtensionDir(moduleDir: string): boolean {
37
+ return moduleDir.replaceAll("\\", "/").endsWith("/src/resources/extensions/gsd");
38
+ }
39
+
36
40
  export function resolveExtensionDirFromCandidates(
37
41
  moduleDir: string,
38
42
  agentGsdDir: string,
@@ -41,6 +45,10 @@ export function resolveExtensionDirFromCandidates(
41
45
  const moduleUsable = hasRequiredExtensionAssets(moduleDir, exists);
42
46
  const agentUsable = hasRequiredExtensionAssets(agentGsdDir, exists);
43
47
 
48
+ // Source checkouts must use their own prompt tree. Otherwise local tests and
49
+ // dev runs can silently render stale prompts from ~/.gsd/agent/extensions/gsd.
50
+ if (moduleUsable && isSourceExtensionDir(moduleDir)) return moduleDir;
51
+
44
52
  // Prefer the user-local extension tree when both are valid. This avoids
45
53
  // leaking npm/global-install paths into prompts on Windows.
46
54
  if (agentUsable) return agentGsdDir;
@@ -12,6 +12,8 @@ Debug GSD itself. Trace the symptom to root cause in current source and produce
12
12
 
13
13
  GSD extension source: `{{gsdSourceDir}}`
14
14
 
15
+ {{toolingSection}}
16
+
15
17
  ### Source Map by Domain
16
18
 
17
19
  | Domain | Files |
@@ -101,7 +103,7 @@ Then **offer GitHub issue creation**: "Would you like me to create a GitHub issu
101
103
 
102
104
  **CRITICAL:** The `github_issues` tool targets only the current user's repository and has no `repo` parameter. Use `gh issue create --repo open-gsd/gsd-pi` via `bash`. Do NOT use the `github_issues` tool.
103
105
 
104
- If yes, create using the `bash` tool:
106
+ If yes and `bash` is available, create using the `bash` tool:
105
107
 
106
108
  ```bash
107
109
  ISSUE_BODY_FILE="${TMPDIR:-${TEMP:-${TMP:-.}}}/gsd-forensic-issue.md"
@@ -142,6 +144,64 @@ TYPE_ID=$(gh api graphql -f query='{ repository(owner:"open-gsd",name:"gsd-pi")
142
144
  gh api graphql -f query='mutation { updateIssue(input:{id:"'"$ISSUE_ID"'",issueTypeId:"'"$TYPE_ID"'"}) { issue { number } } }'
143
145
  ```
144
146
 
147
+ If `bash` is unavailable, do not attempt `bash`, `write`, or `github_issues` tool calls. Instead, provide exactly one paste-once shell script for the user to run locally and say that the live duplicate check / issue creation must be run by the user:
148
+
149
+ ```bash
150
+ KEYWORDS="..."
151
+ echo "Searching closed issues for possible duplicates..."
152
+ gh issue list --repo open-gsd/gsd-pi --state closed --search "$KEYWORDS" --limit 20
153
+
154
+ echo "Searching open PRs for possible fixes..."
155
+ gh pr list --repo open-gsd/gsd-pi --state open --search "$KEYWORDS" --limit 10
156
+
157
+ echo "Searching merged PRs for possible fixes..."
158
+ gh pr list --repo open-gsd/gsd-pi --state merged --search "$KEYWORDS" --limit 10
159
+
160
+ read -r -p "Review the duplicate search above. Continue filing a new issue? [y/N] " SHOULD_FILE
161
+ case "$SHOULD_FILE" in
162
+ y|Y|yes|YES) ;;
163
+ *) echo "Issue filing aborted."; exit 0 ;;
164
+ esac
165
+
166
+ ISSUE_BODY_FILE="${TMPDIR:-${TEMP:-${TMP:-.}}}/gsd-forensic-issue.md"
167
+ cat > "$ISSUE_BODY_FILE" << 'GSD_ISSUE_BODY'
168
+ ## Problem
169
+ [1-2 sentence summary]
170
+
171
+ ## Root Cause
172
+ [Specific file:line in GSD source, with code snippet showing the bug]
173
+
174
+ ## Expected Behavior
175
+ [What the code should do instead — concrete fix suggestion]
176
+
177
+ ## Environment
178
+ - GSD version: [from report]
179
+ - Model: [from report]
180
+ - Unit: [type/id that failed]
181
+
182
+ ## Reproduction Context
183
+ [Phase, milestone, slice, what was happening when it failed]
184
+
185
+ ## Forensic Evidence
186
+ [Key anomalies, error traces, relevant tool call sequences from the report]
187
+
188
+ ---
189
+ *Auto-generated by `/gsd forensics`*
190
+ GSD_ISSUE_BODY
191
+
192
+ ISSUE_URL=$(gh issue create --repo open-gsd/gsd-pi \
193
+ --title "..." \
194
+ --label "auto-generated" \
195
+ --body-file "$ISSUE_BODY_FILE")
196
+ rm -f "$ISSUE_BODY_FILE"
197
+
198
+ ISSUE_NUM=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
199
+ ISSUE_ID=$(gh api graphql -f query='{ repository(owner:"open-gsd",name:"gsd-pi") { issue(number:'"$ISSUE_NUM"') { id } } }' --jq '.data.repository.issue.id')
200
+ TYPE_ID=$(gh api graphql -f query='{ repository(owner:"open-gsd",name:"gsd-pi") { issueTypes(first:20) { nodes { id name } } } }' --jq '.data.repository.issueTypes.nodes[] | select(.name=="Bug") | .id')
201
+ gh api graphql -f query='mutation { updateIssue(input:{id:"'"$ISSUE_ID"'",issueTypeId:"'"$TYPE_ID"'"}) { issue { number } } }'
202
+ echo "$ISSUE_URL"
203
+ ```
204
+
145
205
  ### Redaction Rules (CRITICAL)
146
206
 
147
207
  Before creating the issue, you MUST:
@@ -8,6 +8,8 @@
8
8
 
9
9
  You are evaluating **quality gates in parallel** for this slice. Each gate is an independent question that must be answered before task execution begins. Use the `subagent` tool to dispatch all gate evaluations simultaneously.
10
10
 
11
+ **Tool call format:** Call `subagent` with `tasks: [...]` as a **native JSON array** — one object per gate. Do NOT JSON.stringify the array into a string; the tool validates that `tasks` is an array, and a serialized string will be rejected with "must be array".
12
+
11
13
  ## Slice Plan Context
12
14
 
13
15
  {{slicePlanContent}}
@@ -20,7 +22,7 @@ You are evaluating **quality gates in parallel** for this slice. Each gate is an
20
22
 
21
23
  ## Execution Protocol
22
24
 
23
- 1. **Dispatch all gates** using `subagent` in parallel mode. Each subagent prompt is provided below.
25
+ 1. **Dispatch all gates** using `subagent` in parallel mode. Call `subagent` with `tasks: [{ agent: "tester", task: "<prompt>" }, ...]` — one object per gate. Each subagent prompt is provided below.
24
26
  Pass `tasks` as a **JSON array**, not a string. Example shape:
25
27
 
26
28
  ```json
@@ -12,9 +12,11 @@ You are dispatching parallel research agents for **{{sliceCount}} slices** in mi
12
12
 
13
13
  Dispatch ALL slices simultaneously using the `subagent` tool in **parallel mode**. Each subagent will independently research its slice and write a RESEARCH file.
14
14
 
15
+ **Tool call format:** Call `subagent` with `tasks: [...]` as a **native JSON array** — one object per slice. Do NOT JSON.stringify the array into a string; the tool validates that `tasks` is an array, and a serialized string will be rejected with "must be array".
16
+
15
17
  ## Execution Protocol
16
18
 
17
- 1. Call `subagent` with `tasks: [...]` containing one entry per slice below
19
+ 1. Call `subagent` with `tasks: [{ agent: "scout", task: "<prompt>" }, ...]` containing one entry per slice below
18
20
  2. Wait for ALL subagents to complete
19
21
  3. Verify each slice's RESEARCH file was written (check `.gsd/milestones/{{mid}}/slices/<slice-id>/`)
20
22
  4. If a subagent failed to write its RESEARCH file, retry it **once** individually
@@ -43,7 +43,7 @@ If slice research is inlined, trust its architectural findings, but verify every
43
43
  5. Define slice verification before tasks. Non-trivial slices need real tests or executable assertions; boundary contracts need contract-exercising checks. Tests must not read .gitignore/gitignored paths such as `.gsd/`, `.planning/`, or `.audits/`.
44
44
  6. Include Threat Surface (Q3), Requirement Impact (Q4), proof level, observability, integration closure, Failure Modes (Q5), Load Profile (Q6), and Negative Tests (Q7) only where applicable.
45
45
  7. Right-size tasks. Simple slices can be one task; split only when context, ownership, or verification boundaries justify it.
46
- 8. Task `verify` commands must be safe, simple commands. Do not use shell pipes, redirects, semicolons, backticks, command substitution, output trimming, or grep regex alternation with `|`. If multiple checks are needed, create a small test file and run it with `node --test` or a package test script, or use separate simple commands joined only with `&&`.
46
+ 8. Task `verify` commands must be safe, simple commands. Do not use shell pipes, redirects, semicolons, backticks, command substitution, output trimming, or grep regex alternation with `|`. If multiple checks are needed, create a small test file and run it with `node --test` or a package test script, or use separate simple commands joined only with `&&`. For absence checks, verify a pattern does not exist with `! grep -q 'pattern' file` or `! rg -q 'pattern' file`; do not use `grep -c` or `rg -c` to assert zero matches because count commands exit 1 when they find zero matches, and the verification gate treats that as failure.
47
47
  9. Each task needs the exact `gsd_plan_slice.tasks[]` shape: `taskId`, `title`, `description`, `estimate`, `files`, `verify`, `inputs`, `expectedOutput`, and optional `observabilityImpact`. `description` should contain the Why / Do / Done-when narrative. `files`, `inputs`, and `expectedOutput` must be JSON arrays of strings, even when there is only one path (for example, `"inputs": ["src/index.ts"]`, never `"inputs": "src/index.ts"`). Use paths relative to `{{workingDirectory}}`; do not put absolute paths to the original checkout or any directory outside `{{workingDirectory}}` in `files`, `inputs`, `expectedOutput`, or verification commands. **`expectedOutput` must only list files the task actually creates or overwrites on disk.** Do NOT include files the task merely reads, verifies, or tests — those belong only in `inputs`. If a task is a pure verification or test task that produces no new files, `expectedOutput` may be `[]` or limited to test-result artifacts (e.g. a log or assertion output). A file that does not yet exist on disk and is needed as an `input` must be produced by an earlier task's `expectedOutput` — if no prior task creates it, add a task before this one that does.
48
48
  10. Persist with `gsd_plan_slice` using `milestoneId`, `sliceId`, `goal`, optional `successCriteria`/`proofLevel`/`integrationClosure`/`observabilityImpact`, and `tasks`. `gsd_plan_slice` handles task persistence transactionally and renders `{{outputPath}}` plus task plans; do not call `gsd_plan_task`. The DB-backed tool is the canonical write path. Do **not** rely on direct `PLAN.md` writes as the source of truth.
49
49
  11. Self-audit before finishing: goal/demo closure, requirement coverage, deliverable coverage audit (cross-check every file listed in CONTEXT.md `## Scope` / `### In Scope` against task `files` or `expectedOutput`), locked decisions, concrete paths, dependency order, wiring, scope size, proof truthfulness, feature completeness, and quality gates. Quality gates: non-trivial slices/tasks include specific Q3-Q7 coverage where applicable.
@@ -10,6 +10,8 @@ You are executing **multiple tasks in parallel** for this slice. The task graph
10
10
 
11
11
  **Critical rule:** Use the `subagent` tool in **parallel mode** to dispatch all ready tasks simultaneously. Each subagent gets a task-specific execution packet (task plan + dependency carry-forward + completion contract) and is responsible for its own implementation, verification, task summary, and completion tool calls. The parent batch agent orchestrates, verifies, and records failures only when a dispatched task failed before it could leave its own summary behind.
12
12
 
13
+ **Tool call format:** Call `subagent` with `tasks: [...]` as a **native JSON array** — one object per ready task. Do NOT JSON.stringify the array into a string; the tool validates that `tasks` is an array, and a serialized string will be rejected with "must be array".
14
+
13
15
  ## Task Dependency Graph
14
16
 
15
17
  {{graphContext}}
@@ -22,7 +24,7 @@ You are executing **multiple tasks in parallel** for this slice. The task graph
22
24
 
23
25
  ## Execution Protocol
24
26
 
25
- 1. **Dispatch all ready tasks** using `subagent` in parallel mode. Each subagent prompt is provided below.
27
+ 1. **Dispatch all ready tasks** using `subagent` in parallel mode. Call `subagent` with `tasks: [{ agent: "worker", task: "<prompt>" }, ...]` — one object per ready task. Each subagent prompt is provided below.
26
28
  2. **Wait for all subagents** to complete.
27
29
  3. **Verify each dispatched task's outputs** — check that expected files were created/modified, that verification commands pass where applicable, and that each task wrote its own `T##-SUMMARY.md`.
28
30
  4. **Do not rewrite successful task summaries or duplicate completion tool calls.** Treat a subagent-written summary as authoritative for that task.