@opengsd/gsd-pi 1.1.1-dev.74e8dd1 → 1.1.1-dev.a5a2de8

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 (329) 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/gsd/auto/orchestrator.js +0 -1
  10. package/dist/resources/extensions/gsd/auto-dashboard.js +77 -13
  11. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
  12. package/dist/resources/extensions/gsd/auto-post-unit.js +21 -3
  13. package/dist/resources/extensions/gsd/auto-prompts.js +63 -22
  14. package/dist/resources/extensions/gsd/auto-recovery.js +3 -4
  15. package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
  16. package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
  17. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +18 -66
  18. package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
  19. package/dist/resources/extensions/gsd/auto.js +9 -2
  20. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +20 -14
  21. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +28 -13
  22. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +18 -29
  23. package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
  24. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
  25. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  26. package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
  27. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -1
  28. package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
  29. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  30. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
  31. package/dist/resources/extensions/gsd/escalation.js +4 -4
  32. package/dist/resources/extensions/gsd/forensics.js +74 -2
  33. package/dist/resources/extensions/gsd/gsd-db.js +5 -2
  34. package/dist/resources/extensions/gsd/guided-flow.js +118 -175
  35. package/dist/resources/extensions/gsd/mcp-project-config.js +9 -76
  36. package/dist/resources/extensions/gsd/memory-store.js +4 -1
  37. package/dist/resources/extensions/gsd/milestone-closeout.js +3 -1
  38. package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
  39. package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
  40. package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
  41. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  42. package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
  43. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  44. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  45. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  46. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  47. package/dist/resources/extensions/gsd/prompts/run-uat.md +25 -21
  48. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  49. package/dist/resources/extensions/gsd/recovery-classification.js +20 -0
  50. package/dist/resources/extensions/gsd/rule-registry.js +428 -52
  51. package/dist/resources/extensions/gsd/state.js +2 -2
  52. package/dist/resources/extensions/gsd/templates/plan.md +3 -1
  53. package/dist/resources/extensions/gsd/tool-contract.js +5 -0
  54. package/dist/resources/extensions/gsd/tool-presentation-plan.js +17 -7
  55. package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
  56. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
  57. package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
  58. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +132 -18
  59. package/dist/resources/extensions/gsd/unit-tool-contracts.js +169 -0
  60. package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
  61. package/dist/resources/extensions/gsd/verification-gate.js +72 -1
  62. package/dist/resources/extensions/gsd/workflow-mcp.js +3 -75
  63. package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
  64. package/dist/rtk.d.ts +7 -1
  65. package/dist/rtk.js +27 -11
  66. package/dist/update-check.d.ts +15 -1
  67. package/dist/update-check.js +87 -12
  68. package/dist/update-cmd.d.ts +1 -0
  69. package/dist/update-cmd.js +53 -2
  70. package/dist/web/standalone/.next/BUILD_ID +1 -1
  71. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  72. package/dist/web/standalone/.next/build-manifest.json +2 -2
  73. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  74. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  91. package/dist/web/standalone/.next/server/app/index.html +1 -1
  92. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  99. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  100. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  102. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  103. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  104. package/package.json +4 -2
  105. package/packages/cloud-mcp-gateway/package.json +2 -2
  106. package/packages/contracts/package.json +1 -1
  107. package/packages/daemon/package.json +4 -4
  108. package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
  109. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  110. package/packages/gsd-agent-core/dist/agent-session.js +32 -0
  111. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  112. package/packages/gsd-agent-core/dist/index.d.ts +1 -0
  113. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  114. package/packages/gsd-agent-core/dist/index.js +1 -0
  115. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  116. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
  117. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
  118. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
  119. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
  120. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
  121. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  122. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  123. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  124. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
  125. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  126. package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
  127. package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
  128. package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
  129. package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
  130. package/packages/gsd-agent-core/package.json +6 -6
  131. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
  132. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
  133. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
  134. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
  135. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  136. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  137. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  138. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  139. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +20 -0
  140. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  141. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  142. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
  143. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  144. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
  145. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
  146. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
  147. package/packages/gsd-agent-modes/package.json +7 -7
  148. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
  149. package/packages/mcp-server/dist/remote-questions.js +23 -9
  150. package/packages/mcp-server/dist/remote-questions.js.map +1 -1
  151. package/packages/mcp-server/dist/workflow-tools.js +2 -2
  152. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  153. package/packages/mcp-server/package.json +3 -3
  154. package/packages/native/package.json +1 -1
  155. package/packages/pi-agent-core/dist/agent-loop.js +42 -3
  156. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  157. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  158. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  159. package/packages/pi-agent-core/dist/agent.js +2 -0
  160. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  161. package/packages/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  162. package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
  163. package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  164. package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
  165. package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  166. package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
  167. package/packages/pi-agent-core/dist/types.d.ts +6 -1
  168. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  169. package/packages/pi-agent-core/dist/types.js.map +1 -1
  170. package/packages/pi-agent-core/package.json +1 -1
  171. package/packages/pi-ai/dist/api-registry.d.ts +2 -0
  172. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  173. package/packages/pi-ai/dist/api-registry.js +23 -0
  174. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  175. package/packages/pi-ai/dist/models.generated.d.ts +74 -6
  176. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  177. package/packages/pi-ai/dist/models.generated.js +78 -10
  178. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  179. package/packages/pi-ai/dist/stream.js +6 -6
  180. package/packages/pi-ai/dist/stream.js.map +1 -1
  181. package/packages/pi-ai/package.json +1 -1
  182. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +3 -0
  183. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  186. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  187. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  188. package/packages/pi-coding-agent/dist/core/tools/bash.js +2 -2
  189. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  190. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
  192. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
  194. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
  196. package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
  197. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  198. package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
  199. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  200. package/packages/pi-coding-agent/package.json +7 -7
  201. package/packages/pi-tui/package.json +1 -1
  202. package/packages/rpc-client/package.json +2 -2
  203. package/pkg/package.json +1 -1
  204. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
  205. package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
  206. package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
  207. package/src/resources/extensions/browser-tools/index.ts +60 -9
  208. package/src/resources/extensions/browser-tools/package.json +5 -1
  209. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
  210. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
  211. package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
  212. package/src/resources/extensions/gsd/auto-dashboard.ts +82 -14
  213. package/src/resources/extensions/gsd/auto-dispatch.ts +19 -0
  214. package/src/resources/extensions/gsd/auto-post-unit.ts +28 -2
  215. package/src/resources/extensions/gsd/auto-prompts.ts +97 -15
  216. package/src/resources/extensions/gsd/auto-recovery.ts +3 -3
  217. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
  218. package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
  219. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +43 -74
  220. package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
  221. package/src/resources/extensions/gsd/auto.ts +12 -2
  222. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +20 -14
  223. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +32 -13
  224. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +50 -54
  225. package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
  226. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
  227. package/src/resources/extensions/gsd/commands/handlers/ops.ts +2 -2
  228. package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
  229. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -1
  230. package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
  231. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  232. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
  233. package/src/resources/extensions/gsd/escalation.ts +4 -4
  234. package/src/resources/extensions/gsd/forensics.ts +99 -5
  235. package/src/resources/extensions/gsd/gsd-db.ts +5 -2
  236. package/src/resources/extensions/gsd/guided-flow.ts +214 -216
  237. package/src/resources/extensions/gsd/mcp-project-config.ts +13 -78
  238. package/src/resources/extensions/gsd/memory-store.ts +4 -1
  239. package/src/resources/extensions/gsd/milestone-closeout.ts +3 -1
  240. package/src/resources/extensions/gsd/pending-auto-start.ts +0 -2
  241. package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
  242. package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
  243. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  244. package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
  245. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  246. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  247. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  248. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  249. package/src/resources/extensions/gsd/prompts/run-uat.md +25 -21
  250. package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  251. package/src/resources/extensions/gsd/recovery-classification.ts +20 -0
  252. package/src/resources/extensions/gsd/rule-registry.ts +558 -58
  253. package/src/resources/extensions/gsd/rule-types.ts +2 -0
  254. package/src/resources/extensions/gsd/state.ts +2 -2
  255. package/src/resources/extensions/gsd/templates/plan.md +3 -1
  256. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +105 -4
  257. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +37 -0
  258. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +10 -2
  259. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
  260. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +12 -2
  261. package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
  262. package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
  263. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
  264. package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -0
  265. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
  266. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  267. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
  268. package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
  269. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
  270. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +40 -1
  271. package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
  272. package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
  273. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
  274. package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
  275. package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
  276. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +31 -79
  277. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
  278. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
  279. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +5 -3
  280. package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
  281. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
  282. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
  283. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +8 -0
  284. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
  285. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +69 -10
  286. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +32 -0
  287. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +2 -0
  288. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
  289. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +63 -0
  290. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
  291. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
  292. package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
  293. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
  294. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
  295. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
  296. package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
  297. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +61 -1
  298. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
  299. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
  300. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +44 -0
  301. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
  302. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +4 -0
  303. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +36 -0
  304. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
  305. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +139 -0
  306. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -4
  307. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  308. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
  309. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
  310. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
  311. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
  312. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +351 -0
  313. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -0
  314. package/src/resources/extensions/gsd/tool-contract.ts +6 -0
  315. package/src/resources/extensions/gsd/tool-presentation-plan.ts +38 -8
  316. package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
  317. package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
  318. package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
  319. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +163 -20
  320. package/src/resources/extensions/gsd/types.ts +69 -5
  321. package/src/resources/extensions/gsd/unit-tool-contracts.ts +186 -0
  322. package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
  323. package/src/resources/extensions/gsd/verification-gate.ts +87 -1
  324. package/src/resources/extensions/gsd/workflow-mcp.ts +3 -75
  325. package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
  326. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
  327. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
  328. /package/dist/web/standalone/.next/static/{eRWf-RI9bzbrwEurm_3uI → 9y3LeeR2uGr2yRj9RjY3D}/_buildManifest.js +0 -0
  329. /package/dist/web/standalone/.next/static/{eRWf-RI9bzbrwEurm_3uI → 9y3LeeR2uGr2yRj9RjY3D}/_ssgManifest.js +0 -0
