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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (452) hide show
  1. package/dist/cli.js +3 -2
  2. package/dist/help-text.js +10 -6
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +495 -0
  5. package/dist/resources/extensions/browser-tools/engine/selection.js +16 -0
  6. package/dist/resources/extensions/browser-tools/extension-manifest.json +2 -2
  7. package/dist/resources/extensions/browser-tools/index.js +57 -9
  8. package/dist/resources/extensions/browser-tools/package.json +5 -1
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +167 -16
  10. package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
  11. package/dist/resources/extensions/gsd/auto/phases.js +4 -3
  12. package/dist/resources/extensions/gsd/auto-dashboard.js +92 -17
  13. package/dist/resources/extensions/gsd/auto-dispatch.js +55 -0
  14. package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
  15. package/dist/resources/extensions/gsd/auto-prompts.js +72 -22
  16. package/dist/resources/extensions/gsd/auto-recovery.js +7 -8
  17. package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
  18. package/dist/resources/extensions/gsd/auto-start.js +94 -15
  19. package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
  20. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +18 -65
  21. package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
  22. package/dist/resources/extensions/gsd/auto.js +31 -6
  23. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -4
  24. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +56 -20
  26. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +33 -38
  27. package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
  28. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
  29. package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
  30. package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -2
  31. package/dist/resources/extensions/gsd/commands/handlers/ops.js +9 -5
  32. package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
  33. package/dist/resources/extensions/gsd/commands-maintenance.js +172 -2
  34. package/dist/resources/extensions/gsd/commands-mcp-status.js +109 -60
  35. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
  36. package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
  37. package/dist/resources/extensions/gsd/config-overlay.js +2 -1
  38. package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  40. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
  41. package/dist/resources/extensions/gsd/error-classifier.js +2 -1
  42. package/dist/resources/extensions/gsd/escalation.js +4 -4
  43. package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
  44. package/dist/resources/extensions/gsd/forensics.js +74 -2
  45. package/dist/resources/extensions/gsd/gsd-db.js +42 -6
  46. package/dist/resources/extensions/gsd/guided-flow.js +119 -176
  47. package/dist/resources/extensions/gsd/mcp-filter.js +3 -0
  48. package/dist/resources/extensions/gsd/mcp-project-config.js +76 -84
  49. package/dist/resources/extensions/gsd/memory-store.js +4 -1
  50. package/dist/resources/extensions/gsd/migration-auto-check.js +2 -2
  51. package/dist/resources/extensions/gsd/milestone-closeout.js +3 -1
  52. package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
  53. package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
  54. package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
  55. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  56. package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
  57. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  58. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  59. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  60. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  61. package/dist/resources/extensions/gsd/prompts/run-uat.md +33 -23
  62. package/dist/resources/extensions/gsd/prompts/system.md +3 -1
  63. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  64. package/dist/resources/extensions/gsd/recovery-classification.js +20 -0
  65. package/dist/resources/extensions/gsd/rule-registry.js +428 -52
  66. package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
  67. package/dist/resources/extensions/gsd/skill-activation.js +20 -3
  68. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +4 -2
  69. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +1 -1
  70. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
  71. package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
  72. package/dist/resources/extensions/gsd/state.js +17 -14
  73. package/dist/resources/extensions/gsd/templates/plan.md +3 -1
  74. package/dist/resources/extensions/gsd/tool-contract.js +5 -0
  75. package/dist/resources/extensions/gsd/tool-presentation-plan.js +143 -0
  76. package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
  77. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
  78. package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
  79. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -9
  80. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  81. package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
  82. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +483 -6
  83. package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
  84. package/dist/resources/extensions/gsd/unit-tool-contracts.js +169 -0
  85. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  86. package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
  87. package/dist/resources/extensions/gsd/verification-gate.js +72 -1
  88. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -1
  89. package/dist/resources/extensions/gsd/workflow-mcp.js +5 -73
  90. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -0
  91. package/dist/resources/extensions/mcp-client/manager.js +31 -1
  92. package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
  93. package/dist/rtk.d.ts +7 -1
  94. package/dist/rtk.js +27 -11
  95. package/dist/update-check.d.ts +15 -1
  96. package/dist/update-check.js +87 -12
  97. package/dist/update-cmd.d.ts +1 -0
  98. package/dist/update-cmd.js +53 -2
  99. package/dist/web/standalone/.next/BUILD_ID +1 -1
  100. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  101. package/dist/web/standalone/.next/build-manifest.json +2 -2
  102. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  103. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  112. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/index.html +1 -1
  121. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  128. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  129. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  131. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  132. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  133. package/package.json +5 -3
  134. package/packages/cloud-mcp-gateway/package.json +2 -2
  135. package/packages/contracts/dist/workflow.d.ts +14 -0
  136. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  137. package/packages/contracts/dist/workflow.js +16 -0
  138. package/packages/contracts/dist/workflow.js.map +1 -1
  139. package/packages/contracts/package.json +1 -1
  140. package/packages/daemon/package.json +4 -4
  141. package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
  142. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  143. package/packages/gsd-agent-core/dist/agent-session.js +32 -0
  144. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  145. package/packages/gsd-agent-core/dist/index.d.ts +1 -0
  146. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  147. package/packages/gsd-agent-core/dist/index.js +1 -0
  148. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  149. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
  150. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
  151. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
  152. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
  153. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
  154. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  155. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  156. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  157. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
  158. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  159. package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
  160. package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
  161. package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
  162. package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
  163. package/packages/gsd-agent-core/package.json +6 -6
  164. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
  165. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
  166. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
  167. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
  168. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  169. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  170. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  171. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  172. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  173. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  174. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  175. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
  176. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  177. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +92 -31
  178. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  179. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  180. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
  181. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  182. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.d.ts.map +1 -1
  186. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -0
  187. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  188. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  190. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  192. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
  194. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  196. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
  197. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  198. package/packages/gsd-agent-modes/package.json +7 -7
  199. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
  200. package/packages/mcp-server/dist/remote-questions.js +23 -9
  201. package/packages/mcp-server/dist/remote-questions.js.map +1 -1
  202. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  203. package/packages/mcp-server/dist/workflow-tools.js +84 -2
  204. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  205. package/packages/mcp-server/package.json +3 -3
  206. package/packages/native/package.json +1 -1
  207. package/packages/pi-agent-core/dist/agent-loop.js +42 -3
  208. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  209. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  210. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  211. package/packages/pi-agent-core/dist/agent.js +2 -0
  212. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  213. package/packages/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  214. package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
  215. package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  216. package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
  217. package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  218. package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
  219. package/packages/pi-agent-core/dist/types.d.ts +6 -1
  220. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  221. package/packages/pi-agent-core/dist/types.js.map +1 -1
  222. package/packages/pi-agent-core/package.json +1 -1
  223. package/packages/pi-ai/dist/api-registry.d.ts +2 -0
  224. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  225. package/packages/pi-ai/dist/api-registry.js +23 -0
  226. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  227. package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
  228. package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  229. package/packages/pi-ai/dist/image-models.generated.js +15 -0
  230. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  231. package/packages/pi-ai/dist/models.generated.d.ts +411 -39
  232. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  233. package/packages/pi-ai/dist/models.generated.js +504 -153
  234. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  235. package/packages/pi-ai/dist/stream.js +6 -6
  236. package/packages/pi-ai/dist/stream.js.map +1 -1
  237. package/packages/pi-ai/package.json +1 -1
  238. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +3 -0
  239. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  240. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  243. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  245. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  246. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  247. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/tools/bash.js +2 -2
  249. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
  252. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
  254. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
  256. package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
  259. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  260. package/packages/pi-coding-agent/package.json +7 -7
  261. package/packages/pi-tui/dist/terminal.d.ts +1 -0
  262. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  263. package/packages/pi-tui/dist/terminal.js +8 -4
  264. package/packages/pi-tui/dist/terminal.js.map +1 -1
  265. package/packages/pi-tui/package.json +1 -1
  266. package/packages/rpc-client/package.json +2 -2
  267. package/pkg/package.json +1 -1
  268. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
  269. package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
  270. package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
  271. package/src/resources/extensions/browser-tools/index.ts +60 -9
  272. package/src/resources/extensions/browser-tools/package.json +5 -1
  273. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
  274. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
  275. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +196 -16
  276. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +239 -63
  277. package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
  278. package/src/resources/extensions/gsd/auto/phases.ts +5 -3
  279. package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
  280. package/src/resources/extensions/gsd/auto-dispatch.ts +67 -0
  281. package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
  282. package/src/resources/extensions/gsd/auto-prompts.ts +106 -15
  283. package/src/resources/extensions/gsd/auto-recovery.ts +7 -7
  284. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
  285. package/src/resources/extensions/gsd/auto-start.ts +112 -17
  286. package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
  287. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +43 -73
  288. package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
  289. package/src/resources/extensions/gsd/auto.ts +47 -5
  290. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +96 -4
  291. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
  292. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +81 -25
  293. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +70 -63
  294. package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
  295. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
  296. package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
  297. package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -2
  298. package/src/resources/extensions/gsd/commands/handlers/ops.ts +9 -5
  299. package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
  300. package/src/resources/extensions/gsd/commands-maintenance.ts +197 -2
  301. package/src/resources/extensions/gsd/commands-mcp-status.ts +136 -58
  302. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
  303. package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
  304. package/src/resources/extensions/gsd/config-overlay.ts +3 -1
  305. package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
  306. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  307. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
  308. package/src/resources/extensions/gsd/error-classifier.ts +2 -1
  309. package/src/resources/extensions/gsd/escalation.ts +4 -4
  310. package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
  311. package/src/resources/extensions/gsd/forensics.ts +99 -5
  312. package/src/resources/extensions/gsd/gsd-db.ts +46 -8
  313. package/src/resources/extensions/gsd/guided-flow.ts +215 -217
  314. package/src/resources/extensions/gsd/mcp-filter.ts +3 -0
  315. package/src/resources/extensions/gsd/mcp-project-config.ts +105 -88
  316. package/src/resources/extensions/gsd/memory-store.ts +4 -1
  317. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  318. package/src/resources/extensions/gsd/milestone-closeout.ts +3 -1
  319. package/src/resources/extensions/gsd/pending-auto-start.ts +0 -2
  320. package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
  321. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  322. package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
  323. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  324. package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
  325. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  326. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  327. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  328. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  329. package/src/resources/extensions/gsd/prompts/run-uat.md +33 -23
  330. package/src/resources/extensions/gsd/prompts/system.md +3 -1
  331. package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  332. package/src/resources/extensions/gsd/recovery-classification.ts +20 -0
  333. package/src/resources/extensions/gsd/rule-registry.ts +558 -58
  334. package/src/resources/extensions/gsd/rule-types.ts +2 -0
  335. package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
  336. package/src/resources/extensions/gsd/skill-activation.ts +20 -2
  337. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +4 -2
  338. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +1 -1
  339. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
  340. package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
  341. package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
  342. package/src/resources/extensions/gsd/state.ts +18 -14
  343. package/src/resources/extensions/gsd/templates/plan.md +3 -1
  344. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
  345. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +123 -0
  346. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +10 -2
  347. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
  348. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +143 -2
  349. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +24 -2
  350. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +12 -2
  351. package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
  352. package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
  353. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
  354. package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -0
  355. package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
  356. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
  357. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
  358. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  359. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
  360. package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
  361. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
  362. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +50 -13
  363. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
  364. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +40 -1
  365. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +60 -0
  366. package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
  367. package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
  368. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
  369. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
  370. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
  371. package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
  372. package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
  373. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +31 -79
  374. package/src/resources/extensions/gsd/tests/gsd-rebuild.test.ts +199 -0
  375. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +75 -0
  376. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
  377. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
  378. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +5 -3
  379. package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
  380. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
  381. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
  382. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +8 -0
  383. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
  384. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +72 -10
  385. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +13 -6
  386. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +15 -0
  387. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +100 -0
  388. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +179 -0
  389. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
  390. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +63 -0
  391. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
  392. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
  393. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
  394. package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
  395. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
  396. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
  397. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +39 -1
  398. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
  399. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
  400. package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
  401. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +83 -1
  402. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
  403. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
  404. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
  405. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
  406. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +79 -0
  407. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
  408. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
  409. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +4 -0
  410. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +36 -0
  411. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
  412. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
  413. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +6 -2
  414. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  415. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
  416. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  417. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
  418. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
  419. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
  420. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
  421. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
  422. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
  423. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
  424. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
  425. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +17 -2
  426. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +493 -0
  427. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +40 -0
  428. package/src/resources/extensions/gsd/tool-contract.ts +6 -0
  429. package/src/resources/extensions/gsd/tool-presentation-plan.ts +223 -0
  430. package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
  431. package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
  432. package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
  433. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -9
  434. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  435. package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
  436. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +589 -8
  437. package/src/resources/extensions/gsd/types.ts +69 -5
  438. package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
  439. package/src/resources/extensions/gsd/unit-tool-contracts.ts +186 -0
  440. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  441. package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
  442. package/src/resources/extensions/gsd/verification-gate.ts +87 -1
  443. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -1
  444. package/src/resources/extensions/gsd/workflow-mcp.ts +5 -73
  445. package/src/resources/extensions/gsd/worktree-lifecycle.ts +26 -0
  446. package/src/resources/extensions/mcp-client/manager.ts +33 -1
  447. package/src/resources/extensions/mcp-client/tests/manager.test.ts +35 -0
  448. package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
  449. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
  450. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
  451. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_buildManifest.js +0 -0
  452. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_ssgManifest.js +0 -0
