gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.2e8b124f7

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 (580) hide show
  1. package/README.md +93 -18
  2. package/dist/cli.js +20 -9
  3. package/dist/headless-ui.js +13 -6
  4. package/dist/headless.js +9 -2
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/GSD-WORKFLOW.md +10 -1
  7. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  8. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
  9. package/dist/resources/extensions/cmux/index.js +5 -0
  10. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  11. package/dist/resources/extensions/gsd/auto/loop.js +110 -37
  12. package/dist/resources/extensions/gsd/auto/orchestrator.js +13 -2
  13. package/dist/resources/extensions/gsd/auto/phases.js +104 -38
  14. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  15. package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
  16. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  17. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  18. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  19. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  20. package/dist/resources/extensions/gsd/auto-dispatch.js +71 -20
  21. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  22. package/dist/resources/extensions/gsd/auto-post-unit.js +278 -137
  23. package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
  24. package/dist/resources/extensions/gsd/auto-recovery.js +79 -14
  25. package/dist/resources/extensions/gsd/auto-start.js +90 -14
  26. package/dist/resources/extensions/gsd/auto-timers.js +11 -3
  27. package/dist/resources/extensions/gsd/auto-verification.js +102 -34
  28. package/dist/resources/extensions/gsd/auto-worktree.js +178 -11
  29. package/dist/resources/extensions/gsd/auto.js +107 -54
  30. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +5 -4
  33. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  34. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
  35. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  36. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  37. package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
  38. package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
  39. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  40. package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
  41. package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
  42. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -2
  43. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  44. package/dist/resources/extensions/gsd/crash-recovery.js +52 -7
  45. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  46. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  47. package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
  48. package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
  49. package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
  50. package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
  51. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  52. package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
  53. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  54. package/dist/resources/extensions/gsd/doctor.js +2 -28
  55. package/dist/resources/extensions/gsd/export-html.js +27 -425
  56. package/dist/resources/extensions/gsd/forensics.js +10 -3
  57. package/dist/resources/extensions/gsd/git-service.js +138 -10
  58. package/dist/resources/extensions/gsd/gsd-db.js +76 -33
  59. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  60. package/dist/resources/extensions/gsd/guided-flow.js +110 -117
  61. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  62. package/dist/resources/extensions/gsd/init-wizard.js +17 -2
  63. package/dist/resources/extensions/gsd/markdown-renderer.js +14 -11
  64. package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
  65. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  66. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  67. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  68. package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
  69. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
  70. package/dist/resources/extensions/gsd/paths.js +4 -0
  71. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  72. package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
  73. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
  74. package/dist/resources/extensions/gsd/pre-execution-checks.js +38 -11
  75. package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
  76. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  77. package/dist/resources/extensions/gsd/preferences-validation.js +138 -0
  78. package/dist/resources/extensions/gsd/preferences.js +2 -0
  79. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  80. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  83. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  84. package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
  85. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  86. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  87. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  88. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  89. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  90. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  91. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  92. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  93. package/dist/resources/extensions/gsd/repository-registry.js +44 -0
  94. package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
  95. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
  96. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +59 -2
  97. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  98. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  99. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  100. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  101. package/dist/resources/extensions/gsd/state.js +14 -4
  102. package/dist/resources/extensions/gsd/status-guards.js +14 -2
  103. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  104. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  105. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  106. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  107. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  108. package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
  109. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  110. package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
  111. package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
  112. package/dist/resources/extensions/gsd/validation.js +23 -1
  113. package/dist/resources/extensions/gsd/verification-gate.js +142 -7
  114. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  115. package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
  116. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  117. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  118. package/dist/resources/extensions/gsd/worktree-lifecycle.js +83 -19
  119. package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
  120. package/dist/resources/extensions/gsd/worktree-safety.js +33 -1
  121. package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
  122. package/dist/resources/extensions/shared/html-shell.js +388 -0
  123. package/dist/resources/extensions/shared/interview-ui.js +6 -4
  124. package/dist/resources/extensions/subagent/index.js +448 -78
  125. package/dist/resources/extensions/subagent/launch.js +77 -0
  126. package/dist/resources/extensions/subagent/run-store.js +148 -0
  127. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  128. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  129. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  130. package/dist/resources/extensions/visual-brief/index.js +5 -0
  131. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  132. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  133. package/dist/resources/skills/forensics/SKILL.md +1 -1
  134. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  135. package/dist/web/standalone/.next/BUILD_ID +1 -1
  136. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  137. package/dist/web/standalone/.next/build-manifest.json +3 -3
  138. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  139. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  140. package/dist/web/standalone/.next/required-server-files.json +1 -1
  141. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  143. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  151. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  154. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  155. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  156. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  158. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  159. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  161. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/index.html +1 -1
  164. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  165. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  167. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  169. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  170. package/dist/web/standalone/.next/server/app/page.js +2 -2
  171. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  174. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  175. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  179. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  180. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  181. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  182. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  183. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  184. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  185. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  186. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  187. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  188. package/dist/web/standalone/server.js +1 -1
  189. package/package.json +4 -4
  190. package/packages/contracts/dist/rpc.test.js +7 -0
  191. package/packages/contracts/dist/rpc.test.js.map +1 -1
  192. package/packages/contracts/dist/workflow.d.ts +21 -0
  193. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  194. package/packages/contracts/dist/workflow.js +24 -0
  195. package/packages/contracts/dist/workflow.js.map +1 -1
  196. package/packages/contracts/src/rpc.test.ts +8 -0
  197. package/packages/contracts/src/workflow.ts +24 -0
  198. package/packages/daemon/package.json +2 -2
  199. package/packages/mcp-server/README.md +13 -4
  200. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  201. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  202. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  203. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  204. package/packages/mcp-server/package.json +2 -2
  205. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  206. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  207. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  208. package/packages/native/package.json +1 -1
  209. package/packages/native/tsconfig.json +2 -1
  210. package/packages/native/tsconfig.tsbuildinfo +1 -1
  211. package/packages/pi-agent-core/package.json +1 -1
  212. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  213. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  214. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  215. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  216. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  217. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  218. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  219. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  220. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  221. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  222. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  223. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  224. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  225. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  226. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  227. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  228. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  229. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  230. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  231. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  232. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  233. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  234. package/packages/pi-ai/package.json +1 -1
  235. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  236. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  237. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  238. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  239. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  240. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  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/compaction/compaction.d.ts +6 -1
  251. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  252. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
  253. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
  255. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  257. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
  259. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  261. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  262. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
  267. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
  269. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
  271. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  275. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  277. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  278. package/packages/pi-coding-agent/package.json +1 -1
  279. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  280. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  281. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  282. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
  283. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
  284. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  285. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
  286. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  287. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
  288. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
  289. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
  290. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
  291. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  292. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  293. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  294. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  295. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  296. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  297. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  298. package/packages/pi-tui/dist/__tests__/tui.test.js +45 -2
  299. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  300. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  301. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  302. package/packages/pi-tui/dist/terminal.js +12 -0
  303. package/packages/pi-tui/dist/terminal.js.map +1 -1
  304. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  305. package/packages/pi-tui/dist/tui.js +106 -27
  306. package/packages/pi-tui/dist/tui.js.map +1 -1
  307. package/packages/pi-tui/package.json +1 -1
  308. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  309. package/packages/pi-tui/src/__tests__/tui.test.ts +59 -2
  310. package/packages/pi-tui/src/terminal.ts +11 -0
  311. package/packages/pi-tui/src/tui.ts +108 -27
  312. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  313. package/packages/rpc-client/package.json +1 -1
  314. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  315. package/pkg/package.json +1 -1
  316. package/src/resources/GSD-WORKFLOW.md +10 -1
  317. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  318. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
  319. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  320. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
  321. package/src/resources/extensions/cmux/index.ts +6 -0
  322. package/src/resources/extensions/gsd/auto/contracts.ts +17 -6
  323. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  324. package/src/resources/extensions/gsd/auto/loop.ts +111 -38
  325. package/src/resources/extensions/gsd/auto/orchestrator.ts +13 -2
  326. package/src/resources/extensions/gsd/auto/phases.ts +127 -49
  327. package/src/resources/extensions/gsd/auto/session.ts +16 -0
  328. package/src/resources/extensions/gsd/auto/types.ts +3 -0
  329. package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
  330. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  331. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  332. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  333. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  334. package/src/resources/extensions/gsd/auto-dispatch.ts +74 -20
  335. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  336. package/src/resources/extensions/gsd/auto-post-unit.ts +312 -148
  337. package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
  338. package/src/resources/extensions/gsd/auto-recovery.ts +83 -11
  339. package/src/resources/extensions/gsd/auto-start.ts +99 -12
  340. package/src/resources/extensions/gsd/auto-timers.ts +10 -3
  341. package/src/resources/extensions/gsd/auto-verification.ts +124 -42
  342. package/src/resources/extensions/gsd/auto-worktree.ts +195 -11
  343. package/src/resources/extensions/gsd/auto.ts +100 -42
  344. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
  345. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
  346. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +5 -4
  347. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  348. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
  349. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  350. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  351. package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
  352. package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
  353. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  354. package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
  355. package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
  356. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +11 -3
  357. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  358. package/src/resources/extensions/gsd/crash-recovery.ts +52 -6
  359. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  360. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  361. package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
  362. package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
  363. package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
  364. package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
  365. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  366. package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
  367. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  368. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  369. package/src/resources/extensions/gsd/doctor.ts +2 -27
  370. package/src/resources/extensions/gsd/export-html.ts +27 -427
  371. package/src/resources/extensions/gsd/forensics.ts +9 -3
  372. package/src/resources/extensions/gsd/git-service.ts +166 -11
  373. package/src/resources/extensions/gsd/gsd-db.ts +80 -31
  374. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  375. package/src/resources/extensions/gsd/guided-flow.ts +142 -134
  376. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  377. package/src/resources/extensions/gsd/init-wizard.ts +17 -2
  378. package/src/resources/extensions/gsd/journal.ts +8 -1
  379. package/src/resources/extensions/gsd/markdown-renderer.ts +14 -11
  380. package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
  381. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  382. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  383. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  384. package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
  385. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
  386. package/src/resources/extensions/gsd/paths.ts +5 -0
  387. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  388. package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
  389. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
  390. package/src/resources/extensions/gsd/pre-execution-checks.ts +49 -11
  391. package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
  392. package/src/resources/extensions/gsd/preferences-types.ts +33 -0
  393. package/src/resources/extensions/gsd/preferences-validation.ts +145 -0
  394. package/src/resources/extensions/gsd/preferences.ts +5 -0
  395. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  396. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  397. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  398. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  399. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  400. package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
  401. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  402. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  403. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  404. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  405. package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  406. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  407. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  408. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  409. package/src/resources/extensions/gsd/repository-registry.ts +77 -0
  410. package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
  411. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
  412. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +52 -1
  413. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  414. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  415. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  416. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  417. package/src/resources/extensions/gsd/state.ts +15 -4
  418. package/src/resources/extensions/gsd/status-guards.ts +16 -2
  419. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  420. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  421. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
  422. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  423. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  424. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +300 -1
  425. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +197 -11
  426. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  427. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  428. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  429. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +129 -6
  430. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
  431. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  432. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  433. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  434. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
  435. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  436. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  437. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  438. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
  439. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  440. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  441. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  442. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  443. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  444. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +104 -2
  445. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  446. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  447. package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
  448. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
  449. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +111 -1
  450. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
  451. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  452. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
  453. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
  454. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  455. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
  456. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  457. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  458. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  459. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  460. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  461. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  462. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  463. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  464. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  465. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  466. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
  467. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  468. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +199 -2
  469. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  470. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
  471. package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
  472. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
  473. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
  474. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  475. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  476. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  477. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
  478. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  479. package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
  480. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  481. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  482. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  483. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  484. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  485. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
  486. package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
  487. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  488. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
  489. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  490. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  491. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +59 -0
  492. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
  493. package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
  494. package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
  495. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +78 -0
  496. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  497. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  498. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  499. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  500. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  501. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
  502. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  503. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +21 -1
  504. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +72 -1
  505. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  506. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +86 -2
  507. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  508. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  509. package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
  510. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  511. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
  512. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  513. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
  514. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
  515. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
  516. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  517. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
  518. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +173 -1
  519. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  520. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  521. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  522. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  523. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  524. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  525. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  526. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +57 -2
  527. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
  528. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +46 -0
  529. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
  530. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
  531. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
  532. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  533. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  534. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  535. package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
  536. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  537. package/src/resources/extensions/gsd/types.ts +1 -1
  538. package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
  539. package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
  540. package/src/resources/extensions/gsd/validation.ts +23 -1
  541. package/src/resources/extensions/gsd/verification-gate.ts +170 -6
  542. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  543. package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
  544. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  545. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  546. package/src/resources/extensions/gsd/worktree-lifecycle.ts +93 -20
  547. package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
  548. package/src/resources/extensions/gsd/worktree-safety.ts +45 -6
  549. package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
  550. package/src/resources/extensions/shared/html-shell.ts +412 -0
  551. package/src/resources/extensions/shared/interview-ui.ts +6 -4
  552. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
  553. package/src/resources/extensions/subagent/index.ts +567 -103
  554. package/src/resources/extensions/subagent/launch.ts +131 -0
  555. package/src/resources/extensions/subagent/run-store.ts +218 -0
  556. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  557. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  558. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  559. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  560. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  561. package/src/resources/extensions/visual-brief/index.ts +8 -0
  562. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  563. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  564. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  565. package/src/resources/skills/forensics/SKILL.md +1 -1
  566. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  567. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  568. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  569. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  570. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  571. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  572. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  573. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  574. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  575. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  576. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  577. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  578. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  579. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → zCegwxH2e6vLp1vEZLLuZ}/_buildManifest.js +0 -0
  580. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → zCegwxH2e6vLp1vEZLLuZ}/_ssgManifest.js +0 -0