@@ -42,6 +42,10 @@ export function isAutoPaused(): boolean {
42
42
  return autoSession.paused;
43
43
  }
44
44
 
45
+ export function isAutoCompletionStopInProgress(): boolean {
46
+ return autoSession.completionStopInProgress;
47
+ }
48
+
45
49
  export function markToolStart(toolCallId: string, toolName?: string): void {
46
50
  markTrackedToolStart(toolCallId, autoSession.active, toolName);
47
51
  }
@@ -94,7 +94,7 @@ export function clearInFlightTools(): void {
94
94
  * from the tool handler. When these errors occur, retrying the same unit will
95
95
  * produce the same failure, so the retry loop must be broken.
96
96
  */
97
- const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
97
+ const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Input validation error|Invalid arguments for tool|MCP error -32602|No such tool available|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
98
98
  const DETERMINISTIC_POLICY_ERROR_RE = /(?:^|\b)(?:HARD BLOCK:|Blocked: \/gsd queue is a planning tool|Direct writes to \.gsd\/STATE\.md and \.gsd\/gsd\.db are blocked|This is a mechanical gate)/i;
99
99
 
100
100
  /**
@@ -1,59 +1,13 @@
1
1
  import { parseUnitId } from "./unit-id.js";
2
- import { RUN_UAT_WORKFLOW_TOOL_NAMES } from "./tool-presentation-plan.js";
3
-
4
- export const RUN_UAT_BROWSER_TOOL_NAMES = [
5
- "browser_navigate",
6
- "browser_click",
7
- "browser_type",
8
- "browser_fill_form",
9
- "browser_click_ref",
10
- "browser_fill_ref",
11
- "browser_wait_for",
12
- "browser_assert",
13
- "browser_verify",
14
- "browser_screenshot",
15
- "browser_snapshot_refs",
16
- "browser_find",
17
- "browser_get_console_logs",
18
- "browser_get_network_logs",
19
- "browser_evaluate",
20
- "browser_reload",
21
- "browser_batch",
22
- "browser_act",
23
- ] as const;
2
+ import {
3
+ AUTO_UNIT_SCOPED_TOOLS,
4
+ getForbiddenGsdToolReason,
5
+ } from "./unit-tool-contracts.js";
24
6
 
25
- export const AUTO_UNIT_SCOPED_TOOLS: Record<string, readonly string[]> = {
26
- "research-milestone": ["gsd_summary_save", "gsd_decision_save"],
27
- "plan-milestone": ["gsd_plan_milestone", "gsd_decision_save", "gsd_requirement_update"],
28
- "discuss-milestone": [
29
- "gsd_summary_save",
30
- "gsd_decision_save",
31
- "gsd_requirement_save",
32
- "gsd_requirement_update",
33
- "gsd_plan_milestone",
34
- "gsd_milestone_generate_id",
35
- ],
36
- "discuss-slice": ["gsd_summary_save", "gsd_decision_save"],
37
- "validate-milestone": ["gsd_validate_milestone", "gsd_reassess_roadmap", "subagent"],
38
- "complete-milestone": ["gsd_complete_milestone", "subagent"],
39
- "research-slice": ["gsd_summary_save", "gsd_decision_save"],
40
- "plan-slice": ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
41
- "refine-slice": ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
42
- "replan-slice": ["gsd_replan_slice", "gsd_plan_task", "gsd_decision_save"],
43
- "complete-slice": ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice", "gsd_decision_save", "gsd_requirement_update", "subagent"],
44
- "reassess-roadmap": ["gsd_reassess_roadmap"],
45
- "execute-task": ["gsd_task_complete", "gsd_decision_save"],
46
- "execute-task-simple": ["gsd_task_complete", "gsd_decision_save"],
47
- "reactive-execute": ["gsd_task_complete", "gsd_decision_save"],
48
- "run-uat": [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent", ...RUN_UAT_BROWSER_TOOL_NAMES],
49
- "gate-evaluate": ["gsd_save_gate_result"],
50
- "rewrite-docs": ["gsd_summary_save", "gsd_decision_save"],
51
- "workflow-preferences": ["gsd_summary_save"],
52
- "discuss-project": ["gsd_summary_save", "gsd_decision_save", "gsd_requirement_save"],
53
- "discuss-requirements": ["gsd_requirement_save", "gsd_summary_save"],
54
- "research-decision": ["gsd_summary_save"],
55
- "research-project": ["gsd_summary_save", "gsd_decision_save"],
56
- };
7
+ export {
8
+ AUTO_UNIT_SCOPED_TOOLS,
9
+ RUN_UAT_BROWSER_TOOL_NAMES,
10
+ } from "./unit-tool-contracts.js";
57
11
 
58
12
  const WORKFLOW_TOOL_ALIASES: Record<string, string> = {
59
13
  gsd_save_decision: "gsd_decision_save",
@@ -97,6 +51,14 @@ const SCOPED_GSD_LIFECYCLE_TOOLS = new Set(
97
51
  .map(canonicalWorkflowToolName),
98
52
  );
99
53
 
54
+ export const GSD_PHASE_SCOPE_DISPLAY_REASON = "This GSD phase only allows its scoped workflow tools.";
55
+
56
+ type AutoUnitToolScopeResult = {
57
+ block: boolean;
58
+ reason?: string;
59
+ displayReason?: string;
60
+ };
61
+
100
62
  function stripMcpToolPrefix(toolName: string): string {
101
63
  if (!toolName.startsWith("mcp__")) return toolName;
102
64
  const toolSeparator = toolName.indexOf("__", "mcp__".length);
@@ -114,12 +76,20 @@ export function isWorkflowAliasTool(toolName: string): boolean {
114
76
 
115
77
  function hardBlockReason(unitType: string, what: string): string {
116
78
  return [
117
- `HARD BLOCK: unit "${unitType}" is constrained by auto-unit tool scope — ${what}.`,
79
+ `HARD BLOCK: Tool Contract failure for unit "${unitType}" — ${what}.`,
118
80
  "This is a mechanical phase-boundary gate. You MUST NOT proceed, retry the same call,",
119
81
  "or route around this block; the orchestrator owns phase transitions.",
120
82
  ].join(" ");
121
83
  }
122
84
 
85
+ function hardBlock(unitType: string, what: string): AutoUnitToolScopeResult {
86
+ return {
87
+ block: true,
88
+ reason: hardBlockReason(unitType, what),
89
+ displayReason: GSD_PHASE_SCOPE_DISPLAY_REASON,
90
+ };
91
+ }
92
+
123
93
  function allowedGsdToolsForUnit(unitType: string): string[] {
124
94
  return [...new Set(
125
95
  (AUTO_UNIT_SCOPED_TOOLS[unitType] ?? [])
@@ -144,7 +114,7 @@ function shouldBlockTaskCompletionScope(
144
114
  unitId: string | undefined,
145
115
  toolName: string,
146
116
  input: unknown,
147
- ): { block: boolean; reason?: string } {
117
+ ): AutoUnitToolScopeResult {
148
118
  if (!EXECUTE_TASK_UNIT_TYPES.has(unitType)) return { block: false };
149
119
  if (canonicalWorkflowToolName(toolName) !== "gsd_task_complete") return { block: false };
150
120
  if (!unitId) return { block: false };
@@ -165,13 +135,10 @@ function shouldBlockTaskCompletionScope(
165
135
  return { block: false };
166
136
  }
167
137
 
168
- return {
169
- block: true,
170
- reason: hardBlockReason(
171
- unitType,
172
- `gsd_task_complete may only complete the active task ${expected.milestone}/${expected.slice}/${expected.task}; requested ${actualMilestone}/${actualSlice}/${actualTask}`,
173
- ),
174
- };
138
+ return hardBlock(
139
+ unitType,
140
+ `gsd_task_complete may only complete the active task ${expected.milestone}/${expected.slice}/${expected.task}; requested ${actualMilestone}/${actualSlice}/${actualTask}`,
141
+ );
175
142
  }
176
143
 
177
144
  export function shouldBlockAutoUnitToolCall(
@@ -179,15 +146,12 @@ export function shouldBlockAutoUnitToolCall(
179
146
  toolName: string,
180
147
  input?: unknown,
181
148
  unitId?: string,
182
- ): { block: boolean; reason?: string } {
149
+ ): AutoUnitToolScopeResult {
183
150
  const scopedTools = AUTO_UNIT_SCOPED_TOOLS[unitType];
184
151
  if (!scopedTools) return { block: false };
185
152
 
186
153
  if (isNativeWorkflowTool(toolName)) {
187
- return {
188
- block: true,
189
- reason: hardBlockReason(unitType, "native Workflow is not permitted inside a dispatched GSD auto-mode unit"),
190
- };
154
+ return hardBlock(unitType, "native Workflow is not permitted inside a dispatched GSD auto-mode unit");
191
155
  }
192
156
 
193
157
  const taskScope = shouldBlockTaskCompletionScope(unitType, unitId, toolName, input);
@@ -199,11 +163,16 @@ export function shouldBlockAutoUnitToolCall(
199
163
  const allowedTools = allowedGsdToolsForUnit(unitType);
200
164
  if (allowedTools.includes(canonicalTool)) return { block: false };
201
165
 
202
- return {
203
- block: true,
204
- reason: hardBlockReason(
166
+ const forbiddenReason = getForbiddenGsdToolReason(unitType, canonicalTool);
167
+ if (forbiddenReason) {
168
+ return hardBlock(
205
169
  unitType,
206
- `GSD lifecycle tool "${canonicalTool}" is not permitted; allowed GSD tools: ${allowedTools.length > 0 ? allowedTools.join(", ") : "(none)"}`,
207
- ),
208
- };
170
+ `GSD lifecycle tool "${canonicalTool}" is not permitted; ${forbiddenReason} Fix unit-tool-contracts.ts or the ${unitType} prompt.`,
171
+ );
172
+ }
173
+
174
+ return hardBlock(
175
+ unitType,
176
+ `GSD lifecycle tool "${canonicalTool}" is not permitted; allowed GSD tools: ${allowedTools.length > 0 ? allowedTools.join(", ") : "(none)"}`,
177
+ );
209
178
  }
@@ -83,6 +83,11 @@ import {
83
83
  nativeWorktreeList,
84
84
  nativeLsFiles,
85
85
  } from "./native-git-bridge.js";
86
+ import {
87
+ CLOSEOUT_CONSISTENCY_BLOCKED_REASON,
88
+ checkCloseoutConsistencyGate,
89
+ formatCloseoutConsistencyBlock,
90
+ } from "./closeout-consistency-gate.js";
86
91
  import { gsdHome } from "./gsd-home.js";
87
92
  import { type MilestoneScope, type GsdWorkspace, createWorkspace } from "./workspace.js";
88
93
  import {
@@ -1771,16 +1776,29 @@ export function mergeMilestoneToMain(
1771
1776
  // symlink layout) — ATTACHing a WAL-mode file to itself corrupts the
1772
1777
  // database (#2823).
1773
1778
  if (isDbAvailable()) {
1779
+ const contract = resolveGsdPathContract(worktreeCwd, originalBasePath_);
1780
+ const worktreeDbPath = join(contract.worktreeGsd ?? join(worktreeCwd, ".gsd"), "gsd.db");
1781
+ const mainDbPath = contract.projectDb;
1774
1782
  try {
1775
- const contract = resolveGsdPathContract(worktreeCwd, originalBasePath_);
1776
- const worktreeDbPath = join(contract.worktreeGsd ?? join(worktreeCwd, ".gsd"), "gsd.db");
1777
- const mainDbPath = contract.projectDb;
1783
+ const activeDbPath = getDbPath();
1784
+ if (activeDbPath && _shouldReconcileWorktreeDb(activeDbPath, mainDbPath)) {
1785
+ closeDatabase();
1786
+ if (!openDatabase(mainDbPath)) {
1787
+ throw new Error(`cannot open project DB at ${mainDbPath}`);
1788
+ }
1789
+ }
1778
1790
  if (_shouldReconcileWorktreeDb(worktreeDbPath, mainDbPath)) {
1779
1791
  reconcileWorktreeDb(mainDbPath, worktreeDbPath);
1780
1792
  }
1781
1793
  } catch (err) {
1782
- /* non-fatal */
1783
- logError("worktree", `DB reconciliation failed: ${err instanceof Error ? err.message : String(err)}`);
1794
+ const message = `DB reconciliation failed before milestone ${milestoneId} merge: ${err instanceof Error ? err.message : String(err)}`;
1795
+ logError("worktree", message);
1796
+ throw new GSDError(GSD_GIT_ERROR, `${message}. Recovery reason: ${CLOSEOUT_CONSISTENCY_BLOCKED_REASON}.`);
1797
+ }
1798
+
1799
+ const closeoutGate = checkCloseoutConsistencyGate(milestoneId);
1800
+ if (!closeoutGate.ok) {
1801
+ throw new GSDError(GSD_GIT_ERROR, formatCloseoutConsistencyBlock(closeoutGate));
1784
1802
  }
