gsd-pi 2.82.0 → 3.0.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 (555) hide show
  1. package/README.md +51 -32
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +10 -1
  4. package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
  5. package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
  6. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  7. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +1 -1
  8. package/dist/resources/extensions/cmux/index.js +5 -0
  9. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  10. package/dist/resources/extensions/gsd/auto/loop.js +19 -6
  11. package/dist/resources/extensions/gsd/auto/orchestrator.js +124 -6
  12. package/dist/resources/extensions/gsd/auto/phases.js +90 -31
  13. package/dist/resources/extensions/gsd/auto/session.js +4 -0
  14. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  15. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  16. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  17. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  18. package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
  19. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  20. package/dist/resources/extensions/gsd/auto-post-unit.js +246 -133
  21. package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
  22. package/dist/resources/extensions/gsd/auto-recovery.js +71 -14
  23. package/dist/resources/extensions/gsd/auto-start.js +87 -14
  24. package/dist/resources/extensions/gsd/auto-verification.js +45 -26
  25. package/dist/resources/extensions/gsd/auto-worktree.js +176 -10
  26. package/dist/resources/extensions/gsd/auto.js +178 -63
  27. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
  28. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
  29. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +9 -2
  30. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  31. package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
  32. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +17 -3
  33. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  34. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  35. package/dist/resources/extensions/gsd/commands/handlers/core.js +39 -1
  36. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  37. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  38. package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
  39. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
  40. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  41. package/dist/resources/extensions/gsd/context-store.js +112 -0
  42. package/dist/resources/extensions/gsd/crash-recovery.js +43 -5
  43. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  44. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  45. package/dist/resources/extensions/gsd/db-writer.js +150 -84
  46. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  47. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  48. package/dist/resources/extensions/gsd/doctor-git-checks.js +87 -7
  49. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  50. package/dist/resources/extensions/gsd/doctor.js +2 -28
  51. package/dist/resources/extensions/gsd/export-html.js +27 -425
  52. package/dist/resources/extensions/gsd/forensics.js +3 -3
  53. package/dist/resources/extensions/gsd/git-service.js +45 -3
  54. package/dist/resources/extensions/gsd/gsd-db.js +21 -6
  55. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  56. package/dist/resources/extensions/gsd/guided-flow.js +101 -116
  57. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  58. package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
  59. package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
  60. package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
  61. package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
  62. package/dist/resources/extensions/gsd/markdown-renderer.js +16 -9
  63. package/dist/resources/extensions/gsd/md-importer.js +1 -1
  64. package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
  65. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
  66. package/dist/resources/extensions/gsd/migrate/command.js +5 -0
  67. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  68. package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
  69. package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
  70. package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
  71. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  72. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  73. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  74. package/dist/resources/extensions/gsd/paths.js +4 -0
  75. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  76. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
  77. package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
  78. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  79. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  80. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  82. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  83. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  84. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  85. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  86. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  87. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  88. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  89. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  90. package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
  91. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  92. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  93. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  94. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  95. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  96. package/dist/resources/extensions/gsd/state.js +3 -3
  97. package/dist/resources/extensions/gsd/status-guards.js +11 -0
  98. package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
  99. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  100. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  101. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  102. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  103. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  104. package/dist/resources/extensions/gsd/tools/plan-slice.js +87 -14
  105. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  106. package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
  107. package/dist/resources/extensions/gsd/validation.js +23 -1
  108. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  109. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  110. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  111. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  112. package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
  113. package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
  114. package/dist/resources/extensions/shared/html-shell.js +388 -0
  115. package/dist/resources/extensions/subagent/index.js +448 -78
  116. package/dist/resources/extensions/subagent/launch.js +77 -0
  117. package/dist/resources/extensions/subagent/run-store.js +148 -0
  118. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  119. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  120. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  121. package/dist/resources/extensions/visual-brief/index.js +5 -0
  122. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  123. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  124. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  125. package/dist/web/standalone/.next/BUILD_ID +1 -1
  126. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  127. package/dist/web/standalone/.next/build-manifest.json +3 -3
  128. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  129. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  130. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  140. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  147. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  150. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/index.html +1 -1
  153. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  154. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  155. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  156. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  158. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  159. package/dist/web/standalone/.next/server/app/page.js +2 -2
  160. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  163. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  164. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  168. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  169. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  170. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  171. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  172. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  173. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  174. package/dist/web/standalone/.next/static/chunks/app/layout-b23b3f6858dc6dc8.js +1 -0
  175. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  176. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  177. package/package.json +6 -5
  178. package/packages/contracts/dist/rpc.test.js +7 -0
  179. package/packages/contracts/dist/rpc.test.js.map +1 -1
  180. package/packages/contracts/dist/workflow.d.ts +21 -0
  181. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  182. package/packages/contracts/dist/workflow.js +24 -0
  183. package/packages/contracts/dist/workflow.js.map +1 -1
  184. package/packages/contracts/src/rpc.test.ts +8 -0
  185. package/packages/contracts/src/workflow.ts +24 -0
  186. package/packages/daemon/package.json +2 -2
  187. package/packages/mcp-server/README.md +14 -3
  188. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  189. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  190. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  191. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  192. package/packages/mcp-server/package.json +2 -2
  193. package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
  194. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  195. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  196. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  197. package/packages/native/package.json +1 -1
  198. package/packages/native/tsconfig.json +2 -1
  199. package/packages/native/tsconfig.tsbuildinfo +1 -1
  200. package/packages/pi-agent-core/package.json +1 -1
  201. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  202. package/packages/pi-ai/dist/index.d.ts +2 -2
  203. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  204. package/packages/pi-ai/dist/index.js +1 -1
  205. package/packages/pi-ai/dist/index.js.map +1 -1
  206. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  207. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  208. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  209. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  210. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  211. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  212. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  213. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  214. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  215. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  216. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  217. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  218. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  219. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  220. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  221. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  222. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  223. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  224. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  225. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  226. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  227. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  228. package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
  229. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  230. package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
  231. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  232. package/packages/pi-ai/package.json +1 -1
  233. package/packages/pi-ai/src/index.ts +7 -2
  234. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  235. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  236. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  237. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  238. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  239. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  240. package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
  241. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  242. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  243. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  244. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  245. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  246. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  247. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  249. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  251. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  252. package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
  253. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  256. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
  259. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  261. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  263. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  265. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
  267. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
  268. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
  269. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
  270. package/packages/pi-coding-agent/package.json +1 -1
  271. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  272. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  273. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  274. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  275. package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
  276. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  277. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
  278. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  279. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  280. package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
  281. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  282. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  283. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  284. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  285. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  286. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  287. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  288. package/packages/pi-tui/dist/terminal.js +12 -0
  289. package/packages/pi-tui/dist/terminal.js.map +1 -1
  290. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  291. package/packages/pi-tui/dist/tui.js +5 -0
  292. package/packages/pi-tui/dist/tui.js.map +1 -1
  293. package/packages/pi-tui/package.json +1 -1
  294. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  295. package/packages/pi-tui/src/terminal.ts +11 -0
  296. package/packages/pi-tui/src/tui.ts +6 -0
  297. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  298. package/packages/rpc-client/package.json +1 -1
  299. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  300. package/pkg/package.json +1 -1
  301. package/src/resources/GSD-WORKFLOW.md +10 -1
  302. package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
  303. package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
  304. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  305. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +1 -1
  306. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  307. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +9 -0
  308. package/src/resources/extensions/cmux/index.ts +6 -0
  309. package/src/resources/extensions/gsd/auto/contracts.ts +59 -16
  310. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  311. package/src/resources/extensions/gsd/auto/loop.ts +22 -6
  312. package/src/resources/extensions/gsd/auto/orchestrator.ts +129 -6
  313. package/src/resources/extensions/gsd/auto/phases.ts +104 -38
  314. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  315. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  316. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  317. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  318. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  319. package/src/resources/extensions/gsd/auto-dispatch.ts +21 -19
  320. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  321. package/src/resources/extensions/gsd/auto-post-unit.ts +279 -144
  322. package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
  323. package/src/resources/extensions/gsd/auto-recovery.ts +74 -11
  324. package/src/resources/extensions/gsd/auto-start.ts +94 -12
  325. package/src/resources/extensions/gsd/auto-verification.ts +58 -36
  326. package/src/resources/extensions/gsd/auto-worktree.ts +193 -10
  327. package/src/resources/extensions/gsd/auto.ts +187 -61
  328. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
  329. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
  330. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -2
  331. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  332. package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
  333. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +20 -4
  334. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  335. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  336. package/src/resources/extensions/gsd/commands/handlers/core.ts +42 -1
  337. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  338. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  339. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  340. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
  341. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  342. package/src/resources/extensions/gsd/context-store.ts +120 -1
  343. package/src/resources/extensions/gsd/crash-recovery.ts +44 -4
  344. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  345. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  346. package/src/resources/extensions/gsd/db-writer.ts +167 -84
  347. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
  348. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  349. package/src/resources/extensions/gsd/doctor-git-checks.ts +89 -7
  350. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  351. package/src/resources/extensions/gsd/doctor-types.ts +3 -0
  352. package/src/resources/extensions/gsd/doctor.ts +2 -27
  353. package/src/resources/extensions/gsd/export-html.ts +27 -427
  354. package/src/resources/extensions/gsd/forensics.ts +3 -3
  355. package/src/resources/extensions/gsd/git-service.ts +51 -4
  356. package/src/resources/extensions/gsd/gsd-db.ts +21 -6
  357. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  358. package/src/resources/extensions/gsd/guided-flow.ts +134 -133
  359. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  360. package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
  361. package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
  362. package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
  363. package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
  364. package/src/resources/extensions/gsd/markdown-renderer.ts +16 -9
  365. package/src/resources/extensions/gsd/md-importer.ts +1 -1
  366. package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
  367. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
  368. package/src/resources/extensions/gsd/migrate/command.ts +5 -0
  369. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  370. package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
  371. package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
  372. package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
  373. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  374. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  375. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  376. package/src/resources/extensions/gsd/paths.ts +5 -0
  377. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  378. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  379. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  380. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  381. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  382. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  383. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  384. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  385. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  386. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  387. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  388. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  389. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  390. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  391. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  392. package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
  393. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  394. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  395. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  396. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  397. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  398. package/src/resources/extensions/gsd/state.ts +3 -3
  399. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  400. package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
  401. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  402. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  403. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  404. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  405. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -0
  406. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +487 -4
  407. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  408. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  409. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  410. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +91 -6
  411. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
  412. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  413. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  414. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  415. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  416. package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
  417. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  418. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  419. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
  420. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  421. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  422. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  423. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  424. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  425. package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
  426. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +86 -2
  427. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  428. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  429. package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
  430. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
  431. package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
  432. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  433. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
  434. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  435. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  436. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
  437. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  438. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
  439. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +11 -0
  440. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
  441. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  442. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  443. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  444. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  445. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  446. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  447. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  448. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  449. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  450. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  451. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
  452. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  453. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +112 -1
  454. package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
  455. package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
  456. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  457. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +46 -0
  458. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
  459. package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
  460. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
  461. package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
  462. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
  463. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  464. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
  465. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  466. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
  467. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  468. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
  469. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  470. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  471. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  472. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  473. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
  474. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  475. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  476. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +251 -2
  477. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  478. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  479. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
  480. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  481. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  482. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
  483. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +59 -0
  484. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
  485. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  486. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  487. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
  488. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  489. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  490. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  491. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  492. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
  493. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
  494. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  495. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
  496. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  497. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  498. package/src/resources/extensions/gsd/tests/status-guards.test.ts +13 -1
  499. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  500. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  501. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +103 -7
  502. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  503. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  504. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  505. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  506. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  507. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  508. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  509. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  510. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  511. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
  512. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
  513. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  514. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  515. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  516. package/src/resources/extensions/gsd/tools/plan-slice.ts +97 -12
  517. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  518. package/src/resources/extensions/gsd/types.ts +1 -1
  519. package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
  520. package/src/resources/extensions/gsd/validation.ts +23 -1
  521. package/src/resources/extensions/gsd/verification-gate.ts +78 -6
  522. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  523. package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
  524. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  525. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  526. package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
  527. package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
  528. package/src/resources/extensions/shared/html-shell.ts +412 -0
  529. package/src/resources/extensions/subagent/index.ts +567 -103
  530. package/src/resources/extensions/subagent/launch.ts +131 -0
  531. package/src/resources/extensions/subagent/run-store.ts +218 -0
  532. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  533. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  534. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  535. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  536. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  537. package/src/resources/extensions/visual-brief/index.ts +8 -0
  538. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  539. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  540. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  541. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  542. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  543. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  544. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  545. package/dist/web/standalone/.next/static/chunks/app/layout-9ecfd95f343793f0.js +0 -1
  546. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  547. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  548. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  549. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  550. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  551. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  552. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  553. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  554. /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_buildManifest.js +0 -0
  555. /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_ssgManifest.js +0 -0