@@ -123,6 +123,10 @@ test("#4782 phase 3: buildRunUatPrompt inlines UAT and keeps summary/project con
123
123
  // Project path is advertised on-demand; full project body is not inlined.
124
124
  assert.match(prompt, /\.gsd\/PROJECT\.md/);
125
125
  assert.ok(!prompt.includes("Run-UAT composer fixture project"), "run-uat should not inline full project context");
126
+
127
+ assert.match(prompt, /"toolPresentationPlanId": "run-uat\/default-v1"/);
128
+ assert.match(prompt, /"gsd_uat_result_save"/);
129
+ assert.match(prompt, /"read"/);
126
130
  });
127
131
 
128
132
  test("#4782 phase 3: buildRunUatPrompt omits optional slice summary when file is missing", async (t) => {
@@ -7,6 +7,7 @@ import assert from "node:assert/strict";
7
7
  import { classifyFailure } from "../recovery-classification.js";
8
8
  import { reconcileBeforeDispatch } from "../state-reconciliation.js";
9
9
  import { compileUnitToolContract } from "../tool-contract.js";
10
+ import { shouldBlockAutoUnitToolCall } from "../auto-unit-tool-scope.js";
10
11
  import type { GSDState } from "../types.js";
11
12
 
12
13
  function makeState(overrides: Partial<GSDState> = {}): GSDState {
@@ -63,10 +64,35 @@ test("Tool Contract compiles known Unit prompt and tool policy", () => {
63
64
  assert.equal(result.ok, true);
64
65
  assert.equal(result.ok && result.contract.unitType, "execute-task");
65
66
  assert.deepEqual(result.ok && result.contract.requiredWorkflowTools, ["gsd_task_complete"]);
67
+ assert.deepEqual(result.ok && result.contract.forbiddenWorkflowTools, []);
66
68
  assert.equal(result.ok && result.contract.toolsPolicy.mode, "all");
67
69
  assert.ok(result.ok && result.contract.validationRules.includes("closeout-tool-present"));
68
70
  });
69
71
 
72
+ test("Tool Contract records high-risk cross-phase tool boundaries without single-owning every tool", () => {
73
+ const completeSlice = compileUnitToolContract("complete-slice");
74
+ const runUat = compileUnitToolContract("run-uat");
75
+
76
+ assert.equal(completeSlice.ok, true);
77
+ assert.ok(
78
+ completeSlice.ok &&
79
+ completeSlice.contract.forbiddenWorkflowTools.some((tool) => tool.name === "gsd_uat_result_save"),
80
+ "complete-slice should explicitly forbid saving UAT Assessments",
81
+ );
82
+
83
+ assert.equal(runUat.ok, true);
84
+ assert.ok(
85
+ runUat.ok &&
86
+ runUat.contract.requiredWorkflowTools.includes("gsd_uat_result_save"),
87
+ "run-uat should own the UAT result-save tool",
88
+ );
89
+ assert.ok(
90
+ runUat.ok &&
91
+ runUat.contract.forbiddenWorkflowTools.some((tool) => tool.name === "gsd_exec"),
92
+ "run-uat should prefer typed UAT execution over generic gsd_exec",
93
+ );
94
+ });
95
+
70
96
  test("Tool Contract fails closed for unknown Units", () => {
71
97
  const result = compileUnitToolContract("custom-step");
72
98
 
@@ -74,10 +100,20 @@ test("Tool Contract fails closed for unknown Units", () => {
74
100
  assert.equal(!result.ok && result.reason, "unknown-unit-type");
75
101
  });
76
102
 
103
+ test("auto Unit tool scope blocks complete-slice from saving UAT Assessment", () => {
104
+ const result = shouldBlockAutoUnitToolCall("complete-slice", "gsd_uat_result_save");
105
+
106
+ assert.equal(result.block, true);
107
+ assert.match(result.reason ?? "", /Tool Contract failure/);
108
+ assert.match(result.reason ?? "", /Run UAT owns persisted UAT Assessment/);
109
+ });
110
+
77
111
  test("Recovery Classification covers ADR-015 failure families", () => {
78
112
  const cases = [
79
113
  ["invalid tool schema enum", "tool-schema", "stop"],
114
+ ["Tool Contract failure: complete-slice cannot use gsd_uat_result_save", "tool-contract", "stop"],
80
115
  ["deterministic policy rejection", "deterministic-policy", "stop"],
116
+ ["cannot legally advance because required UAT Assessment artifact is missing", "lifecycle-progression", "stop"],
81
117
  ["stale worker lease", "stale-worker", "stop"],
82
118
  ["worktree root missing .git", "worktree-invalid", "stop"],
83
119
  ["verification drift in state snapshot", "verification-drift", "escalate"],
@@ -298,6 +298,106 @@ test("session_start installs the welcome screen as the TUI header", async (t) =>
298
298
  assert.deepEqual(header.render(123), ["welcome 9.9.9-test none 123"]);
299
299
  });
300
300
 
301
+ test("session hooks preserve closeout-boundary UI during completion reroot", async (t) => {
302
+ const dir = join(
303
+ tmpdir(),
304
+ `gsd-closeout-session-hooks-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
305
+ );
306
+ mkdirSync(join(dir, ".gsd"), { recursive: true });
307
+ mkdirSync(join(dir, "dist"), { recursive: true });
308
+ const tempGsdHome = join(dir, "home");
309
+ mkdirSync(tempGsdHome, { recursive: true });
310
+ writeFileSync(
311
+ join(dir, "dist", "welcome-screen.js"),
312
+ "export function buildWelcomeScreenLines() { return ['welcome header']; }\n",
313
+ "utf-8",
314
+ );
315
+
316
+ const originalCwd = process.cwd();
317
+ const originalGsdHome = process.env.GSD_HOME;
318
+ const originalGsdPkgRoot = process.env.GSD_PKG_ROOT;
319
+ process.chdir(dir);
320
+ process.env.GSD_HOME = tempGsdHome;
321
+ process.env.GSD_PKG_ROOT = dir;
322
+ autoSession.reset();
323
+ autoSession.completionStopInProgress = true;
324
+ t.after(() => {
325
+ autoSession.reset();
326
+ process.chdir(originalCwd);
327
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
328
+ else process.env.GSD_HOME = originalGsdHome;
329
+ if (originalGsdPkgRoot === undefined) delete process.env.GSD_PKG_ROOT;
330
+ else process.env.GSD_PKG_ROOT = originalGsdPkgRoot;
331
+ try { rmSync(dir, { recursive: true, force: true }); } catch { /* best-effort */ }
332
+ });
333
+
334
+ const handlers = new Map<string, (event: unknown, ctx: any) => Promise<void> | void>();
335
+ const pi = {
336
+ on(event: string, handler: (event: unknown, ctx: any) => Promise<void> | void) {
337
+ handlers.set(event, handler);
338
+ },
339
+ } as any;
340
+
341
+ registerHooks(pi, []);
342
+
343
+ const sessionStart = handlers.get("session_start");
344
+ const sessionSwitch = handlers.get("session_switch");
345
+ assert.ok(sessionStart, "session_start handler must be registered");
346
+ assert.ok(sessionSwitch, "session_switch handler must be registered");
347
+
348
+ const widgetCalls: Array<{ key: string; value: unknown }> = [];
349
+ let headerInstallCount = 0;
350
+ const ctx = {
351
+ hasUI: true,
352
+ ui: {
353
+ notify: () => {},
354
+ setStatus: () => {},
355
+ setFooter: () => {},
356
+ setHeader: () => {
357
+ headerInstallCount++;
358
+ },
359
+ setWorkingMessage: () => {},
360
+ onTerminalInput: () => () => {},
361
+ setWidget: (key: string, value: unknown) => {
362
+ widgetCalls.push({ key, value });
363
+ },
364
+ },
365
+ sessionManager: { getSessionId: () => null },
366
+ model: null,
367
+ setCompactionThresholdOverride: () => {},
368
+ modelRegistry: {
369
+ setDisabledModelProviders: () => {},
370
+ getProviderAuthMode: () => undefined,
371
+ isProviderRequestReady: () => false,
372
+ },
373
+ };
374
+
375
+ await sessionStart!({}, ctx);
376
+ assert.equal(
377
+ headerInstallCount,
378
+ 0,
379
+ "completion reroot session_start must not reinstall the welcome/project-console header",
380
+ );
381
+ assert.ok(
382
+ widgetCalls.some((call) => call.key === "gsd-health" && call.value === undefined),
383
+ "completion reroot session_start should hide the ambient health widget",
384
+ );
385
+
386
+ widgetCalls.length = 0;
387
+ await sessionSwitch!({ reason: "reroot" }, ctx);
388
+ assert.deepEqual(
389
+ widgetCalls
390
+ .filter((call) => call.key === "gsd-progress" || call.key === "gsd-outcome")
391
+ .map((call) => [call.key, call.value]),
392
+ [],
393
+ "completion reroot session_switch must not clear the preserved closeout surface",
394
+ );
395
+ assert.ok(
396
+ widgetCalls.some((call) => call.key === "gsd-health" && call.value === undefined),
397
+ "completion reroot session_switch should keep the ambient health widget hidden",
398
+ );
399
+ });
400
+
301
401
  test("session_start and session_switch apply disabled model provider policy from current preferences", async (t) => {
302
402
  const dir = join(
303
403
  tmpdir(),
@@ -5,6 +5,7 @@ import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
  import { loadSkills } from "@gsd/pi-coding-agent";
7
7
  import {
8
+ buildCompleteSlicePrompt,
8
9
  buildPlanMilestonePrompt,
9
10
  buildResearchMilestonePrompt,
10
11
  buildSkillActivationBlock,
@@ -143,6 +144,29 @@ test("buildSkillActivationBlock includes skill_rules matches and task-plan skill
143
144
  }
144
145
  });
145
146
 
147
+ test("buildSkillActivationBlock matches skill_rules against exact unit type context", () => {
148
+ const base = makeTempBase();
149
+ try {
150
+ writeSkill(base, "complete-slice-policies", "Use for complete-slice closeout policy checks.");
151
+ writeSkill(base, "slice-broad", "Use for broad slice work.");
152
+ loadOnlyTestSkills(base);
153
+
154
+ const result = buildBlock(base, {
155
+ unitType: "complete-slice",
156
+ }, {
157
+ skill_rules: [
158
+ { when: "complete-slice", use: ["complete-slice-policies"] },
159
+ { when: "slice", use: ["slice-broad"] },
160
+ ],
161
+ });
162
+
163
+ assert.match(result, /Call Skill\(\{ skill: 'complete-slice-policies' \}\)/);
164
+ assert.doesNotMatch(result, /slice-broad/);
165
+ } finally {
166
+ cleanup(base);
167
+ }
168
+ });
169
+
146
170
  test("buildSkillActivationBlock honors avoid_skills against always_use_skills", () => {
147
171
  const base = makeTempBase();
148
172
  try {
@@ -328,6 +352,37 @@ test("milestone prompt builders propagate always_use_skills through buildSkillAc
328
352
  }
329
353
  });
330
354
 
355
+ test("complete-slice prompt propagates always_use_skills through buildSkillActivationBlock", async () => {
356
+ const base = makeTempBase();
357
+ try {
358
+ writeSkill(base, "write-docs", "Use when writing docs or RFCs.");
359
+ writeProjectPreferences(base, "always_use_skills:\n - write-docs\n");
360
+ loadOnlyTestSkills(base);
361
+
362
+ const milestoneDir = join(base, ".gsd", "milestones", "M001");
363
+ const sliceDir = join(milestoneDir, "slices", "S01");
364
+ mkdirSync(sliceDir, { recursive: true });
365
+ writeFileSync(
366
+ join(milestoneDir, "M001-ROADMAP.md"),
367
+ [
368
+ "# M001: Test",
369
+ "",
370
+ "## Slices",
371
+ "",
372
+ "- [ ] **S01: Slice** `risk:low` `depends:[]`",
373
+ "",
374
+ ].join("\n"),
375
+ );
376
+ writeFileSync(join(sliceDir, "S01-PLAN.md"), "# S01: Slice\n\n## Tasks\n\n- [x] **T01: Done**\n");
377
+
378
+ const prompt = await buildCompleteSlicePrompt("M001", "Test", "S01", "Slice", base);
379
+
380
+ assert.match(prompt, /Call Skill\(\{ skill: 'write-docs' \}\)/);
381
+ } finally {
382
+ cleanup(base);
383
+ }
384
+ });
385
+
331
386
  test("skill manifest strict warnings require GSD_SKILL_MANIFEST_STRICT=1", (t) => {
332
387
  const previousStrict = process.env.GSD_SKILL_MANIFEST_STRICT;
333
388
  const previousStderr = setStderrLoggingEnabled(false);
@@ -148,6 +148,7 @@ test("fresh start registers the auto worker before bootstrap enters worktree flo
148
148
  const freshStartSectionIdx = startAutoBody.indexOf("// ── Fresh start path — delegated to auto-start.ts ──");
149
149
  const resumeBody = startAutoBody.slice(resumeSectionIdx, freshStartSectionIdx);
150
150
  const resumeDbOpenIdx = resumeBody.indexOf("await openProjectDbIfPresent(base);");
151
+ const resumeMergeReconcileIdx = resumeBody.indexOf("reconcileMergedMilestonesFromJournal(base);");
151
152
  const resumeRegisterIdx = resumeBody.indexOf("registerAutoWorkerForSession(s, base);");
152
153
  const resumeEnterMilestoneIdx = resumeBody.indexOf("buildLifecycle().enterMilestone");
153
154
  const dbOpenIdx = bootstrapBody.indexOf("await openProjectDbIfPresent(base);");
@@ -164,6 +165,7 @@ test("fresh start registers the auto worker before bootstrap enters worktree flo
164
165
  assert.ok(resumeSectionIdx > -1, "startAuto should have resume milestone entry flow");
165
166
  assert.ok(freshStartSectionIdx > resumeSectionIdx, "resume assertions should be scoped before fresh start");
166
167
  assert.ok(resumeDbOpenIdx > -1, "resume should open DB before milestone entry");
168
+ assert.ok(resumeMergeReconcileIdx > -1, "resume should reconcile merged milestones before deriving dispatch state");
167
169
  assert.ok(resumeRegisterIdx > -1, "resume should register worker before milestone entry");
168
170
  assert.ok(resumeEnterMilestoneIdx > -1, "resume should enter milestones through lifecycle");
169
171
  assert.ok(bootstrapIdx > -1, "bootstrapAutoSession should exist");
@@ -179,8 +181,10 @@ test("fresh start registers the auto worker before bootstrap enters worktree flo
179
181
  "bootstrap must open DB and register worker before first enterMilestone",
180
182
  );
181
183
  assert.ok(
182
- resumeDbOpenIdx < resumeRegisterIdx && resumeRegisterIdx < resumeEnterMilestoneIdx,
183
- "resume must open DB and register worker before first enterMilestone",
184
+ resumeDbOpenIdx < resumeMergeReconcileIdx &&
185
+ resumeMergeReconcileIdx < resumeRegisterIdx &&
186
+ resumeRegisterIdx < resumeEnterMilestoneIdx,
187
+ "resume must open DB, reconcile merged milestones, and register worker before first enterMilestone",
184
188
  );
185
189
  });
186
190
 
@@ -906,6 +906,51 @@ test("ADR-017 (#5704): registered milestone (DB row present) → no drift", asyn
906
906
 
907
907
  // ─── #5705: roadmap-divergence drift ─────────────────────────────────────────
908
908
 
909
+ test("ADR-017 (#391): roadmap-divergence skips slices before task planning completes", async (t) => {
910
+ const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-unplanned-"));
911
+ const milestoneDir = join(base, ".gsd", "milestones", "M001");
912
+ const roadmapPath = join(milestoneDir, "M001-ROADMAP.md");
913
+ mkdirSync(milestoneDir, { recursive: true });
914
+ const originalRoadmap = [
915
+ "# M001: Test",
916
+ "",
917
+ "**Vision:** Verify transient milestone planning state",
918
+ "",
919
+ "## Slices",
920
+ "",
921
+ "- [ ] **S01: Foundation** `risk:medium` `depends:[]`",
922
+ "- [ ] **S02: Feature** `risk:medium` `depends:[S01]`",
923
+ "",
924
+ ].join("\n");
925
+ writeFileSync(roadmapPath, originalRoadmap);
926
+ t.after(() => {
927
+ try { closeDatabase(); } catch { /* noop */ }
928
+ rmSync(base, { recursive: true, force: true });
929
+ });
930
+
931
+ openDatabase(join(base, ".gsd", "gsd.db"));
932
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
933
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
934
+ insertSlice({ id: "S02", milestoneId: "M001", title: "Feature", status: "pending", risk: "medium", depends: [], demo: "", sequence: 2 });
935
+
936
+ assert.equal(getSliceTasks("M001", "S01").length, 0, "pre: S01 has not been planned");
937
+ assert.equal(getSliceTasks("M001", "S02").length, 0, "pre: S02 has not been planned");
938
+
939
+ const result = await reconcileBeforeDispatch(base, {
940
+ invalidateStateCache: () => {},
941
+ deriveState: async () => makeState(),
942
+ });
943
+
944
+ assert.equal(result.ok, true);
945
+ assert.equal(
946
+ result.repaired.some((d) => d.kind === "roadmap-divergence"),
947
+ false,
948
+ "unplanned slices should not trigger roadmap-divergence repair",
949
+ );
950
+ assert.equal(readFileSync(roadmapPath, "utf-8"), originalRoadmap);
951
+ assert.deepEqual(getSlice("M001", "S02")?.depends, [], "DB remains unchanged");
952
+ });
953
+
909
954
  test("ADR-017 (#5705): roadmap-divergence re-renders projection without syncing depends into DB", async (t) => {
910
955
  const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-"));
911
956
  const milestoneDir = join(base, ".gsd", "milestones", "M001");
@@ -936,6 +981,8 @@ test("ADR-017 (#5705): roadmap-divergence re-renders projection without syncing
936
981
  // Seed DB with S02 depending on [] — diverges from ROADMAP.md
937
982
  insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
938
983
  insertSlice({ id: "S02", milestoneId: "M001", title: "Feature", status: "pending", risk: "medium", depends: [], demo: "", sequence: 2 });
984
+ insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
985
+ insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", title: "Plan S02", status: "pending" });
939
986
 
940
987
  assert.deepEqual(getSlice("M001", "S02")?.depends, [], "pre: DB has S02.depends = []");
941
988
 
@@ -987,6 +1034,7 @@ test("ADR-017 (#5705): ROADMAP-only slice is removed from projection and not ins
987
1034
  insertMilestone({ id: "M001", title: "Test", status: "active" });
988
1035
  // Only insert S01 — S02 is intentionally absent from the DB.
989
1036
  insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
1037
+ insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
990
1038
 
991
1039
  assert.equal(getSlice("M001", "S02"), null, "pre: S02 has no DB row");
992
1040
 
@@ -1035,6 +1083,8 @@ test("ADR-017 (#5705): ROADMAP sequence drift re-renders from DB order without m
1035
1083
  insertMilestone({ id: "M001", title: "Test", status: "active" });
1036
1084
  insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
1037
1085
  insertSlice({ id: "S02", milestoneId: "M001", title: "Feature", status: "pending", risk: "medium", depends: [], demo: "", sequence: 2 });
1086
+ insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
1087
+ insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", title: "Plan S02", status: "pending" });
1038
1088
 
1039
1089
  const result = await reconcileBeforeDispatch(base, {
1040
1090
  invalidateStateCache: () => {},
@@ -1078,6 +1128,7 @@ test("ADR-017 (#5705): ROADMAP checkbox drift re-renders from DB status without
1078
1128
  openDatabase(join(base, ".gsd", "gsd.db"));
1079
1129
  insertMilestone({ id: "M001", title: "Test", status: "active" });
1080
1130
  insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
1131
+ insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
1081
1132
 
1082
1133
  const result = await reconcileBeforeDispatch(base, {
1083
1134
  invalidateStateCache: () => {},
@@ -1119,6 +1170,7 @@ test("ADR-017 (#5705): in-sync ROADMAP and DB → no roadmap-divergence drift",
1119
1170
  openDatabase(join(base, ".gsd", "gsd.db"));
1120
1171
  insertMilestone({ id: "M001", title: "Test", status: "active" });
1121
1172
  insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "low", depends: [], demo: "", sequence: 1 });
1173
+ insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
1122
1174
 
1123
1175
  const result = await reconcileBeforeDispatch(base, {
1124
1176
  invalidateStateCache: () => {},
@@ -1300,6 +1352,145 @@ test("ADR-017: orphan task completion artifact fails closed", async (t) => {
1300
1352
  assert.match(result.blockers.join("\n"), /Artifact\/DB status drift/);
1301
1353
  });
1302
1354
 
1355
+ test("ADR-017 (#414): failure-path summary artifact blocker matches auto.ts filter phrase", async (t) => {
1356
+ // When gsd_summary_save writes a SUMMARY artifact row for a task that never
1357
+ // called gsd_task_complete, the task stays pending and the artifact DB row
1358
+ // produces an artifact-db-status-divergence blocker. The auto.ts dispatch
1359
+ // wrapper must be able to filter this class of blocker to allow re-dispatch.
1360
+ // If this test fails, update the filter strings in auto.ts to match.
1361
+ const base = mkdtempSync(join(tmpdir(), "gsd-failure-path-summary-drift-"));
1362
+ t.after(() => cleanup(base));
1363
+
1364
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S04"), { recursive: true });
1365
+ openDatabase(join(base, ".gsd", "gsd.db"));
1366
+ insertMilestone({ id: "M001", title: "Milestone", status: "active" });
1367
+ insertSlice({ id: "S04", milestoneId: "M001", title: "Slice", status: "pending" });
1368
+ insertTask({ id: "T01", sliceId: "S04", milestoneId: "M001", title: "Task", status: "pending" });
1369
+ insertArtifact({
1370
+ path: join(base, ".gsd", "milestones", "M001", "slices", "S04", "tasks", "T01", "T01-SUMMARY.md"),
1371
+ artifact_type: "SUMMARY",
1372
+ milestone_id: "M001",
1373
+ slice_id: "S04",
1374
+ task_id: "T01",
1375
+ full_content: "# T01 Failure Summary\n",
1376
+ });
1377
+
1378
+ const result = await reconcileBeforeDispatch(base, {
1379
+ invalidateStateCache: () => {},
1380
+ deriveState: async () => makeState({ activeMilestone: { id: "M001", title: "Milestone" } }),
1381
+ });
1382
+
1383
+ assert.equal(result.ok, true);
1384
+ assert.ok(result.blockers.length > 0, "blocker must be produced for pending-task SUMMARY drift");
1385
+ const blocker = result.blockers.join("\n");
1386
+ assert.match(
1387
+ blocker,
1388
+ /has SUMMARY artifact while DB status is/,
1389
+ "blocker phrase must match the filter in auto.ts reconcileBeforeDispatch wrapper",
1390
+ );
1391
+ });
1392
+
1393
+ test("ADR-017 (#414): no-db-tasks summary artifact blocker matches auto.ts filter phrase", async (t) => {
1394
+ // When a slice has SUMMARY artifacts in the DB but no DB tasks, the auto.ts
1395
+ // filter must be able to recognise this as a failure-path case and skip it.
1396
+ const base = mkdtempSync(join(tmpdir(), "gsd-no-db-tasks-summary-drift-"));
1397
+ t.after(() => cleanup(base));
1398
+
1399
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S04"), { recursive: true });
1400
+ openDatabase(join(base, ".gsd", "gsd.db"));
1401
+ insertMilestone({ id: "M001", title: "Milestone", status: "active" });
1402
+ insertSlice({ id: "S04", milestoneId: "M001", title: "Slice", status: "pending" });
1403
+ // No tasks inserted — slice has SUMMARY artifacts for a task that no longer exists.
1404
+ insertArtifact({
1405
+ path: join(base, ".gsd", "milestones", "M001", "slices", "S04", "tasks", "T01", "T01-SUMMARY.md"),
1406
+ artifact_type: "SUMMARY",
1407
+ milestone_id: "M001",
1408
+ slice_id: "S04",
1409
+ task_id: "T01",
1410
+ full_content: "# T01 Failure Summary\n",
1411
+ });
1412
+
1413
+ const result = await reconcileBeforeDispatch(base, {
1414
+ invalidateStateCache: () => {},
1415
+ deriveState: async () => makeState({ activeMilestone: { id: "M001", title: "Milestone" } }),
1416
+ });
1417
+
1418
+ assert.equal(result.ok, true);
1419
+ assert.ok(result.blockers.length > 0, "blocker must be produced for no-db-tasks SUMMARY drift");
1420
+ const blocker = result.blockers.join("\n");
1421
+ assert.match(
1422
+ blocker,
1423
+ /has task SUMMARY artifacts but no DB tasks/,
1424
+ "blocker phrase must match the filter in auto.ts reconcileBeforeDispatch wrapper",
1425
+ );
1426
+ });
1427
+
1428
+ test("ADR-017 (#414): task-level on-disk summary blocker matches auto.ts filter phrase", async (t) => {
1429
+ // When gsd_summary_save writes a SUMMARY file to disk for a task that never
1430
+ // called gsd_task_complete, but the artifact DB row was not yet written (or
1431
+ // the process crashed before insertion), reconciliation emits
1432
+ // "has SUMMARY on disk while DB status is". The auto.ts filter must match
1433
+ // this phrase so re-dispatch is not blocked.
1434
+ const base = mkdtempSync(join(tmpdir(), "gsd-task-disk-summary-drift-"));
1435
+ t.after(() => cleanup(base));
1436
+
1437
+ const tasksDir = join(base, ".gsd", "milestones", "M001", "slices", "S04", "tasks");
1438
+ mkdirSync(tasksDir, { recursive: true });
1439
+ writeFileSync(join(tasksDir, "T01-SUMMARY.md"), "# T01 Failure Summary\n");
1440
+
1441
+ openDatabase(join(base, ".gsd", "gsd.db"));
1442
+ insertMilestone({ id: "M001", title: "Milestone", status: "active" });
1443
+ insertSlice({ id: "S04", milestoneId: "M001", title: "Slice", status: "pending" });
1444
+ insertTask({ id: "T01", sliceId: "S04", milestoneId: "M001", title: "Task", status: "pending" });
1445
+ // No artifact row inserted — SUMMARY exists only on disk.
1446
+
1447
+ const result = await reconcileBeforeDispatch(base, {
1448
+ invalidateStateCache: () => {},
1449
+ deriveState: async () => makeState({ activeMilestone: { id: "M001", title: "Milestone" } }),
1450
+ });
1451
+
1452
+ assert.equal(result.ok, true);
1453
+ assert.ok(result.blockers.length > 0, "blocker must be produced for on-disk task SUMMARY drift");
1454
+ const blocker = result.blockers.join("\n");
1455
+ assert.match(
1456
+ blocker,
1457
+ /has SUMMARY on disk while DB status is/,
1458
+ "blocker phrase must match the filter in auto.ts reconcileBeforeDispatch wrapper",
1459
+ );
1460
+ });
1461
+
1462
+ test("ADR-017 (#414): slice-level on-disk summary blocker matches auto.ts filter phrase", async (t) => {
1463
+ // When a SUMMARY file exists on disk for a slice that is still pending
1464
+ // (no gsd_task_complete for the slice), reconciliation emits
1465
+ // "has SUMMARY on disk while DB status is". The auto.ts filter must match
1466
+ // this phrase so re-dispatch is not blocked.
1467
+ const base = mkdtempSync(join(tmpdir(), "gsd-slice-disk-summary-drift-"));
1468
+ t.after(() => cleanup(base));
1469
+
1470
+ const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S04");
1471
+ mkdirSync(sliceDir, { recursive: true });
1472
+ writeFileSync(join(sliceDir, "S04-SUMMARY.md"), "# S04 Failure Summary\n");
1473
+
1474
+ openDatabase(join(base, ".gsd", "gsd.db"));
1475
+ insertMilestone({ id: "M001", title: "Milestone", status: "active" });
1476
+ insertSlice({ id: "S04", milestoneId: "M001", title: "Slice", status: "pending" });
1477
+ // No artifact row inserted — SUMMARY exists only on disk.
1478
+
1479
+ const result = await reconcileBeforeDispatch(base, {
1480
+ invalidateStateCache: () => {},
1481
+ deriveState: async () => makeState({ activeMilestone: { id: "M001", title: "Milestone" } }),
1482
+ });
1483
+
1484
+ assert.equal(result.ok, true);
1485
+ assert.ok(result.blockers.length > 0, "blocker must be produced for on-disk slice SUMMARY drift");
1486
+ const blocker = result.blockers.join("\n");
1487
+ assert.match(
1488
+ blocker,
1489
+ /has SUMMARY on disk while DB status is/,
1490
+ "blocker phrase must match the filter in auto.ts reconcileBeforeDispatch wrapper",
1491
+ );
1492
+ });
1493
+
1303
1494
  test("ADR-017: completed milestone dispatch history blocks accidental re-planning", async (t) => {
1304
1495
  const base = mkdtempSync(join(tmpdir(), "gsd-completed-reopened-drift-"));
1305
1496
  t.after(() => cleanup(base));