1785
1803
  }
1786
1804
 
@@ -2311,10 +2311,20 @@ export function createWiredAutoOrchestrationModule(
2311
2311
  async reconcileBeforeDispatch() {
2312
2312
  const activeBasePath = getLiveDispatchBasePath();
2313
2313
  const result = await reconcileBeforeDispatch(activeBasePath);
2314
- if (result.blockers.length > 0) {
2314
+ // Failure-path summaries written by gsd_summary_save create
2315
+ // artifact-db-status-divergence blockers for tasks that are still
2316
+ // pending (gsd_task_complete never ran). These tasks can still be
2317
+ // dispatched and the drift self-heals once they complete successfully.
2318
+ const hardBlockers = result.blockers.filter(
2319
+ (b) =>
2320
+ !b.includes("has SUMMARY artifact while DB status is") &&
2321
+ !b.includes("has SUMMARY on disk while DB status is") &&
2322
+ !b.includes("has task SUMMARY artifacts but no DB tasks"),
2323
+ );
2324
+ if (hardBlockers.length > 0) {
2315
2325
  return {
2316
2326
  ok: false,
2317
- reason: result.blockers[0],
2327
+ reason: hardBlockers[0],
2318
2328
  stateSnapshot: result.stateSnapshot,
2319
2329
  };
2320
2330
  }
@@ -78,6 +78,9 @@ function readDetails(result: any): any {
78
78
 
79
79
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- result shape varies by tool
80
80
  function formatToolErrorText(result: any, details: any): string {
81
+ if (typeof details?.displayReason === "string" && details.displayReason) {
82
+ return details.displayReason;
83
+ }
81
84
  const message = details?.error
82
85
  ?? result?.content?.find((entry: { type?: string; text?: string }) => entry.type === "text")?.text
83
86
  ?? "unknown";
@@ -424,6 +427,9 @@ export function registerDbTools(pi: ExtensionAPI): void {
424
427
  kind: StringEnum(["gsd_uat_exec", "gsd_exec", "screenshot", "log", "url", "browser"], { description: "Evidence kind" }),
425
428
  ref: Type.String({ description: "Evidence ID, approved .gsd path, or URL" }),
426
429
  note: Type.Optional(Type.String({ description: "Short evidence note" })),
430
+ unitType: Type.Optional(Type.String({ description: "Unit that produced the evidence" })),
431
+ tool: Type.Optional(Type.String({ description: "Tool that produced the evidence" })),
432
+ executionId: Type.Optional(Type.String({ description: "Stable execution or artifact id" })),
427
433
  });
428
434
 
429
435
  const uatCheck = Type.Object({
@@ -437,17 +443,17 @@ export function registerDbTools(pi: ExtensionAPI): void {
437
443
  });
438
444
 
439
445
  const toolPresentationBlock = Type.Object({
440
- surface: StringEnum(["provider-tools", "claude-code-sdk", "mcp", "hybrid"], { description: "Tool presentation surface" }),
446
+ surface: Type.Optional(StringEnum(["provider-tools", "claude-code-sdk", "mcp", "hybrid"], { description: "Tool presentation surface" })),
441
447
  model: Type.Optional(Type.Object({
442
448
  provider: Type.Optional(Type.String()),
443
449
  api: Type.Optional(Type.String()),
444
450
  id: Type.Optional(Type.String()),
445
451
  })),
446
- presentedTools: Type.Array(Type.String(), { description: "Tool names actually presented to the model" }),
447
- blockedTools: Type.Array(Type.Object({
452
+ presentedTools: Type.Optional(Type.Array(Type.String(), { description: "Tool names actually presented to the model" })),
453
+ blockedTools: Type.Optional(Type.Array(Type.Object({
448
454
  name: Type.String(),
449
455
  reason: Type.String(),
450
- }), { description: "Tool names blocked from the model with reasons" }),
456
+ }), { description: "Tool names blocked from the model with reasons" })),
451
457
  aliases: Type.Optional(Type.Array(Type.Object({
452
458
  requested: Type.String(),
453
459
  canonical: Type.String(),
@@ -471,12 +477,12 @@ export function registerDbTools(pi: ExtensionAPI): void {
471
477
  "Do not use raw gsd_summary_save as a substitute for UAT results.",
472
478
  ],
473
479
  parameters: Type.Object({
474
- milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
475
- sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
476
- uatType: StringEnum(["artifact-driven", "browser-executable", "runtime-executable", "live-runtime", "mixed", "human-experience"], { description: "Declared UAT mode" }),
477
- verdict: StringEnum(["PASS", "FAIL", "PARTIAL"], { description: "Overall UAT verdict" }),
478
- checks: Type.Array(uatCheck, { description: "Structured check results" }),
479
- presentation: toolPresentationBlock,
480
+ milestoneId: Type.Optional(Type.String({ description: "Milestone ID (e.g. M001)" })),
481
+ sliceId: Type.Optional(Type.String({ description: "Slice ID (e.g. S01)" })),
482
+ uatType: Type.Optional(Type.String({ description: "Declared UAT mode" })),
483
+ verdict: Type.Optional(Type.String({ description: "Overall UAT verdict: PASS, FAIL, or PARTIAL" })),
484
+ checks: Type.Optional(Type.Array(uatCheck, { description: "Structured check results" })),
485
+ presentation: Type.Optional(toolPresentationBlock),
480
486
  notes: Type.Optional(Type.String({ description: "Overall verdict rationale" })),
481
487
  attempt: Type.Optional(Type.String({ description: "Attempt number or auto" })),
482
488
  previousAttemptId: Type.Optional(Type.String({ description: "Prior attempt ID, when retrying" })),
@@ -832,7 +838,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
832
838
  recommendation: Type.String({ description: "Option id the executor recommends." }),
833
839
  recommendationRationale: Type.String({ description: "Why the recommendation — 1–2 sentences." }),
834
840
  continueWithDefault: Type.Boolean({
835
- description: "When true, loop continues (artifact logged for later review). When false, auto-mode pauses until the user resolves via /gsd escalate resolve.",
841
+ description: "When true, the recommendation is recorded as the default, but auto-mode still pauses until the user resolves via /gsd escalate resolve.",
836
842
  }),
837
843
  }, { description: "ADR-011 Phase 2: optional escalation payload. Only honored when phases.mid_execution_escalation is true." })),
838
844
  verificationEvidence: Type.Optional(Type.Array(
@@ -881,7 +887,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
881
887
  sliceTitle: Type.String({ description: "Title of the slice" }),
882
888
  oneLiner: Type.String({ description: "One-line summary of what the slice accomplished" }),
883
889
  narrative: Type.String({ description: "Detailed narrative of what happened across all tasks" }),
884
- verification: Type.String({ description: "What was verified across all tasks" }),
890
+ verification: Type.Optional(Type.String({ description: "What was verified across all tasks — if omitted, summary records verification as passed without detail." })),
885
891
  uatContent: Type.String({ description: "UAT test content (markdown body)" }),
886
892
  // ── Enrichment metadata (optional — defaults to empty) ────────────
887
893
  deviations: Type.Optional(Type.String({ description: "Deviations from the slice plan, or 'None.'" })),
@@ -1095,7 +1101,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
1095
1101
  promptGuidelines: [
1096
1102
  "Use gsd_validate_milestone when all slices are done and the milestone needs validation before completion.",
1097
1103
  "Parameters: milestoneId, verdict, remediationRound, successCriteriaChecklist, sliceDeliveryAudit, crossSliceIntegration, requirementCoverage, verificationClasses (optional), verdictRationale, remediationPlan (optional).",
1098
- "If verification classes were planned, verificationClasses must include canonical class rows using the exact class names Contract, Integration, Operational, and UAT when present in planning.",
1104
+ "If verification classes were planned, verificationClasses must be a complete canonical table with one row for every applicable planned class using the exact class names Contract, Integration, Operational, and UAT. Do not submit a partial table.",
1099
1105
  "Planned verification text marked as none/not required/not applicable/N/A (including suffixed variants such as 'not required - backend-only') is treated as not applicable and does not require a class row.",
1100
1106
  "If verdict is 'needs-remediation', also provide remediationPlan and use gsd_reassess_roadmap to add remediation slices to the roadmap.",
1101
1107
  "On success, returns validationPath where VALIDATION.md was written.",
@@ -1108,7 +1114,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
1108
1114
  sliceDeliveryAudit: Type.String({ description: "Markdown table auditing each slice's claimed vs delivered output" }),
1109
1115
  crossSliceIntegration: Type.String({ description: "Markdown describing any cross-slice boundary mismatches" }),
1110
1116
  requirementCoverage: Type.String({ description: "Markdown describing any unaddressed requirements" }),
1111
- verificationClasses: Type.Optional(Type.String({ description: "Markdown describing verification class compliance and gaps using canonical class names (Contract, Integration, Operational, UAT) for each applicable planned class" })),
1117
+ verificationClasses: Type.Optional(Type.String({ description: "Complete markdown table describing verification class compliance and gaps; include one canonical row for every applicable planned class (Contract, Integration, Operational, UAT)" })),
1112
1118
  verdictRationale: Type.String({ description: "Why this verdict was chosen" }),
1113
1119
  remediationPlan: Type.Optional(Type.String({ description: "Remediation plan (required if verdict is needs-remediation)" })),
1114
1120
  }),
@@ -17,7 +17,7 @@ import { canonicalToolName, clearDiscussionFlowState, isDepthConfirmationAnswer,
17
17
  import { resolveManifest } from "../unit-context-manifest.js";
18
18
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
19
19
  import { loadFile, saveFile, formatContinue } from "../files.js";
20
- import { clearToolInvocationError, getAutoRuntimeSnapshot, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
20
+ import { clearToolInvocationError, getAutoRuntimeSnapshot, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
21
21
 
22
22
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
23
23
  import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
@@ -38,7 +38,7 @@ import { getGuidedUnitContext } from "../guided-unit-context.js";
38
38
  import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
39
39
  import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
40
40
  import { filterToolsForProvider } from "../model-router.js";
41
- import { RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
41
+ import { RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
42
42
 
43
43
  let approvalQuestionAbortInFlight = false;
44
44
 
@@ -252,7 +252,12 @@ export function buildRunUatGsdToolSet(
252
252
  ): string[] {
253
253
  const scoped = resolveScopedToolNames(
254
254
  [...activeToolNames, ...registeredToolNames],
255
- [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent", ...RUN_UAT_BROWSER_TOOL_NAMES],
255
+ [
256
+ ...RUN_UAT_WORKFLOW_TOOL_NAMES,
257
+ ...RUN_UAT_READ_ONLY_TOOL_NAMES,
258
+ "subagent",
259
+ ...RUN_UAT_BROWSER_TOOL_NAMES,
260
+ ],
256
261
  );
257
262
  return [...new Set(scoped)];
258
263
  }
@@ -480,22 +485,30 @@ function isContextDraftSummarySave(toolName: string, input: unknown): boolean {
480
485
  return (input as { artifact_type?: unknown }).artifact_type === "CONTEXT-DRAFT";
481
486
  }
482
487
 
488
+ function withDepthGateDisplayReason<T extends { block: boolean; reason?: string }>(
489
+ result: T,
490
+ displayReason = "Depth confirmation is waiting for your answer.",
491
+ ): T & { displayReason?: string } {
492
+ if (!result.block) return result;
493
+ return { ...result, displayReason };
494
+ }
495
+
483
496
  function shouldBlockDeferredApprovalTool(
484
497
  toolName: string,
485
498
  input: unknown,
486
499
  basePath: string,
487
- ): { block: boolean; reason?: string } {
500
+ ): { block: boolean; reason?: string; displayReason?: string } {
488
501
  if (deferredApprovalGate?.basePath !== basePath) return { block: false };
489
502
  if (toolName === "ask_user_questions") return { block: false };
490
503
  if (isContextDraftSummarySave(toolName, input)) return { block: false };
491
- return {
504
+ return withDepthGateDisplayReason({
492
505
  block: true,
493
506
  reason: [
494
507
  `HARD BLOCK: Approval question "${deferredApprovalGate.gateId}" has been shown to the user.`,
495
508
  `Only CONTEXT-DRAFT persistence may finish in this same assistant turn.`,
496
509
  `Wait for the user's answer before calling additional tools.`,
497
510
  ].join(" "),
498
- };
511
+ });
499
512
  }
500
513
 
501
514
  export function resolveNotificationStoreBasePath(basePath: string): string {
@@ -535,8 +548,9 @@ export function registerHooks(
535
548
 
536
549
  pi.on("session_start", async (_event, ctx) => {
537
550
  const basePath = contextBasePath(ctx);
551
+ const preserveCloseoutSurface = isAutoCompletionStopInProgress();
538
552
  initSessionNotifications(ctx);
539
- if (!isAutoActive()) {
553
+ if (!isAutoActive() && !preserveCloseoutSurface) {
540
554
  const { initHealthWidget } = await import("../health-widget.js");
541
555
  initHealthWidget(ctx);
542
556
  }
@@ -556,15 +570,18 @@ export function registerHooks(
556
570
  const prefs = loadEffectiveGSDPreferences(basePath);
557
571
  process.env.GSD_SHOW_TOKEN_COST = prefs?.preferences.show_token_cost ? "1" : "";
558
572
  } catch { /* non-fatal */ }
559
- await installWelcomeHeader(ctx);
573
+ if (!preserveCloseoutSurface) {
574
+ await installWelcomeHeader(ctx);
575
+ }
560
576
  await loadToolApiKeysForSession();
561
- if (isAutoActive()) {
577
+ if (isAutoActive() || preserveCloseoutSurface) {
562
578
  ctx.ui.setWidget("gsd-health", undefined);
563
579
  }
564
580
  });
565
581
 
566
582
  pi.on("session_switch", async (_event, ctx) => {
567
583
  const basePath = contextBasePath(ctx);
584
+ const preserveCloseoutSurface = isAutoCompletionStopInProgress();
568
585
  initSessionNotifications(ctx);
569
586
  resetWriteGateState(basePath);
570
587
  resetToolCallLoopGuard();
@@ -576,7 +593,7 @@ export function registerHooks(
576
593
  await applyCompactionThresholdOverride(ctx);
577
594
  await prepareWorkflowMcpForHookContext(ctx, basePath);
578
595
  await loadToolApiKeysForSession();
579
- if (!isAutoActive()) {
596
+ if (!isAutoActive() && !preserveCloseoutSurface) {
580
597
  ctx.ui.setWidget("gsd-progress", undefined);
581
598
  ctx.ui.setWidget("gsd-outcome", undefined);
582
599
  const { initHealthWidget } = await import("../health-widget.js");
@@ -913,7 +930,7 @@ export function registerHooks(
913
930
  "Depth confirmation is waiting for your answer — pausing auto-mode.",
914
931
  );
915
932
  }
916
- return bashGuard;
933
+ return withDepthGateDisplayReason(bashGuard);
917
934
  }
918
935
  } else {
919
936
  const gateGuard = shouldBlockPendingGate(
@@ -931,7 +948,7 @@ export function registerHooks(
931
948
  "Depth confirmation is waiting for your answer — pausing auto-mode.",
932
949
  );
933
950
  }
934
- return gateGuard;
951
+ return withDepthGateDisplayReason(gateGuard);
935
952
  }
936
953
  }
937
954
  }
@@ -1036,7 +1053,9 @@ export function registerHooks(
1036
1053
  isQueuePhaseActive(discussionBasePath),
1037
1054
  discussionBasePath,
1038
1055
  );
1039
- if (result.block) return result;
1056
+ if (result.block) {
1057
+ return withDepthGateDisplayReason(result, "Depth check required before writing milestone context.");
1058
+ }
1040
1059
  });
1041
1060
 
1042
1061
  // ── Safety harness: evidence collection + destructive command blocking ──