@@ -544,7 +544,7 @@ test("ADR-017 (#5703): live worker lock is not cleared", async (t) => {
544
544
 
545
545
  // ─── #5704: unregistered-milestone drift ────────────────────────────────────
546
546
 
547
- test("ADR-017 (#5704): unregistered-milestone drift detected and DB row inserted", async (t) => {
547
+ test("ADR-017 (#5704): unregistered-milestone drift fails closed without importing markdown", async (t) => {
548
548
  const base = mkdtempSync(join(tmpdir(), "gsd-adr017-projmd-"));
549
549
  const milestoneDir = join(base, ".gsd", "milestones", "M042");
550
550
  mkdirSync(milestoneDir, { recursive: true });
@@ -571,20 +571,22 @@ test("ADR-017 (#5704): unregistered-milestone drift detected and DB row inserted
571
571
  // Pre-condition: filesystem has the milestone, DB does NOT.
572
572
  assert.equal(getMilestone("M042"), null, "pre: DB has no row for M042");
573
573
 
574
- const result = await reconcileBeforeDispatch(base, {
575
- invalidateStateCache: () => {},
576
- deriveState: async () => makeState(),
577
- });
578
-
579
- assert.equal(result.ok, true);
580
- assert.ok(getMilestone("M042"), "post: DB row inserted for M042");
581
- const milestoneRepaired = result.repaired.find(
582
- (d) => d.kind === "unregistered-milestone",
574
+ await assert.rejects(
575
+ reconcileBeforeDispatch(base, {
576
+ invalidateStateCache: () => {},
577
+ deriveState: async () => makeState(),
578
+ }),
579
+ (err: unknown) => {
580
+ assert.ok(err instanceof ReconciliationFailedError);
581
+ assert.match(String(err.message), /unregistered-milestone/);
582
+ assert.equal(err.failures[0]?.drift.kind, "unregistered-milestone");
583
+ assert.match(String(err.failures[0]?.cause), /M042/);
584
+ assert.match(String(err.failures[0]?.cause), /markdown projection/);
585
+ assert.match(String(err.failures[0]?.cause), /recovery\/migration/);
586
+ return true;
587
+ },
583
588
  );
584
- assert.ok(milestoneRepaired, "repaired list should include the unregistered-milestone drift");
585
- if (milestoneRepaired?.kind === "unregistered-milestone") {
586
- assert.equal(milestoneRepaired.milestoneId, "M042");
587
- }
589
+ assert.equal(getMilestone("M042"), null, "post: DB still has no row for M042");
588
590
  });
589
591
 
590
592
  test("ADR-017 (#5704): registered milestone (DB row present) → no drift", async (t) => {
@@ -627,13 +629,14 @@ test("ADR-017 (#5704): registered milestone (DB row present) → no drift", asyn
627
629
 
628
630
  // ─── #5705: roadmap-divergence drift ─────────────────────────────────────────
629
631
 
630
- test("ADR-017 (#5705): roadmap-divergence drift detected and DB depends synced", async (t) => {
632
+ test("ADR-017 (#5705): roadmap-divergence re-renders projection without syncing depends into DB", async (t) => {
631
633
  const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-"));
632
634
  const milestoneDir = join(base, ".gsd", "milestones", "M001");
635
+ const roadmapPath = join(milestoneDir, "M001-ROADMAP.md");
633
636
  mkdirSync(milestoneDir, { recursive: true });
634
637
  // ROADMAP.md declares S02 depends on [S01]
635
638
  writeFileSync(
636
- join(milestoneDir, "M001-ROADMAP.md"),
639
+ roadmapPath,
637
640
  [
638
641
  "# M001: Test",
639
642
  "",
@@ -665,7 +668,12 @@ test("ADR-017 (#5705): roadmap-divergence drift detected and DB depends synced",
665
668
  });
666
669
 
667
670
  assert.equal(result.ok, true);
668
- assert.deepEqual(getSlice("M001", "S02")?.depends, ["S01"], "post: DB depends matches ROADMAP.md");
671
+ assert.deepEqual(getSlice("M001", "S02")?.depends, [], "post: DB depends remains authoritative");
672
+ assert.match(
673
+ readFileSync(roadmapPath, "utf-8"),
674
+ /- \[ \] \*\*S02: Feature\*\* `risk:medium` `depends:\[\]`/,
675
+ "post: ROADMAP projection is regenerated from DB depends",
676
+ );
669
677
  const roadmapRepaired = result.repaired.find((d) => d.kind === "roadmap-divergence");
670
678
  assert.ok(roadmapRepaired, "repaired list should include the roadmap-divergence drift");
671
679
  if (roadmapRepaired?.kind === "roadmap-divergence") {
@@ -673,13 +681,14 @@ test("ADR-017 (#5705): roadmap-divergence drift detected and DB depends synced",
673
681
  }
674
682
  });
675
683
 
676
- test("ADR-017 (#5705): ROADMAP declares slice missing from DB slice inserted and drift reported", async (t) => {
684
+ test("ADR-017 (#5705): ROADMAP-only slice is removed from projection and not inserted into DB", async (t) => {
677
685
  const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-newslice-"));
678
686
  const milestoneDir = join(base, ".gsd", "milestones", "M001");
687
+ const roadmapPath = join(milestoneDir, "M001-ROADMAP.md");
679
688
  mkdirSync(milestoneDir, { recursive: true });
680
689
  // ROADMAP.md declares S01 and S02; DB will only have S01.
681
690
  writeFileSync(
682
- join(milestoneDir, "M001-ROADMAP.md"),
691
+ roadmapPath,
683
692
  [
684
693
  "# M001: Test",
685
694
  "",
@@ -710,10 +719,10 @@ test("ADR-017 (#5705): ROADMAP declares slice missing from DB → slice inserted
710
719
  });
711
720
 
712
721
  assert.equal(result.ok, true);
713
- const s02 = getSlice("M001", "S02");
714
- assert.ok(s02, "post: S02 inserted into DB after repair");
715
- assert.equal(s02?.sequence, 2, "post: S02 sequence matches ROADMAP order");
716
- assert.deepEqual(s02?.depends, ["S01"], "post: S02 depends matches ROADMAP");
722
+ assert.equal(getSlice("M001", "S02"), null, "post: S02 still has no DB row");
723
+ const rendered = readFileSync(roadmapPath, "utf-8");
724
+ assert.match(rendered, /- \[ \] \*\*S01: Foundation\*\*/);
725
+ assert.doesNotMatch(rendered, /S02: Feature/, "post: ROADMAP-only S02 removed from projection");
717
726
  const roadmapRepaired = result.repaired.find((d) => d.kind === "roadmap-divergence");
718
727
  assert.ok(roadmapRepaired, "repaired list should include the roadmap-divergence drift");
719
728
  if (roadmapRepaired?.kind === "roadmap-divergence") {
@@ -721,6 +730,93 @@ test("ADR-017 (#5705): ROADMAP declares slice missing from DB → slice inserted
721
730
  }
722
731
  });
723
732
 
733
+ test("ADR-017 (#5705): ROADMAP sequence drift re-renders from DB order without mutating DB", async (t) => {
734
+ const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-sequence-"));
735
+ const milestoneDir = join(base, ".gsd", "milestones", "M001");
736
+ const roadmapPath = join(milestoneDir, "M001-ROADMAP.md");
737
+ mkdirSync(milestoneDir, { recursive: true });
738
+ writeFileSync(
739
+ roadmapPath,
740
+ [
741
+ "# M001: Test",
742
+ "",
743
+ "**Vision:** Verify sequence drift",
744
+ "",
745
+ "## Slices",
746
+ "",
747
+ "- [ ] **S02: Feature** `risk:medium` `depends:[]`",
748
+ "- [ ] **S01: Foundation** `risk:medium` `depends:[]`",
749
+ "",
750
+ ].join("\n"),
751
+ );
752
+ t.after(() => {
753
+ try { closeDatabase(); } catch { /* noop */ }
754
+ rmSync(base, { recursive: true, force: true });
755
+ });
756
+
757
+ openDatabase(join(base, ".gsd", "gsd.db"));
758
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
759
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
760
+ insertSlice({ id: "S02", milestoneId: "M001", title: "Feature", status: "pending", risk: "medium", depends: [], demo: "", sequence: 2 });
761
+
762
+ const result = await reconcileBeforeDispatch(base, {
763
+ invalidateStateCache: () => {},
764
+ deriveState: async () => makeState(),
765
+ });
766
+
767
+ assert.equal(result.ok, true);
768
+ assert.equal(getSlice("M001", "S01")?.sequence, 1, "post: S01 DB sequence remains authoritative");
769
+ assert.equal(getSlice("M001", "S02")?.sequence, 2, "post: S02 DB sequence remains authoritative");
770
+ const rendered = readFileSync(roadmapPath, "utf-8");
771
+ assert.ok(
772
+ rendered.indexOf("S01: Foundation") < rendered.indexOf("S02: Feature"),
773
+ "post: ROADMAP projection follows DB sequence",
774
+ );
775
+ assert.ok(result.repaired.some((d) => d.kind === "roadmap-divergence"));
776
+ });
777
+
778
+ test("ADR-017 (#5705): ROADMAP checkbox drift re-renders from DB status without mutating DB", async (t) => {
779
+ const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-checkbox-"));
780
+ const milestoneDir = join(base, ".gsd", "milestones", "M001");
781
+ const roadmapPath = join(milestoneDir, "M001-ROADMAP.md");
782
+ mkdirSync(milestoneDir, { recursive: true });
783
+ writeFileSync(
784
+ roadmapPath,
785
+ [
786
+ "# M001: Test",
787
+ "",
788
+ "**Vision:** Verify checkbox drift",
789
+ "",
790
+ "## Slices",
791
+ "",
792
+ "- [x] **S01: Foundation** `risk:medium` `depends:[]`",
793
+ "",
794
+ ].join("\n"),
795
+ );
796
+ t.after(() => {
797
+ try { closeDatabase(); } catch { /* noop */ }
798
+ rmSync(base, { recursive: true, force: true });
799
+ });
800
+
801
+ openDatabase(join(base, ".gsd", "gsd.db"));
802
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
803
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
804
+
805
+ const result = await reconcileBeforeDispatch(base, {
806
+ invalidateStateCache: () => {},
807
+ deriveState: async () => makeState(),
808
+ });
809
+
810
+ assert.equal(result.ok, true);
811
+ assert.equal(getSlice("M001", "S01")?.status, "pending", "post: DB status remains authoritative");
812
+ assert.match(
813
+ readFileSync(roadmapPath, "utf-8"),
814
+ /- \[ \] \*\*S01: Foundation\*\*/,
815
+ "post: ROADMAP checkbox reflects DB status",
816
+ );
817
+ assert.ok(result.repaired.some((d) => d.kind === "roadmap-divergence"));
818
+ });
819
+
724
820
  test("ADR-017 (#5705): in-sync ROADMAP and DB → no roadmap-divergence drift", async (t) => {
725
821
  const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-clean-"));
726
822
  const milestoneDir = join(base, ".gsd", "milestones", "M001");
@@ -3,7 +3,7 @@
3
3
  import test from 'node:test';
4
4
  import assert from 'node:assert/strict';
5
5
 
6
- import { isClosedStatus } from '../status-guards.ts';
6
+ import { isClosedStatus, isFutureMilestoneStatus } from '../status-guards.ts';
7
7
 
8
8
  test('isClosedStatus: "complete" returns true', () => {
9
9
  assert.equal(isClosedStatus('complete'), true);
@@ -17,6 +17,10 @@ test('isClosedStatus: "skipped" returns true', () => {
17
17
  assert.equal(isClosedStatus('skipped'), true);
18
18
  });
19
19
 
20
+ test('isClosedStatus: "closed" returns true', () => {
21
+ assert.equal(isClosedStatus('closed'), true);
22
+ });
23
+
20
24
  test('isClosedStatus: "pending" returns false', () => {
21
25
  assert.equal(isClosedStatus('pending'), false);
22
26
  });
@@ -32,3 +36,15 @@ test('isClosedStatus: "active" returns false', () => {
32
36
  test('isClosedStatus: "" (empty string) returns false', () => {
33
37
  assert.equal(isClosedStatus(''), false);
34
38
  });
39
+
40
+ test('isFutureMilestoneStatus includes future milestone aliases', () => {
41
+ assert.equal(isFutureMilestoneStatus('pending'), true);
42
+ assert.equal(isFutureMilestoneStatus('queued'), true);
43
+ assert.equal(isFutureMilestoneStatus('planned'), true);
44
+ });
45
+
46
+ test('isFutureMilestoneStatus excludes active and closed milestones', () => {
47
+ assert.equal(isFutureMilestoneStatus('active'), false);
48
+ assert.equal(isFutureMilestoneStatus('complete'), false);
49
+ assert.equal(isFutureMilestoneStatus('parked'), false);
50
+ });
@@ -19,13 +19,17 @@ import {
19
19
  closeDatabase,
20
20
  insertMilestone,
21
21
  } from "../gsd-db.ts";
22
- import { registerAutoWorker } from "../db/auto-workers.ts";
22
+ import { registerAutoWorker, markWorkerCrashed } from "../db/auto-workers.ts";
23
23
  import { claimMilestoneLease } from "../db/milestone-leases.ts";
24
24
  import {
25
25
  recordDispatchClaim,
26
+ markFailed,
27
+ markCanceled,
26
28
  getRecentUnitKeysForWorker,
29
+ getRecentUnitKeysForProjectRoot,
27
30
  } from "../db/unit-dispatches.ts";
28
31
  import { setRuntimeKv, getRuntimeKv } from "../db/runtime-kv.ts";
32
+ import { detectStuck } from "../auto/detect-stuck.ts";
29
33
 
30
34
  function makeBase(): string {
31
35
  const base = mkdtempSync(join(tmpdir(), "gsd-stuck-state-db-"));
@@ -67,6 +71,65 @@ test("getRecentUnitKeysForWorker reconstructs the recentUnits sliding window", (
67
71
  assert.deepEqual(window.map(w => w.key), ["U1", "U2", "U3"]);
68
72
  });
69
73
 
74
+ test("getRecentUnitKeysForProjectRoot restores compound keys used by stuck detection", (t) => {
75
+ const base = makeBase();
76
+ t.after(() => cleanup(base));
77
+ openDatabase(join(base, ".gsd", "gsd.db"));
78
+ insertMilestone({ id: "M001", title: "T", status: "active" });
79
+ insertMilestone({ id: "M002", title: "Crashed", status: "active" });
80
+ const worker = registerAutoWorker({ projectRootRealpath: base });
81
+ const lease = claimMilestoneLease(worker, "M001");
82
+ assert.equal(lease.ok, true);
83
+ if (!lease.ok) return;
84
+
85
+ for (let i = 0; i < 2; i++) {
86
+ const claim = recordDispatchClaim({
87
+ traceId: `t${i}`,
88
+ workerId: worker,
89
+ milestoneLeaseToken: lease.token,
90
+ milestoneId: "M001",
91
+ sliceId: "S01",
92
+ unitType: "complete-slice",
93
+ unitId: "M001/S01",
94
+ });
95
+ assert.equal(claim.ok, true);
96
+ if (!claim.ok) return;
97
+ markCanceled(claim.dispatchId, "pause");
98
+ }
99
+
100
+ const crashedWorker = registerAutoWorker({ projectRootRealpath: base });
101
+ const crashedLease = claimMilestoneLease(crashedWorker, "M002");
102
+ assert.equal(crashedLease.ok, true);
103
+ if (!crashedLease.ok) return;
104
+
105
+ for (let i = 0; i < 3; i++) {
106
+ const claim = recordDispatchClaim({
107
+ traceId: `crashed-${i}`,
108
+ workerId: crashedWorker,
109
+ milestoneLeaseToken: crashedLease.token,
110
+ milestoneId: "M002",
111
+ sliceId: "S01",
112
+ taskId: "T01",
113
+ unitType: "execute-task",
114
+ unitId: "M002/S01/T01",
115
+ });
116
+ assert.equal(claim.ok, true);
117
+ if (!claim.ok) return;
118
+ markFailed(claim.dispatchId, { errorSummary: "worker crashed" });
119
+ }
120
+ markWorkerCrashed(crashedWorker);
121
+
122
+ const window = getRecentUnitKeysForProjectRoot(base, 3);
123
+ assert.deepEqual(window.map(w => w.key), [
124
+ "complete-slice/M001/S01",
125
+ "complete-slice/M001/S01",
126
+ ]);
127
+
128
+ const result = detectStuck([...window, { key: "complete-slice/M001/S01" }]);
129
+ assert.equal(result?.stuck, true);
130
+ assert.match(result?.reason ?? "", /3 consecutive times/);
131
+ });
132
+
70
133
  test("getRecentUnitKeysForWorker honors the limit parameter", (t) => {
71
134
  const base = makeBase();
72
135
  t.after(() => cleanup(base));
@@ -91,8 +91,9 @@ test("buildReactiveExecutePrompt injects subagent model when provided", async (t
91
91
  );
92
92
 
93
93
  assert.match(prompt, /model: "claude-opus-4-6"/);
94
- assert.match(prompt, /Context Mode \(execution lane\):/);
94
+ assert.match(prompt, /Lane: \*\*execution lane\*\*\./);
95
95
  assert.match(prompt, /## Context Mode/);
96
+ assert.doesNotMatch(prompt, /You are executing GSD auto-mode\./);
96
97
  });
97
98
 
98
99
  test("buildReactiveExecutePrompt omits model instruction when subagentModel is omitted", async (t) => {
@@ -175,13 +175,17 @@ const verificationEvidence = [
175
175
  );
176
176
  }
177
177
 
178
- // Test 11: empty key_files renders YAML placeholder, not empty array
178
+ // Test 11: empty key_files renders an empty YAML list, not a sentinel path
179
179
  {
180
180
  const noFiles = { ...taskRow, key_files: [] };
181
181
  const output = renderSummaryContent(noFiles, SLICE_ID, MILESTONE_ID);
182
182
  assertTrue(
183
- output.includes("key_files:\n - (none)"),
184
- "empty key_files must render as YAML list with (none) placeholder",
183
+ output.includes("key_files: []"),
184
+ "empty key_files must render as an empty YAML list",
185
+ );
186
+ assertTrue(
187
+ !output.includes("key_files:\n - (none)"),
188
+ "empty key_files must not render (none) as a path-like list item",
185
189
  );
186
190
  }
187
191
 
@@ -153,6 +153,7 @@ const laneLabelByMode: Record<string, string> = {
153
153
  verification: "verification",
154
154
  orchestration: "orchestration",
155
155
  docs: "documentation",
156
+ triage: "triage",
156
157
  };
157
158
 
158
159
  test("Context Mode composer: every known eligible unit renders its configured lane and required tools", () => {
@@ -7,13 +7,17 @@ import {
7
7
  ARTIFACT_KEYS,
8
8
  KNOWN_UNIT_TYPES,
9
9
  UNIT_MANIFESTS,
10
+ resolveSubagentPermissionContract,
10
11
  resolveManifest,
11
12
  type ArtifactKey,
12
13
  type ContextModePolicy,
13
14
  type SkillsPolicy,
14
15
  type UnitContextManifest,
15
16
  } from "../unit-context-manifest.ts";
16
- import { ALLOWED_PLANNING_DISPATCH_AGENTS } from "../bootstrap/write-gate.ts";
17
+ import {
18
+ ALLOWED_PLANNING_DISPATCH_AGENTS,
19
+ shouldBlockPlanningUnit,
20
+ } from "../bootstrap/write-gate.ts";
17
21
  import {
18
22
  getRequiredWorkflowToolsForAutoUnit,
19
23
  getRequiredWorkflowToolsForGuidedUnit,
@@ -106,8 +110,10 @@ test("Context Mode: every manifest declares the expected contextMode lane", () =
106
110
  "reassess-roadmap": "planning",
107
111
  "execute-task": "execution",
108
112
  "reactive-execute": "execution",
113
+ "quick-task": "execution",
109
114
  "run-uat": "verification",
110
115
  "gate-evaluate": "verification",
116
+ "triage-captures": "triage",
111
117
  "validate-milestone": "verification",
112
118
  "complete-slice": "verification",
113
119
  "complete-milestone": "verification",
@@ -216,7 +222,7 @@ test("#4934: every manifest declares a tools policy", () => {
216
222
  });
217
223
 
218
224
  test("#4934: tools.mode is one of the declared policies", () => {
219
- const validModes = new Set(["all", "read-only", "planning", "planning-dispatch", "docs"]);
225
+ const validModes = new Set(["all", "read-only", "planning", "planning-dispatch", "docs", "verification"]);
220
226
  for (const [unitType, manifest] of Object.entries(UNIT_MANIFESTS)) {
221
227
  const mode = (manifest as { tools: { mode: string } }).tools.mode;
222
228
  assert.ok(
@@ -226,32 +232,130 @@ test("#4934: tools.mode is one of the declared policies", () => {
226
232
  }
227
233
  });
228
234
 
229
- test('#4934: only execute-task and reactive-execute may use tools.mode "all" (full source-tree write access)', () => {
230
- const allowedAllUnits = new Set(["execute-task", "reactive-execute"]);
235
+ test('#4934: only execution units, quick-task, and closeout units may use tools.mode "all"', () => {
236
+ const allowedAllUnits = new Set([
237
+ "execute-task",
238
+ "reactive-execute",
239
+ "quick-task",
240
+ "validate-milestone",
241
+ "complete-milestone",
242
+ "complete-slice",
243
+ ]);
231
244
  for (const [unitType, manifest] of Object.entries(UNIT_MANIFESTS)) {
232
245
  const mode = (manifest as { tools: { mode: string } }).tools.mode;
233
246
  if (mode === "all") {
234
247
  assert.ok(
235
248
  allowedAllUnits.has(unitType),
236
- `manifest "${unitType}" declares tools.mode = "all" but is not on the execute-track. ` +
237
- 'Only execute-task and reactive-execute should have full source write access; ' +
249
+ `manifest "${unitType}" declares tools.mode = "all" but is not explicitly allowed. ` +
250
+ 'Only execute-task/reactive-execute, quick-task, and closeout units should have full source write access; ' +
238
251
  'planning/discuss/research units must use "planning" or "planning-dispatch" (or "docs" for rewrite-docs).',
239
252
  );
240
253
  }
241
254
  }
242
255
  });
243
256
 
257
+ test("#5453: complete-milestone uses all tools so bash verification is not planning-dispatch blocked", () => {
258
+ const manifest = UNIT_MANIFESTS["complete-milestone"];
259
+
260
+ assert.strictEqual(manifest.tools.mode, "all");
261
+ assert.deepEqual(resolveSubagentPermissionContract("complete-milestone"), {
262
+ allowed: true,
263
+ allowedSubagents: ["*"],
264
+ toolsMode: "all",
265
+ });
266
+ // Runtime gate-level regression: these verification commands were blocked
267
+ // under planning-dispatch in #5453; complete-milestone must bypass that gate.
268
+ for (const cmd of ["git diff --name-only HEAD~1", "git log -n1 --oneline"]) {
269
+ const result = shouldBlockPlanningUnit(
270
+ "bash",
271
+ cmd,
272
+ process.cwd(),
273
+ "complete-milestone",
274
+ manifest.tools,
275
+ );
276
+ assert.strictEqual(
277
+ result.block,
278
+ false,
279
+ `shouldBlockPlanningUnit must not block ${cmd} for complete-milestone: ${result.reason}`,
280
+ );
281
+ }
282
+ });
283
+
284
+ test("#5731: validate-milestone and complete-slice use all tools so closeout verification is not planning-dispatch blocked", () => {
285
+ for (const unitType of ["validate-milestone", "complete-slice"] as const) {
286
+ const manifest = UNIT_MANIFESTS[unitType];
287
+ assert.strictEqual(manifest.tools.mode, "all");
288
+ const result = shouldBlockPlanningUnit(
289
+ "bash",
290
+ "go test -short -count=1 ./...",
291
+ process.cwd(),
292
+ unitType,
293
+ manifest.tools,
294
+ );
295
+ assert.strictEqual(
296
+ result.block,
297
+ false,
298
+ `${unitType} must allow verification bash commands: ${result.reason}`,
299
+ );
300
+ }
301
+ });
302
+
303
+ test("#5843: run-uat uses verification tools policy so build/test commands can run", () => {
304
+ const manifest = UNIT_MANIFESTS["run-uat"];
305
+
306
+ assert.strictEqual(manifest.tools.mode, "verification");
307
+
308
+ const buildResult = shouldBlockPlanningUnit(
309
+ "bash",
310
+ "npm run build 2>&1",
311
+ process.cwd(),
312
+ "run-uat",
313
+ manifest.tools,
314
+ );
315
+ assert.strictEqual(
316
+ buildResult.block,
317
+ false,
318
+ `run-uat must allow build verification commands: ${buildResult.reason}`,
319
+ );
320
+
321
+ const sourceWriteResult = shouldBlockPlanningUnit(
322
+ "edit",
323
+ "src/main.ts",
324
+ process.cwd(),
325
+ "run-uat",
326
+ manifest.tools,
327
+ );
328
+ assert.strictEqual(sourceWriteResult.block, true);
329
+ assert.match(sourceWriteResult.reason!, /tools-policy "verification"/);
330
+ });
331
+
332
+ test("planning-dispatch hard block message omits internal tracker references", () => {
333
+ const manifest = UNIT_MANIFESTS["plan-slice"];
334
+ assert.strictEqual(manifest.tools.mode, "planning-dispatch");
335
+
336
+ const result = shouldBlockPlanningUnit(
337
+ "task",
338
+ "scout",
339
+ process.cwd(),
340
+ "plan-slice",
341
+ manifest.tools,
342
+ );
343
+
344
+ assert.strictEqual(result.block, true);
345
+ assert.ok(result.reason, "blocked dispatch should include a user-facing reason");
346
+ assert.doesNotMatch(result.reason!, /#[0-9]{3,}/);
347
+ });
348
+
244
349
  test('planning-dispatch mode is reserved for slice-level decomposition and completion units', () => {
245
350
  const allowedDispatchUnits = new Set([
246
351
  "plan-slice",
352
+ "research-slice",
247
353
  "refine-slice",
248
- "complete-slice",
249
- "complete-milestone",
354
+ "gate-evaluate",
250
355
  // Deep planning mode: research-project orchestrates 4 parallel research
251
356
  // subagents (stack/features/architecture/pitfalls). Subagent dispatch is
252
357
  // the unit's core mechanism — without it, the unit cannot do its job.
253
358
  "research-project",
254
- "validate-milestone",
255
359
  ]);
256
360
  for (const [unitType, manifest] of Object.entries(UNIT_MANIFESTS)) {
257
361
  const mode = (manifest as { tools: { mode: string } }).tools.mode;
@@ -265,6 +369,24 @@ test('planning-dispatch mode is reserved for slice-level decomposition and compl
265
369
  }
266
370
  });
267
371
 
372
+ test('Unit Tool Contract exposes subagent dispatch permissions', () => {
373
+ assert.deepEqual(resolveSubagentPermissionContract("plan-slice"), {
374
+ allowed: true,
375
+ allowedSubagents: ["scout", "planner"],
376
+ toolsMode: "planning-dispatch",
377
+ });
378
+ assert.deepEqual(resolveSubagentPermissionContract("gate-evaluate"), {
379
+ allowed: true,
380
+ allowedSubagents: ["reviewer", "security", "tester"],
381
+ toolsMode: "planning-dispatch",
382
+ });
383
+ assert.deepEqual(resolveSubagentPermissionContract("discuss-milestone"), {
384
+ allowed: false,
385
+ allowedSubagents: [],
386
+ toolsMode: "planning",
387
+ });
388
+ });
389
+
268
390
  test('planning-dispatch manifests declare non-empty allowedSubagents lists', () => {
269
391
  for (const [unitType, manifest] of Object.entries(UNIT_MANIFESTS)) {
270
392
  if (manifest.tools.mode !== "planning-dispatch") continue;