@@ -57,6 +57,12 @@ skills_used:
57
57
  - {{howToVerifyThisTaskIsActuallyDone}}
58
58
  - {{commandToRun_OR_behaviorToCheck}}
59
59
 
60
+ ## Verify Rules
61
+
62
+ - Use a real executable check, not prose.
63
+ - If the check needs file-content assertions, write a `node:test` file and run it with `node --test` or a package test script.
64
+ - Do not use inline `node -e` assertions for verification.
65
+
60
66
  ## Observability Impact
61
67
 
62
68
  <!-- OMIT THIS SECTION ENTIRELY for simple tasks that don't touch runtime boundaries,
@@ -72,7 +78,8 @@ skills_used:
72
78
  <!-- Every input MUST be a backtick-wrapped file path. These paths are machine-parsed to
73
79
  derive task dependencies — vague descriptions without paths break dependency detection.
74
80
  For the first task in a slice with no prior task outputs, list the existing source files
75
- this task reads or modifies. -->
81
+ this task reads or modifies.
82
+ Tool field: inputs must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
76
83
 
77
84
  - `{{filePath}}` — {{whatThisTaskNeedsFromPriorWork}}
78
85
 
@@ -82,6 +89,7 @@ skills_used:
82
89
  or modifies. These paths are machine-parsed to derive task dependencies.
83
90
  This task should produce a real increment toward making the slice goal/demo true. A full
84
91
  slice plan should not be able to mark every task complete while the claimed slice behavior
85
- still does not work at the stated proof level. -->
92
+ still does not work at the stated proof level.
93
+ Tool field: expectedOutput must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
86
94
 
87
95
  - `{{filePath}}` — {{whatThisTaskCreatesOrModifies}}
@@ -24,11 +24,11 @@ function renderMilestoneSummaryMarkdown(params, completedAt) {
24
24
  const keyFiles = params.keyFiles ?? [];
25
25
  const lessonsLearned = params.lessonsLearned ?? [];
26
26
  const keyDecisionsYaml = keyDecisions.length > 0
27
- ? keyDecisions.map(d => ` - ${d}`).join("\n")
28
- : " - (none)";
27
+ ? `\n${keyDecisions.map(d => ` - ${d}`).join("\n")}`
28
+ : " []";
29
29
  const keyFilesYaml = keyFiles.length > 0
30
- ? keyFiles.map(f => ` - ${f}`).join("\n")
31
- : " - (none)";
30
+ ? `\n${keyFiles.map(f => ` - ${f}`).join("\n")}`
31
+ : " []";
32
32
  const lessonsYaml = lessonsLearned.length > 0
33
33
  ? lessonsLearned.map(l => ` - ${l}`).join("\n")
34
34
  : " - (none)";
@@ -37,10 +37,8 @@ id: ${params.milestoneId}
37
37
  title: "${displayTitle}"
38
38
  status: complete
39
39
  completed_at: ${completedAt}
40
- key_decisions:
41
- ${keyDecisionsYaml}
42
- key_files:
43
- ${keyFilesYaml}
40
+ key_decisions:${keyDecisionsYaml}
41
+ key_files:${keyFilesYaml}
44
42
  lessons_learned:
45
43
  ${lessonsYaml}
46
44
  ---
@@ -65,11 +65,11 @@ function renderSliceSummaryMarkdown(params) {
65
65
  ? affects.map(a => ` - ${a}`).join("\n")
66
66
  : " []";
67
67
  const keyFilesYaml = keyFiles.length > 0
68
- ? keyFiles.map(f => ` - ${f}`).join("\n")
69
- : " - (none)";
68
+ ? `\n${keyFiles.map(f => ` - ${f}`).join("\n")}`
69
+ : " []";
70
70
  const keyDecisionsYaml = keyDecisions.length > 0
71
- ? keyDecisions.map(d => ` - ${d}`).join("\n")
72
- : " - (none)";
71
+ ? `\n${keyDecisions.map(d => ` - ${d}`).join("\n")}`
72
+ : " []";
73
73
  const patternsYaml = patternsEstablished.length > 0
74
74
  ? patternsEstablished.map(p => ` - ${p}`).join("\n")
75
75
  : " - (none)";
@@ -106,10 +106,8 @@ requires:
106
106
  ${requiresYaml}
107
107
  affects:
108
108
  ${affectsYaml}
109
- key_files:
110
- ${keyFilesYaml}
111
- key_decisions:
112
- ${keyDecisionsYaml}
109
+ key_files:${keyFilesYaml}
110
+ key_decisions:${keyDecisionsYaml}
113
111
  patterns_established:
114
112
  ${patternsYaml}
115
113
  observability_surfaces:
@@ -1,6 +1,6 @@
1
1
  import { clearParseCache } from "../files.js";
2
2
  import { isClosedStatus } from "../status-guards.js";
3
- import { isNonEmptyString, validateStringArray } from "../validation.js";
3
+ import { isNonEmptyString, validateStringArray, validateTitle } from "../validation.js";
4
4
  import { transaction, getMilestone, getMilestoneSlices, getSlice, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
5
5
  import { invalidateStateCache } from "../state.js";
6
6
  import { renderRoadmapFromDb } from "../markdown-renderer.js";
@@ -77,6 +77,9 @@ function validateSlices(value) {
77
77
  seen.add(sliceId);
78
78
  if (!isNonEmptyString(title))
79
79
  throw new Error(`slices[${index}].title must be a non-empty string`);
80
+ const titleIssue = validateTitle(title);
81
+ if (titleIssue)
82
+ throw new Error(`slices[${index}].title is invalid: ${titleIssue}`);
80
83
  if (!isNonEmptyString(risk))
81
84
  throw new Error(`slices[${index}].risk must be a non-empty string`);
82
85
  if (!Array.isArray(depends) || depends.some((item) => !isNonEmptyString(item))) {
@@ -127,6 +130,9 @@ function validateParams(params) {
127
130
  throw new Error("title is required");
128
131
  if (!isNonEmptyString(params?.vision))
129
132
  throw new Error("vision is required");
133
+ const milestoneTitleIssue = validateTitle(params.title);
134
+ if (milestoneTitleIssue)
135
+ throw new Error(`title is invalid: ${milestoneTitleIssue}`);
130
136
  return {
131
137
  ...params,
132
138
  dependsOn: params.dependsOn ? validateStringArray(params.dependsOn, "dependsOn") : [],
@@ -1,7 +1,9 @@
1
+ import { existsSync, rmSync } from "node:fs";
2
+ import { join, relative } from "node:path";
1
3
  import { clearParseCache } from "../files.js";
2
4
  import { isClosedStatus, isDeferredStatus } from "../status-guards.js";
3
- import { isNonEmptyString } from "../validation.js";
4
- import { transaction, getMilestone, getSlice, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, updateSliceStatus, } from "../gsd-db.js";
5
+ import { isNonEmptyString, validateStringArray } from "../validation.js";
6
+ import { transaction, getMilestone, getSlice, getSliceTasks, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, updateSliceStatus, setSliceSketchFlag, deleteTask, deleteArtifactByPath, } from "../gsd-db.js";
5
7
  import { invalidateStateCache } from "../state.js";
6
8
  import { renderPlanFromDb } from "../markdown-renderer.js";
7
9
  import { renderAllProjections } from "../workflow-projections.js";
@@ -9,6 +11,8 @@ import { writeManifest } from "../workflow-manifest.js";
9
11
  import { appendEvent } from "../workflow-events.js";
10
12
  import { logWarning } from "../workflow-logger.js";
11
13
  import { validatePlanningPathScope } from "../planning-path-scope.js";
14
+ import { checkFilePathConsistency, checkTaskOrdering } from "../pre-execution-checks.js";
15
+ import { buildTaskFileName, gsdProjectionRoot } from "../paths.js";
12
16
  function validateTasks(value) {
13
17
  if (!Array.isArray(value) || value.length === 0) {
14
18
  throw new Error("tasks must be a non-empty array");
@@ -39,17 +43,11 @@ function validateTasks(value) {
39
43
  throw new Error(`tasks[${index}].description must be a non-empty string`);
40
44
  if (!isNonEmptyString(estimate))
41
45
  throw new Error(`tasks[${index}].estimate must be a non-empty string`);
42
- if (!Array.isArray(files) || files.some((item) => !isNonEmptyString(item))) {
43
- throw new Error(`tasks[${index}].files must be an array of non-empty strings`);
44
- }
46
+ const validatedFiles = validateStringArray(files, `tasks[${index}].files`);
45
47
  if (!isNonEmptyString(verify))
46
48
  throw new Error(`tasks[${index}].verify must be a non-empty string`);
47
- if (!Array.isArray(inputs) || inputs.some((item) => !isNonEmptyString(item))) {
48
- throw new Error(`tasks[${index}].inputs must be an array of non-empty strings`);
49
- }
50
- if (!Array.isArray(expectedOutput) || expectedOutput.some((item) => !isNonEmptyString(item))) {
51
- throw new Error(`tasks[${index}].expectedOutput must be an array of non-empty strings`);
52
- }
49
+ const validatedInputs = validateStringArray(inputs, `tasks[${index}].inputs`);
50
+ const validatedExpectedOutput = validateStringArray(expectedOutput, `tasks[${index}].expectedOutput`);
53
51
  if (observabilityImpact !== undefined && !isNonEmptyString(observabilityImpact)) {
54
52
  throw new Error(`tasks[${index}].observabilityImpact must be a non-empty string when provided`);
55
53
  }
@@ -58,10 +56,10 @@ function validateTasks(value) {
58
56
  title,
59
57
  description,
60
58
  estimate,
61
- files,
59
+ files: validatedFiles,
62
60
  verify,
63
- inputs,
64
- expectedOutput,
61
+ inputs: validatedInputs,
62
+ expectedOutput: validatedExpectedOutput,
65
63
  observabilityImpact: typeof observabilityImpact === "string" ? observabilityImpact : "",
66
64
  };
67
65
  });
@@ -84,6 +82,53 @@ function validateParams(params) {
84
82
  tasks: validateTasks(params.tasks),
85
83
  };
86
84
  }
85
+ function toTaskRows(params) {
86
+ return params.tasks.map((task, index) => ({
87
+ milestone_id: params.milestoneId,
88
+ slice_id: params.sliceId,
89
+ id: task.taskId,
90
+ title: task.title,
91
+ status: "pending",
92
+ one_liner: "",
93
+ narrative: "",
94
+ verification_result: "",
95
+ duration: "",
96
+ completed_at: null,
97
+ blocker_discovered: false,
98
+ deviations: "",
99
+ known_issues: "",
100
+ key_files: [],
101
+ key_decisions: [],
102
+ full_summary_md: "",
103
+ description: task.description,
104
+ estimate: task.estimate,
105
+ files: task.files,
106
+ verify: task.verify,
107
+ inputs: task.inputs,
108
+ expected_output: task.expectedOutput,
109
+ observability_impact: task.observabilityImpact ?? "",
110
+ full_plan_md: task.fullPlanMd ?? "",
111
+ sequence: index + 1,
112
+ blocker_source: "",
113
+ escalation_pending: 0,
114
+ escalation_awaiting_review: 0,
115
+ escalation_artifact_path: null,
116
+ escalation_override_applied_at: null,
117
+ }));
118
+ }
119
+ function validateTaskPathsBeforePersist(params, basePath) {
120
+ const taskRows = toTaskRows(params);
121
+ const checks = [
122
+ ...checkFilePathConsistency(taskRows, basePath),
123
+ ...checkTaskOrdering(taskRows, basePath),
124
+ ];
125
+ const blocking = checks.filter((check) => !check.passed && check.blocking);
126
+ if (blocking.length === 0)
127
+ return null;
128
+ return blocking
129
+ .map((check) => `[${check.category}] ${check.target}: ${check.message}`)
130
+ .join("\n");
131
+ }
87
132
  export async function handlePlanSlice(rawParams, basePath) {
88
133
  let params;
89
134
  try {
@@ -100,10 +145,15 @@ export async function handlePlanSlice(rawParams, basePath) {
100
145
  if (pathScopeError) {
101
146
  return { error: `validation failed: ${pathScopeError}` };
102
147
  }
148
+ const pathError = validateTaskPathsBeforePersist(params, basePath);
149
+ if (pathError) {
150
+ return { error: `pre-execution validation failed:\n${pathError}` };
151
+ }
103
152
  // ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
104
153
  // Guards must be inside the transaction so the state they check cannot
105
154
  // change between the read and the write (#2723).
106
155
  let guardError = null;
156
+ let omittedTaskIds = [];
107
157
  try {
108
158
  transaction(() => {
109
159
  const parentMilestone = getMilestone(params.milestoneId);
@@ -124,9 +174,21 @@ export async function handlePlanSlice(rawParams, basePath) {
124
174
  guardError = `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first`;
125
175
  return;
126
176
  }
177
+ const newTaskIds = new Set(params.tasks.map((task) => task.taskId));
178
+ const existingTasks = getSliceTasks(params.milestoneId, params.sliceId);
179
+ omittedTaskIds = existingTasks
180
+ .filter((task) => !newTaskIds.has(task.id))
181
+ .map((task) => task.id);
182
+ for (const task of existingTasks) {
183
+ if (!newTaskIds.has(task.id) && isClosedStatus(task.status)) {
184
+ guardError = `cannot remove completed task ${task.id}`;
185
+ return;
186
+ }
187
+ }
127
188
  if (isDeferredStatus(parentSlice.status)) {
128
189
  updateSliceStatus(params.milestoneId, params.sliceId, "pending");
129
190
  }
191
+ setSliceSketchFlag(params.milestoneId, params.sliceId, false);
130
192
  upsertSlicePlanning(params.milestoneId, params.sliceId, {
131
193
  goal: params.goal,
132
194
  successCriteria: params.successCriteria,
@@ -134,6 +196,9 @@ export async function handlePlanSlice(rawParams, basePath) {
134
196
  integrationClosure: params.integrationClosure,
135
197
  observabilityImpact: params.observabilityImpact,
136
198
  });
199
+ for (const taskId of omittedTaskIds) {
200
+ deleteTask(params.milestoneId, params.sliceId, taskId);
201
+ }
137
202
  for (const task of params.tasks) {
138
203
  insertTask({
139
204
  id: task.taskId,
@@ -176,6 +241,14 @@ export async function handlePlanSlice(rawParams, basePath) {
176
241
  return { error: guardError };
177
242
  }
178
243
  try {
244
+ const tasksDir = join(gsdProjectionRoot(basePath), "milestones", params.milestoneId, "slices", params.sliceId, "tasks");
245
+ for (const taskId of omittedTaskIds) {
246
+ const taskPlanPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
247
+ if (existsSync(taskPlanPath))
248
+ rmSync(taskPlanPath, { force: true });
249
+ const artifactPath = relative(gsdProjectionRoot(basePath), taskPlanPath).replace(/\\/g, "/");
250
+ deleteArtifactByPath(artifactPath);
251
+ }
179
252
  const renderResult = await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
180
253
  invalidateStateCache();
181
254
  clearParseCache();
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Adapts shared GSD workflow handlers for MCP executor calls.
1
3
  import { ensureDbOpen } from "../bootstrap/dynamic-tools.js";
2
4
  import { sanitizeCompleteMilestoneParams } from "../bootstrap/sanitize-complete-milestone.js";
3
5
  import { loadWriteGateSnapshot, shouldBlockContextArtifactSaveInSnapshot, shouldBlockRootArtifactSaveInSnapshot } from "../bootstrap/write-gate.js";
@@ -12,6 +14,9 @@ import { handleCompleteSlice } from "./complete-slice.js";
12
14
  import { handlePlanMilestone } from "./plan-milestone.js";
13
15
  import { handlePlanSlice } from "./plan-slice.js";
14
16
  import { handleReplanSlice } from "./replan-slice.js";
17
+ import { handleReopenMilestone } from "./reopen-milestone.js";
18
+ import { handleReopenSlice } from "./reopen-slice.js";
19
+ import { handleReopenTask } from "./reopen-task.js";
15
20
  import { handleReassessRoadmap } from "./reassess-roadmap.js";
16
21
  import { handleValidateMilestone } from "./validate-milestone.js";
17
22
  import { logError, logWarning } from "../workflow-logger.js";
@@ -274,6 +279,120 @@ export async function executeTaskComplete(params, basePath = process.cwd()) {
274
279
  };
275
280
  }
276
281
  }
282
+ export async function executeTaskReopen(params, basePath = process.cwd()) {
283
+ const dbAvailable = await ensureDbOpen(basePath);
284
+ if (!dbAvailable) {
285
+ return {
286
+ content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen task." }],
287
+ details: { operation: "reopen_task", error: "db_unavailable" },
288
+ isError: true,
289
+ };
290
+ }
291
+ try {
292
+ const result = await handleReopenTask(params, basePath);
293
+ if ("error" in result) {
294
+ return {
295
+ content: [{ type: "text", text: `Error reopening task: ${result.error}` }],
296
+ details: { operation: "reopen_task", error: result.error },
297
+ isError: true,
298
+ };
299
+ }
300
+ return {
301
+ content: [{ type: "text", text: `Reopened task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
302
+ details: {
303
+ operation: "reopen_task",
304
+ taskId: result.taskId,
305
+ sliceId: result.sliceId,
306
+ milestoneId: result.milestoneId,
307
+ },
308
+ };
309
+ }
310
+ catch (err) {
311
+ const msg = err instanceof Error ? err.message : String(err);
312
+ logError("tool", `reopen_task tool failed: ${msg}`, { tool: "gsd_task_reopen", error: String(err) });
313
+ return {
314
+ content: [{ type: "text", text: `Error reopening task: ${msg}` }],
315
+ details: { operation: "reopen_task", error: msg },
316
+ isError: true,
317
+ };
318
+ }
319
+ }
320
+ export async function executeSliceReopen(params, basePath = process.cwd()) {
321
+ const dbAvailable = await ensureDbOpen(basePath);
322
+ if (!dbAvailable) {
323
+ return {
324
+ content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen slice." }],
325
+ details: { operation: "reopen_slice", error: "db_unavailable" },
326
+ isError: true,
327
+ };
328
+ }
329
+ try {
330
+ const result = await handleReopenSlice(params, basePath);
331
+ if ("error" in result) {
332
+ return {
333
+ content: [{ type: "text", text: `Error reopening slice: ${result.error}` }],
334
+ details: { operation: "reopen_slice", error: result.error },
335
+ isError: true,
336
+ };
337
+ }
338
+ return {
339
+ content: [{ type: "text", text: `Reopened slice ${result.sliceId} (${result.milestoneId})` }],
340
+ details: {
341
+ operation: "reopen_slice",
342
+ sliceId: result.sliceId,
343
+ milestoneId: result.milestoneId,
344
+ tasksReset: result.tasksReset,
345
+ },
346
+ };
347
+ }
348
+ catch (err) {
349
+ const msg = err instanceof Error ? err.message : String(err);
350
+ logError("tool", `reopen_slice tool failed: ${msg}`, { tool: "gsd_slice_reopen", error: String(err) });
351
+ return {
352
+ content: [{ type: "text", text: `Error reopening slice: ${msg}` }],
353
+ details: { operation: "reopen_slice", error: msg },
354
+ isError: true,
355
+ };
356
+ }
357
+ }
358
+ export async function executeMilestoneReopen(params, basePath = process.cwd()) {
359
+ const dbAvailable = await ensureDbOpen(basePath);
360
+ if (!dbAvailable) {
361
+ return {
362
+ content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen milestone." }],
363
+ details: { operation: "reopen_milestone", error: "db_unavailable" },
364
+ isError: true,
365
+ };
366
+ }
367
+ try {
368
+ const result = await handleReopenMilestone(params, basePath);
369
+ if ("error" in result) {
370
+ return {
371
+ content: [{ type: "text", text: `Error reopening milestone: ${result.error}` }],
372
+ details: { operation: "reopen_milestone", error: result.error },
373
+ isError: true,
374
+ };
375
+ }
376
+ return {
377
+ content: [{ type: "text", text: `Reopened milestone ${result.milestoneId}` }],
378
+ details: {
379
+ operation: "reopen_milestone",
380
+ milestoneId: result.milestoneId,
381
+ slicesReset: result.slicesReset,
382
+ tasksReset: result.tasksReset,
383
+ },
384
+ };
385
+ }
386
+ catch (err) {
387
+ const msg = err instanceof Error ? err.message : String(err);
388
+ logError("tool", `reopen_milestone tool failed: ${msg}`, { tool: "gsd_milestone_reopen", error: String(err) });
389
+ return {
390
+ content: [{ type: "text", text: `Error reopening milestone: ${msg}` }],
391
+ details: { operation: "reopen_milestone", error: msg },
392
+ isError: true,
393
+ };
394
+ }
395
+ }
277
396
  export async function executeSliceComplete(params, basePath = process.cwd()) {
278
397
  const dbAvailable = await ensureDbOpen(basePath);
279
398
  if (!dbAvailable) {
@@ -73,6 +73,7 @@ const COMMON_BUDGET_SMALL = 250_000; // ~65K tokens
73
73
  // allowed-path set for the docs policy lives in one reviewable place.
74
74
  const TOOLS_ALL = { mode: "all" };
75
75
  const TOOLS_PLANNING = { mode: "planning" };
76
+ const TOOLS_VERIFICATION = { mode: "verification" };
76
77
  // Like TOOLS_PLANNING but permits dispatch to read-only recon/planning
77
78
  // specialists. Runtime-enforced by write-gate.ts before the subagent tool runs.
78
79
  const TOOLS_PLANNING_DISPATCH_RECON = {
@@ -187,8 +188,8 @@ export const UNIT_MANIFESTS = {
187
188
  contextMode: "verification",
188
189
  // planning-dispatch: validation is a verification-fan-out unit. It reads
189
190
  // the milestone surface and dispatches reviewer/security/tester subagents
190
- // to report findings without touching user source. Mirrors
191
- // complete-milestone's policy. Write isolation to .gsd/ is preserved.
191
+ // to report findings without touching user source. Write isolation to
192
+ // .gsd/ is preserved.
192
193
  tools: TOOLS_PLANNING_DISPATCH_REVIEW,
193
194
  artifacts: {
194
195
  inline: ["roadmap", "slice-summary", "slice-uat", "requirements", "decisions", "templates"],
@@ -204,11 +205,9 @@ export const UNIT_MANIFESTS = {
204
205
  codebaseMap: false,
205
206
  preferences: "active-only",
206
207
  contextMode: "verification",
207
- // planning-dispatch: completion is a high-leverage place to fan out to
208
- // reviewer / security / tester subagents. They read the diff and report
209
- // findings; they do not write user source. Write isolation to .gsd/ is
210
- // preserved.
211
- tools: TOOLS_PLANNING_DISPATCH_REVIEW,
208
+ // Milestone closeout must run unrestricted shell verification commands
209
+ // against the final diff before recording completion.
210
+ tools: TOOLS_ALL,
212
211
  artifacts: {
213
212
  // #4780 landed slice-summary as excerpt for this unit; phase 2 of
214
213
  // the architecture will read this manifest as the source of truth
@@ -227,7 +226,9 @@ export const UNIT_MANIFESTS = {
227
226
  codebaseMap: true,
228
227
  preferences: "active-only",
229
228
  contextMode: "research",
230
- tools: TOOLS_PLANNING,
229
+ // Multi-slice research dispatches use the research-slice unit contract to
230
+ // fan out scout subagents that write .gsd research artifacts.
231
+ tools: TOOLS_PLANNING_DISPATCH_RECON,
231
232
  artifacts: {
232
233
  inline: ["roadmap", "milestone-research", "dependency-summaries", "templates"],
233
234
  excerpt: [],
@@ -365,7 +366,7 @@ export const UNIT_MANIFESTS = {
365
366
  codebaseMap: false,
366
367
  preferences: "active-only",
367
368
  contextMode: "verification",
368
- tools: TOOLS_PLANNING,
369
+ tools: TOOLS_VERIFICATION,
369
370
  artifacts: {
370
371
  // Phase 3 migration (#4782): manifest matches today's actual
371
372
  // buildRunUatPrompt inlining. Prior phase-1 entry listed
@@ -384,7 +385,9 @@ export const UNIT_MANIFESTS = {
384
385
  codebaseMap: false,
385
386
  preferences: "active-only",
386
387
  contextMode: "verification",
387
- tools: TOOLS_PLANNING,
388
+ // Gate evaluation fans out tester-style subagents, which read the slice
389
+ // plan and report via the DB-backed gate-result tool.
390
+ tools: TOOLS_PLANNING_DISPATCH_REVIEW,
388
391
  artifacts: {
389
392
  inline: ["slice-plan", "prior-task-summaries"],
390
393
  excerpt: [],
@@ -509,3 +512,22 @@ export const UNIT_MANIFESTS = {
509
512
  export function resolveManifest(unitType) {
510
513
  return UNIT_MANIFESTS[unitType] ?? null;
511
514
  }
515
+ export function compileSubagentPermissionContract(policy) {
516
+ if (!policy) {
517
+ return { allowed: false, allowedSubagents: [], toolsMode: "unknown" };
518
+ }
519
+ if (policy.mode === "all") {
520
+ return { allowed: true, allowedSubagents: ["*"], toolsMode: policy.mode };
521
+ }
522
+ if (policy.mode === "planning-dispatch") {
523
+ return {
524
+ allowed: true,
525
+ allowedSubagents: [...policy.allowedSubagents],
526
+ toolsMode: policy.mode,
527
+ };
528
+ }
529
+ return { allowed: false, allowedSubagents: [], toolsMode: policy.mode };
530
+ }
531
+ export function resolveSubagentPermissionContract(unitType) {
532
+ return compileSubagentPermissionContract(resolveManifest(unitType)?.tools);
533
+ }
@@ -5,6 +5,27 @@
5
5
  export function isNonEmptyString(value) {
6
6
  return typeof value === "string" && value.trim().length > 0;
7
7
  }
8
+ /**
9
+ * Characters that are used as delimiters in GSD state management documents
10
+ * and should not appear in milestone or slice titles.
11
+ */
12
+ const TITLE_DELIMITER_RE = /[\u2014\u2013\/]/; // em dash, en dash, forward slash
13
+ /**
14
+ * Check whether a milestone or slice title contains characters that conflict
15
+ * with GSD's state document delimiter conventions.
16
+ * Returns a human-readable description of the problem, or null if the title is safe.
17
+ */
18
+ export function validateTitle(title) {
19
+ if (TITLE_DELIMITER_RE.test(title)) {
20
+ const found = [];
21
+ if (/[\u2014\u2013]/.test(title))
22
+ found.push("em/en dash (\u2014 or \u2013)");
23
+ if (/\//.test(title))
24
+ found.push("forward slash (/)");
25
+ return `title contains ${found.join(" and ")}, which conflict with GSD state document delimiters`;
26
+ }
27
+ return null;
28
+ }
8
29
  /**
9
30
  * Validate that `value` is an array of non-empty strings.
10
31
  * Throws with a message referencing `field` on failure.
@@ -12,7 +33,8 @@ export function isNonEmptyString(value) {
12
33
  */
13
34
  export function validateStringArray(value, field) {
14
35
  if (!Array.isArray(value)) {
15
- throw new Error(`${field} must be an array`);
36
+ const received = value === null ? "null" : typeof value;
37
+ throw new Error(`${field} must be an array of strings, not ${received}`);
16
38
  }
17
39
  if (value.some((item) => !isNonEmptyString(item))) {
18
40
  throw new Error(`${field} must contain only non-empty strings`);