@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.b1abb545

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 (375) hide show
  1. package/dist/cli-web-branch.d.ts +2 -0
  2. package/dist/cli-web-branch.js +9 -2
  3. package/dist/help-text.js +5 -0
  4. package/dist/resources/.managed-resources-content-hash +1 -1
  5. package/dist/resources/extensions/ask-user-questions.js +78 -23
  6. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +84 -228
  7. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
  8. package/dist/resources/extensions/github-sync/templates.js +3 -3
  9. package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
  10. package/dist/resources/extensions/gsd/auto/loop.js +74 -56
  11. package/dist/resources/extensions/gsd/auto/orchestrator.js +109 -11
  12. package/dist/resources/extensions/gsd/auto/phases.js +28 -3
  13. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
  14. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  15. package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
  17. package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
  19. package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
  20. package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
  21. package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
  22. package/dist/resources/extensions/gsd/auto-start.js +12 -23
  23. package/dist/resources/extensions/gsd/auto-timers.js +16 -2
  24. package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
  25. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
  26. package/dist/resources/extensions/gsd/auto-verification.js +7 -7
  27. package/dist/resources/extensions/gsd/auto-worktree.js +21 -19
  28. package/dist/resources/extensions/gsd/auto.js +11 -7
  29. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
  30. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +11 -37
  31. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +100 -138
  33. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +63 -4
  34. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
  35. package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
  36. package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
  37. package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
  38. package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
  39. package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
  40. package/dist/resources/extensions/gsd/commands-ship.js +2 -2
  41. package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
  42. package/dist/resources/extensions/gsd/db-workspace.js +103 -0
  43. package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
  44. package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
  45. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  46. package/dist/resources/extensions/gsd/doctor.js +16 -9
  47. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  48. package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
  49. package/dist/resources/extensions/gsd/gsd-db.js +12 -0
  50. package/dist/resources/extensions/gsd/guided-flow.js +34 -468
  51. package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
  52. package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
  53. package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
  54. package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
  55. package/dist/resources/extensions/gsd/md-importer.js +4 -3
  56. package/dist/resources/extensions/gsd/migrate/safety.js +2 -2
  57. package/dist/resources/extensions/gsd/migration-auto-check.js +3 -2
  58. package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
  59. package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
  60. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
  61. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
  62. package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
  63. package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
  64. package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
  65. package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
  66. package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
  67. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
  68. package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
  69. package/dist/resources/extensions/gsd/preferences.js +147 -29
  70. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  71. package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
  72. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  73. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  74. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  75. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  76. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  77. package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
  78. package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
  79. package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
  80. package/dist/resources/extensions/gsd/question-transport.js +86 -0
  81. package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
  83. package/dist/resources/extensions/gsd/state.js +13 -5
  84. package/dist/resources/extensions/gsd/templates/plan.md +7 -0
  85. package/dist/resources/extensions/gsd/templates/project.md +1 -0
  86. package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
  87. package/dist/resources/extensions/gsd/templates/uat.md +5 -1
  88. package/dist/resources/extensions/gsd/tool-contract.js +52 -8
  89. package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
  90. package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
  91. package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
  92. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
  93. package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
  94. package/dist/resources/extensions/gsd/uat-policy.js +16 -10
  95. package/dist/resources/extensions/gsd/uat-run.js +9 -14
  96. package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
  97. package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
  98. package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
  99. package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
  100. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  101. package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
  102. package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
  103. package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
  104. package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
  105. package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
  106. package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
  107. package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
  108. package/dist/resources/extensions/shared/interview-ui.js +2 -2
  109. package/dist/resources/shared/claude-runtime-floor.js +182 -0
  110. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  111. package/dist/update-cmd.js +20 -0
  112. package/dist/web/standalone/.next/BUILD_ID +1 -1
  113. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  114. package/dist/web/standalone/.next/build-manifest.json +3 -3
  115. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  116. package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
  117. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/index.html +1 -1
  134. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  141. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  142. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  145. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  146. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  147. package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
  148. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
  149. package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
  150. package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
  151. package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
  152. package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
  153. package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
  154. package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
  155. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  156. package/dist/web-mode.d.ts +2 -0
  157. package/dist/web-mode.js +20 -8
  158. package/package.json +2 -1
  159. package/packages/cloud-mcp-gateway/package.json +2 -2
  160. package/packages/contracts/package.json +1 -1
  161. package/packages/daemon/package.json +4 -4
  162. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
  163. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  164. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
  165. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  166. package/packages/gsd-agent-core/package.json +5 -5
  167. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  168. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
  169. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  170. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  171. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
  172. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  173. package/packages/gsd-agent-modes/package.json +7 -7
  174. package/packages/mcp-server/dist/server.d.ts +10 -0
  175. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  176. package/packages/mcp-server/dist/server.js +8 -0
  177. package/packages/mcp-server/dist/server.js.map +1 -1
  178. package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
  179. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  180. package/packages/mcp-server/dist/workflow-tools.js +2 -1
  181. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  182. package/packages/mcp-server/package.json +3 -3
  183. package/packages/native/package.json +1 -1
  184. package/packages/pi-agent-core/package.json +1 -1
  185. package/packages/pi-ai/dist/models.generated.d.ts +8 -93
  186. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  187. package/packages/pi-ai/dist/models.generated.js +35 -120
  188. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  189. package/packages/pi-ai/package.json +1 -1
  190. package/packages/pi-coding-agent/package.json +7 -7
  191. package/packages/pi-tui/dist/components/input.js +1 -1
  192. package/packages/pi-tui/dist/components/input.js.map +1 -1
  193. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  194. package/packages/pi-tui/dist/keys.js +39 -30
  195. package/packages/pi-tui/dist/keys.js.map +1 -1
  196. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  197. package/packages/pi-tui/dist/stdin-buffer.js +22 -0
  198. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  199. package/packages/pi-tui/package.json +2 -2
  200. package/packages/rpc-client/package.json +2 -2
  201. package/pkg/package.json +1 -1
  202. package/src/resources/extensions/ask-user-questions.ts +87 -24
  203. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +108 -281
  204. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +240 -0
  205. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
  206. package/src/resources/extensions/github-sync/templates.ts +3 -3
  207. package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
  208. package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
  209. package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
  210. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
  211. package/src/resources/extensions/gsd/auto/loop.ts +83 -61
  212. package/src/resources/extensions/gsd/auto/orchestrator.ts +125 -12
  213. package/src/resources/extensions/gsd/auto/phases.ts +35 -3
  214. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
  215. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  216. package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
  217. package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
  218. package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
  219. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -3
  220. package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
  221. package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
  222. package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
  223. package/src/resources/extensions/gsd/auto-start.ts +17 -20
  224. package/src/resources/extensions/gsd/auto-timers.ts +16 -2
  225. package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
  226. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
  227. package/src/resources/extensions/gsd/auto-verification.ts +7 -8
  228. package/src/resources/extensions/gsd/auto-worktree.ts +33 -26
  229. package/src/resources/extensions/gsd/auto.ts +15 -8
  230. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
  231. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +10 -37
  232. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  233. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +116 -151
  234. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +107 -3
  235. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
  236. package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
  237. package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
  238. package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
  239. package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
  240. package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
  241. package/src/resources/extensions/gsd/commands-ship.ts +2 -2
  242. package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
  243. package/src/resources/extensions/gsd/db-workspace.ts +170 -0
  244. package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
  245. package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
  246. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  247. package/src/resources/extensions/gsd/doctor.ts +15 -5
  248. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  249. package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
  250. package/src/resources/extensions/gsd/gsd-db.ts +12 -0
  251. package/src/resources/extensions/gsd/guided-flow.ts +47 -558
  252. package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
  253. package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
  254. package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
  255. package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
  256. package/src/resources/extensions/gsd/md-importer.ts +3 -3
  257. package/src/resources/extensions/gsd/migrate/safety.ts +2 -2
  258. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  259. package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
  260. package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
  261. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
  262. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
  263. package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
  264. package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
  265. package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
  266. package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
  267. package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
  268. package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
  269. package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
  270. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  271. package/src/resources/extensions/gsd/preferences.ts +173 -28
  272. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  273. package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
  274. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  275. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  276. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  277. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  278. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  279. package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
  280. package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
  281. package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
  282. package/src/resources/extensions/gsd/question-transport.ts +138 -0
  283. package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
  284. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
  285. package/src/resources/extensions/gsd/state.ts +15 -5
  286. package/src/resources/extensions/gsd/templates/plan.md +7 -0
  287. package/src/resources/extensions/gsd/templates/project.md +1 -0
  288. package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
  289. package/src/resources/extensions/gsd/templates/uat.md +5 -1
  290. package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
  291. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
  292. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +321 -5
  293. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
  294. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
  295. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
  296. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
  297. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
  298. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  299. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
  300. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
  301. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
  302. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
  303. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
  304. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
  305. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
  306. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
  307. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
  308. package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
  309. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +58 -0
  310. package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
  311. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
  312. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
  313. package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
  314. package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
  315. package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
  316. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
  317. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  318. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
  319. package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
  320. package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
  321. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
  322. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
  323. package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
  324. package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
  325. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +94 -0
  326. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
  327. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
  328. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
  329. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +101 -1
  330. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
  331. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
  332. package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
  333. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
  334. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
  335. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
  336. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
  337. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
  338. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
  339. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
  340. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
  341. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +21 -0
  342. package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
  343. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
  344. package/src/resources/extensions/gsd/tests/write-gate.test.ts +79 -0
  345. package/src/resources/extensions/gsd/tool-contract.ts +86 -8
  346. package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
  347. package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
  348. package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
  349. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
  350. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
  351. package/src/resources/extensions/gsd/uat-policy.ts +19 -10
  352. package/src/resources/extensions/gsd/uat-run.ts +10 -14
  353. package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
  354. package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
  355. package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
  356. package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
  357. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  358. package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
  359. package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
  360. package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
  361. package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
  362. package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
  363. package/src/resources/extensions/gsd/worktree-lifecycle.ts +7 -16
  364. package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
  365. package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
  366. package/src/resources/extensions/shared/interview-ui.ts +15 -2
  367. package/src/resources/shared/claude-runtime-floor.ts +248 -0
  368. package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
  369. package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
  370. package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
  371. package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
  372. package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
  373. package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
  374. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → 3PtrU9qGPEXwNLWkIyiqk}/_buildManifest.js +0 -0
  375. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → 3PtrU9qGPEXwNLWkIyiqk}/_ssgManifest.js +0 -0
@@ -44,6 +44,8 @@ import {
44
44
  import { logWarning } from "./workflow-logger.js";
45
45
  import { formattedShortcutPair } from "./shortcut-defs.js";
46
46
  import { readUnitRuntimeRecord, type AutoUnitRuntimeRecord } from "./unit-runtime.js";
47
+ import { describeMilestoneReadinessPhase } from "./milestone-readiness.js";
48
+ import type { ToolSurfaceSnapshot } from "./tool-surface-snapshot.js";
47
49
 
48
50
  const ACTIVE_SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"] as const;
49
51
 
@@ -85,6 +87,8 @@ export interface AutoDashboardData {
85
87
  rtkEnabled?: boolean;
86
88
  /** Cross-process: another auto-mode session detected via auto.lock (PID, startedAt) */
87
89
  remoteSession?: { pid: number; startedAt: string; unitType: string; unitId: string };
90
+ /** Last typed tool-surface snapshot for active auto-mode scoping/debugging. */
91
+ toolSurface?: ToolSurfaceSnapshot | null;
88
92
  }
89
93
 
90
94
  export interface CompletionDashboardSnapshot {
@@ -189,6 +193,18 @@ export function unitPhaseLabel(unitType: string): string {
189
193
  }
190
194
  }
191
195
 
196
+ export function formatToolSurfaceSnapshot(snapshot: ToolSurfaceSnapshot | null | undefined): string | null {
197
+ if (!snapshot) return null;
198
+ const counts = [
199
+ `model ${snapshot.modelFacingToolNames.length}`,
200
+ `registered ${snapshot.registeredToolNames.length}`,
201
+ `scoped ${snapshot.scopedToolNames.length}`,
202
+ `presented ${snapshot.presentedToolNames.length}`,
203
+ ];
204
+ const label = snapshot.unitType ?? snapshot.phase ?? snapshot.source;
205
+ return `${label}: ${counts.join(" / ")}`;
206
+ }
207
+
192
208
  function peekNext(unitType: string, state: GSDState): string {
193
209
  // Show active hook info in progress display
194
210
  const activeHookState = getActiveHook();
@@ -224,12 +240,10 @@ export function describeNextUnit(state: GSDState): { label: string; description:
224
240
  const sTitle = state.activeSlice?.title;
225
241
  const tid = state.activeTask?.id;
226
242
  const tTitle = state.activeTask?.title;
243
+ const readinessDescription = describeMilestoneReadinessPhase(state.phase);
244
+ if (readinessDescription) return readinessDescription;
227
245
 
228
246
  switch (state.phase) {
229
- case "needs-discussion":
230
- return { label: "Discuss milestone draft", description: "Milestone has a draft context — needs discussion before planning." };
231
- case "pre-planning":
232
- return { label: "Research & plan milestone", description: "Scout the landscape and create the roadmap." };
233
247
  case "planning":
234
248
  return { label: `Plan ${sid}: ${sTitle}`, description: "Research and decompose into tasks." };
235
249
  case "executing":
@@ -112,9 +112,9 @@ import { runTurnGitAction } from "./git-service.js";
112
112
  import { parseUnitId } from "./unit-id.js";
113
113
  import { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
114
114
  import {
115
- checkCloseoutConsistencyGate,
116
- formatCloseoutConsistencyBlock,
117
- } from "./closeout-consistency-gate.js";
115
+ formatCloseoutProofBlock,
116
+ proveMilestoneCloseout,
117
+ } from "./milestone-closeout-proof.js";
118
118
 
119
119
  // ─── Types ────────────────────────────────────────────────────────────────
120
120
 
@@ -153,6 +153,8 @@ export interface DispatchContext {
153
153
  sessionProvider?: string;
154
154
  /** Active tools in the current session, used for transport preflight checks. */
155
155
  activeTools?: string[];
156
+ /** Registered tools in the current session, used for run-uat tools re-scoped at dispatch. */
157
+ registeredTools?: string[];
156
158
  /** Session model base URL, used for transport preflight checks. */
157
159
  sessionBaseUrl?: string;
158
160
  /** Session model auth mode, used for transport preflight checks. */
@@ -734,7 +736,17 @@ export const DISPATCH_RULES: DispatchRule[] = [
734
736
  },
735
737
  {
736
738
  name: "run-uat (post-completion)",
737
- match: async ({ state, mid, basePath, prefs, sessionProvider, sessionAuthMode, activeTools, sessionBaseUrl }) => {
739
+ match: async ({
740
+ state,
741
+ mid,
742
+ basePath,
743
+ prefs,
744
+ sessionProvider,
745
+ sessionAuthMode,
746
+ activeTools,
747
+ registeredTools,
748
+ sessionBaseUrl,
749
+ }) => {
738
750
  const needsRunUat = await checkNeedsRunUat(basePath, mid, state, prefs);
739
751
  if (!needsRunUat) return null;
740
752
  const { sliceId, uatType } = needsRunUat;
@@ -753,6 +765,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
753
765
  const browserToolError = getUatBrowserToolSupportError({
754
766
  uatType,
755
767
  activeTools,
768
+ registeredTools,
756
769
  milestoneId: mid,
757
770
  sliceId,
758
771
  });
@@ -1745,11 +1758,11 @@ export const DISPATCH_RULES: DispatchRule[] = [
1745
1758
  };
1746
1759
  }
1747
1760
  if (milestone) {
1748
- const closeoutGate = checkCloseoutConsistencyGate(mid, { refreshFromDisk: true });
1749
- if (!closeoutGate.ok) {
1761
+ const closeoutProof = proveMilestoneCloseout(mid, { refreshFromDisk: true });
1762
+ if (!closeoutProof.ok) {
1750
1763
  return {
1751
1764
  action: "stop",
1752
- reason: formatCloseoutConsistencyBlock(closeoutGate),
1765
+ reason: formatCloseoutProofBlock(closeoutProof),
1753
1766
  level: "warning",
1754
1767
  };
1755
1768
  }
@@ -122,6 +122,14 @@ export function getToolBaselineSnapshot(pi: ExtensionAPI): string[] {
122
122
  return [...new Set([...baseline, ...live])];
123
123
  }
124
124
 
125
+ export function getRegisteredToolSnapshot(pi: ExtensionAPI): string[] {
126
+ if (typeof pi.getAllTools !== "function") return getToolBaselineSnapshot(pi);
127
+ const names = pi.getAllTools()
128
+ .map((tool) => tool.name)
129
+ .filter((name): name is string => typeof name === "string" && name.length > 0);
130
+ return [...new Set(names)];
131
+ }
132
+
125
133
  /**
126
134
  * Models eligible for the pre-dispatch policy gate. Prefer registry-available
127
135
  * models; when that list is empty (common after worktree resume before registry
@@ -49,7 +49,8 @@ import { regenerateIfMissing } from "./workflow-projections.js";
49
49
  import { WorktreeStateProjection } from "./worktree-state-projection.js";
50
50
  import { createWorkspace, scopeMilestone } from "./workspace.js";
51
51
  import { normalizeWorktreePathForCompare } from "./worktree-root.js";
52
- import { isDbAvailable, getDbPath, refreshOpenDatabaseFromDisk, getTask, getSlice, getMilestone, getMilestoneSlices, updateTaskStatus, _getAdapter, getVerificationEvidence } from "./gsd-db.js";
52
+ import { isDbAvailable, getTask, getSlice, getMilestone, getMilestoneSlices, updateTaskStatus, _getAdapter, getVerificationEvidence } from "./gsd-db.js";
53
+ import { getWorkflowDatabasePath, refreshWorkflowDatabaseFromDisk } from "./db-workspace.js";
53
54
  import { renderPlanCheckboxes, renderRoadmapFromDb } from "./markdown-renderer.js";
54
55
  import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
55
56
  import { consumeSignal } from "./session-status-io.js";
@@ -1273,9 +1274,9 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
1273
1274
  await new Promise(r => setTimeout(r, 100));
1274
1275
  }
1275
1276
 
1276
- const dbPath = getDbPath();
1277
+ const dbPath = getWorkflowDatabasePath();
1277
1278
  if (isDbAvailable() && dbPath && dbPath !== ":memory:") {
1278
- const refreshed = refreshOpenDatabaseFromDisk();
1279
+ const refreshed = refreshWorkflowDatabaseFromDisk();
1279
1280
  if (!refreshed) {
1280
1281
  logWarning("db", "post-unit database refresh failed; derived state may be stale");
1281
1282
  }
@@ -36,8 +36,18 @@ import {
36
36
  } from "./gate-registry.js";
37
37
  import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
38
38
  import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
39
- import { composeContextModeInstructions, composeInlinedContext, composeUnitContext, type ArtifactResolver, type ContextModeRenderMode, type ExcerptResolver } from "./unit-context-composer.js";
40
- import { resolveManifest } from "./unit-context-manifest.js";
39
+ import {
40
+ composeContextModeInstructions,
41
+ composeContractedUnitContext,
42
+ composeInlinedContext,
43
+ composeUnitContext,
44
+ type ArtifactResolver,
45
+ type ComposedUnitContextBlock,
46
+ type ContextModeRenderMode,
47
+ type ExcerptResolver,
48
+ } from "./unit-context-composer.js";
49
+ import { resolveManifest, type ArtifactKey } from "./unit-context-manifest.js";
50
+ import { compileUnitContextContract, type UnitPromptContextContract } from "./tool-contract.js";
41
51
  import { readCompactionSnapshot } from "./compaction-snapshot.js";
42
52
  import { logWarning } from "./workflow-logger.js";
43
53
  import { inlineGraphSubgraph } from "./graph-context.js";
@@ -48,6 +58,7 @@ import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-acti
48
58
  import { findMilestoneIds } from "./milestone-ids.js";
49
59
  import { buildRunUatPresentationForType, RUN_UAT_TOOL_PRESENTATION_PLAN_ID } from "./tool-presentation-plan.js";
50
60
  import { resolveEffectiveUatType, shouldDispatchUatForContent, type UatType } from "./uat-policy.js";
61
+ import { buildWebAppUatGuidanceBlock } from "./web-app-uat.js";
51
62
 
52
63
  export { buildSkillActivationBlock, buildSkillDiscoveryVars };
53
64
 
@@ -287,6 +298,39 @@ function prependContextModeToBlock(
287
298
  return `${contextMode}\n\n${block}`;
288
299
  }
289
300
 
301
+ function requireUnitPromptContextContract(unitType: string): UnitPromptContextContract {
302
+ const result = compileUnitContextContract(unitType);
303
+ if (result.ok) return result.contract;
304
+ throw new Error(result.detail);
305
+ }
306
+
307
+ function requireComposedArtifactBlock(
308
+ blocks: readonly ComposedUnitContextBlock[],
309
+ unitType: string,
310
+ key: ArtifactKey,
311
+ ): string {
312
+ const block = blocks.find((item) => item.key === key);
313
+ if (!block) {
314
+ throw new Error(`Unit Context Contract for ${unitType} did not compose required artifact ${key}`);
315
+ }
316
+ return block.body;
317
+ }
318
+
319
+ function renderExecuteTaskOnDemandContext(
320
+ base: string,
321
+ mid: string,
322
+ sid: string,
323
+ artifacts: readonly ArtifactKey[],
324
+ ): string {
325
+ if (!artifacts.includes("slice-research")) return "";
326
+ const researchPath = relSliceFile(base, mid, sid, "RESEARCH");
327
+ return [
328
+ "## On-demand Context",
329
+ "",
330
+ `Slice research is available at \`${researchPath}\`. Read it only if the inlined task plan, slice plan excerpt, and carry-forward context do not explain a required implementation detail.`,
331
+ ].join("\n");
332
+ }
333
+
290
334
  // ─── Executor Constraints ─────────────────────────────────────────────────────
291
335
 
292
336
  /**
@@ -1976,6 +2020,12 @@ export async function buildPlanMilestonePrompt(mid: string, midTitle: string, ba
1976
2020
  } else {
1977
2021
  trackPromptContext(contextTelemetry, "knowledge", "skipped", null, "missing");
1978
2022
  }
2023
+ const webAppUatGuidance = buildWebAppUatGuidanceBlock(base);
2024
+ if (webAppUatGuidance) {
2025
+ pushTracked("web-app-uat", webAppUatGuidance);
2026
+ } else {
2027
+ trackPromptContext(contextTelemetry, "web-app-uat", "skipped", null, "not a web app");
2028
+ }
1979
2029
  pushTracked("templates", inlineTemplate("roadmap", "Roadmap"));
1980
2030
  if (inlineLevel === "full") {
1981
2031
  pushTracked("templates", inlineTemplate("decisions", "Decisions"));
@@ -2306,6 +2356,14 @@ async function renderSlicePrompt(options: {
2306
2356
  trackPromptContext(contextTelemetry, "graph-subgraph", "skipped", null, "missing");
2307
2357
  }
2308
2358
 
2359
+ const webAppUatGuidance = buildWebAppUatGuidanceBlock(base);
2360
+ if (webAppUatGuidance) {
2361
+ inlined.push(webAppUatGuidance);
2362
+ trackPromptContext(contextTelemetry, "web-app-uat", "inline", webAppUatGuidance);
2363
+ } else {
2364
+ trackPromptContext(contextTelemetry, "web-app-uat", "skipped", null, "not a web app");
2365
+ }
2366
+
2309
2367
  const planTemplateInline = level === "minimal" ? inlineCompactTemplate("plan", "Slice Plan") : inlineTemplate("plan", "Slice Plan");
2310
2368
  inlined.push(planTemplateInline);
2311
2369
  trackPromptContext(contextTelemetry, "templates", "inline", planTemplateInline);
@@ -2510,7 +2568,7 @@ export async function buildExecuteTaskPrompt(
2510
2568
  const taskPlanPath = resolveTaskFile(base, mid, sid, tid, "PLAN");
2511
2569
  const taskPlanContent = taskPlanPath ? await loadFile(taskPlanPath) : null;
2512
2570
  const taskPlanRelPath = relSlicePath(base, mid, sid) + `/tasks/${tid}-PLAN.md`;
2513
- const taskPlanInline = taskPlanContent
2571
+ const taskPlanContext = taskPlanContent
2514
2572
  ? [
2515
2573
  "## Inlined Task Plan (authoritative local execution contract)",
2516
2574
  `Source: \`${taskPlanRelPath}\``,
@@ -2521,12 +2579,12 @@ export async function buildExecuteTaskPrompt(
2521
2579
  "## Inlined Task Plan (authoritative local execution contract)",
2522
2580
  `Task plan not found at dispatch time. Read \`${taskPlanRelPath}\` before executing.`,
2523
2581
  ].join("\n");
2524
- trackPromptContext(contextTelemetry, "task-plan", taskPlanContent ? "inline" : "on-demand", taskPlanInline, taskPlanContent ? undefined : "missing at dispatch");
2582
+ trackPromptContext(contextTelemetry, "task-plan", taskPlanContent ? "inline" : "on-demand", taskPlanContext, taskPlanContent ? undefined : "missing at dispatch");
2525
2583
 
2526
2584
  const slicePlanPath = resolveSliceFile(base, mid, sid, "PLAN");
2527
2585
  const slicePlanContent = slicePlanPath ? await loadFile(slicePlanPath) : null;
2528
- const slicePlanExcerpt = extractSliceExecutionExcerpt(slicePlanContent, relSliceFile(base, mid, sid, "PLAN"));
2529
- trackPromptContext(contextTelemetry, "slice-plan", slicePlanExcerpt ? "excerpt" : "skipped", slicePlanExcerpt, slicePlanExcerpt ? undefined : "missing");
2586
+ const slicePlanContext = extractSliceExecutionExcerpt(slicePlanContent, relSliceFile(base, mid, sid, "PLAN"));
2587
+ trackPromptContext(contextTelemetry, "slice-plan", slicePlanContext ? "excerpt" : "skipped", slicePlanContext, slicePlanContext ? undefined : "missing");
2530
2588
 
2531
2589
  // Check for continue file (new naming or legacy)
2532
2590
  const continueFile = resolveSliceFile(base, mid, sid, "CONTINUE");
@@ -2657,6 +2715,37 @@ export async function buildExecuteTaskPrompt(
2657
2715
  }
2658
2716
  trackPromptContext(contextTelemetry, "templates", "inline", inlinedTemplates, inlineLevel);
2659
2717
 
2718
+ const contextContract = requireUnitPromptContextContract("execute-task");
2719
+ const contractedContext = await composeContractedUnitContext(contextContract, {
2720
+ base: { unitType: "execute-task", basePath: base, milestoneId: mid, sliceId: sid, taskId: tid },
2721
+ resolveArtifact: async (key) => {
2722
+ switch (key) {
2723
+ case "task-plan":
2724
+ return taskPlanContext;
2725
+ case "slice-plan":
2726
+ return slicePlanContext;
2727
+ case "prior-task-summaries":
2728
+ return finalCarryForward;
2729
+ case "templates":
2730
+ return inlinedTemplates;
2731
+ default:
2732
+ return null;
2733
+ }
2734
+ },
2735
+ });
2736
+ const taskPlanInline = requireComposedArtifactBlock(contractedContext.blocks, "execute-task", "task-plan");
2737
+ const slicePlanExcerpt = requireComposedArtifactBlock(contractedContext.blocks, "execute-task", "slice-plan");
2738
+ const contractedCarryForward = requireComposedArtifactBlock(contractedContext.blocks, "execute-task", "prior-task-summaries");
2739
+ const contractedTemplates = requireComposedArtifactBlock(contractedContext.blocks, "execute-task", "templates");
2740
+ const onDemandContext = renderExecuteTaskOnDemandContext(base, mid, sid, contractedContext.onDemand);
2741
+ trackPromptContext(
2742
+ contextTelemetry,
2743
+ "slice-research",
2744
+ onDemandContext ? "on-demand" : "skipped",
2745
+ onDemandContext,
2746
+ onDemandContext ? undefined : "not declared by contract",
2747
+ );
2748
+
2660
2749
  const prompt = loadPrompt("execute-task", {
2661
2750
  overridesSection,
2662
2751
  runtimeContext,
@@ -2668,11 +2757,12 @@ export async function buildExecuteTaskPrompt(
2668
2757
  taskPlanPath: taskPlanRelPath,
2669
2758
  taskPlanInline,
2670
2759
  slicePlanExcerpt,
2671
- carryForwardSection: finalCarryForward,
2760
+ carryForwardSection: contractedCarryForward,
2672
2761
  resumeSection,
2673
2762
  priorTaskLines: priorLines,
2763
+ onDemandContext,
2674
2764
  taskSummaryPath,
2675
- inlinedTemplates,
2765
+ inlinedTemplates: contractedTemplates,
2676
2766
  verificationBudget,
2677
2767
  gatesToClose,
2678
2768
  skillActivation: buildSkillActivationBlock({
@@ -2683,7 +2773,7 @@ export async function buildExecuteTaskPrompt(
2683
2773
  taskId: tid,
2684
2774
  taskTitle: tTitle,
2685
2775
  taskPlanContent,
2686
- extraContext: [taskPlanInline, slicePlanExcerpt, finalCarryForward, resumeSection],
2776
+ extraContext: [taskPlanInline, slicePlanExcerpt, contractedCarryForward, resumeSection],
2687
2777
  unitType: "execute-task",
2688
2778
  }),
2689
2779
  });
@@ -2803,6 +2893,14 @@ export async function buildCompleteSlicePrompt(
2803
2893
  }
2804
2894
  }
2805
2895
 
2896
+ const webAppUatGuidance = buildWebAppUatGuidanceBlock(base);
2897
+ if (webAppUatGuidance && body) {
2898
+ body = `${webAppUatGuidance}\n\n---\n\n${body}`;
2899
+ trackPromptContext(contextTelemetry, "web-app-uat", "inline", webAppUatGuidance);
2900
+ } else {
2901
+ trackPromptContext(contextTelemetry, "web-app-uat", "skipped", null, webAppUatGuidance ? "missing composed body" : "not a web app");
2902
+ }
2903
+
2806
2904
  // Overrides section prepends to the top of the inlined context —
2807
2905
  // standard pattern for slice-level builders (until composer v2 lands
2808
2906
  // the prepend contract).
@@ -25,15 +25,13 @@ import {
25
25
  updateSliceStatus,
26
26
  insertSlice,
27
27
  getMilestone,
28
- getMilestoneSlices,
29
- getLatestAssessmentByScope,
30
28
  updateMilestoneStatus,
31
- refreshOpenDatabaseFromDisk,
32
29
  getCompletedMilestoneTaskFileHints,
33
30
  getMilestoneCommitAttributionShas,
34
31
  recordMilestoneCommitAttribution,
35
32
  transaction,
36
33
  } from "./gsd-db.js";
34
+ import { refreshWorkflowDatabaseFromDisk } from "./db-workspace.js";
37
35
  import { isValidationTerminal } from "./state.js";
38
36
  import { getErrorMessage } from "./error-utils.js";
39
37
  import { logWarning, logError } from "./workflow-logger.js";
@@ -72,7 +70,10 @@ import { isGsdWorktreePath } from "./worktree-root.js";
72
70
  import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
73
71
  import { hasImplementationArtifacts } from "./milestone-implementation-evidence.js";
74
72
  import { loadAllCaptures, loadPendingCaptures } from "./captures.js";
75
- import { checkCloseoutConsistencyGate } from "./closeout-consistency-gate.js";
73
+ import {
74
+ proveMilestoneCloseout,
75
+ type CloseoutProofFailureReason,
76
+ } from "./milestone-closeout-proof.js";
76
77
 
77
78
  // Re-export so existing consumers of auto-recovery.ts keep working.
78
79
  export { resolveExpectedArtifactPath, diagnoseExpectedArtifact };
@@ -117,6 +118,19 @@ export type ArtifactRecoveryDbRefreshResult =
117
118
  | { ok: true }
118
119
  | { ok: false; fatal: boolean; message: string; reason: string };
119
120
 
121
+ function closeoutProofRecoveryReason(reason: CloseoutProofFailureReason): string {
122
+ switch (reason) {
123
+ case "slice-missing":
124
+ return "complete-milestone-slices-missing";
125
+ case "summary-artifact-missing":
126
+ return "complete-milestone-summary-missing";
127
+ case "summary-artifact-failed":
128
+ return "complete-milestone-summary-failed";
129
+ default:
130
+ return `complete-milestone-${reason}`;
131
+ }
132
+ }
133
+
120
134
  export function refreshRecoveryDbForArtifact(
121
135
  unitType: string,
122
136
  unitId: string,
@@ -125,7 +139,7 @@ export function refreshRecoveryDbForArtifact(
125
139
  if (unitType !== "plan-slice" && unitType !== "execute-task" && unitType !== "complete-milestone") return { ok: true };
126
140
  if (!isDbAvailable()) return { ok: true };
127
141
 
128
- if (!refreshOpenDatabaseFromDisk()) {
142
+ if (!refreshWorkflowDatabaseFromDisk()) {
129
143
  return {
130
144
  ok: false,
131
145
  fatal: unitType === "execute-task" || unitType === "complete-milestone",
@@ -156,52 +170,29 @@ export function refreshRecoveryDbForArtifact(
156
170
  }
157
171
  if (isClosedStatus(milestone.status)) return { ok: true };
158
172
 
159
- const validation = getLatestAssessmentByScope(mid, "milestone-validation");
160
- if (validation?.status !== "pass") {
161
- return {
162
- ok: false,
163
- fatal: true,
164
- reason: "complete-milestone-validation-not-pass",
165
- message: `Stuck recovery found complete-milestone ${unitId} artifacts, but milestone-validation is "${validation?.status ?? "absent"}" in the DB.`,
166
- };
167
- }
168
-
169
- const slices = getMilestoneSlices(mid);
170
- if (slices.length === 0) {
171
- return {
172
- ok: false,
173
- fatal: true,
174
- reason: "complete-milestone-slices-missing",
175
- message: `Stuck recovery found complete-milestone ${unitId} artifacts, but no slices exist in the DB.`,
176
- };
177
- }
178
- const openSlice = slices.find((slice) => !isClosedStatus(slice.status));
179
- if (openSlice) {
180
- return {
181
- ok: false,
182
- fatal: true,
183
- reason: "complete-milestone-slice-open",
184
- message: `Stuck recovery found complete-milestone ${unitId} artifacts, but slice ${openSlice.id} is still "${openSlice.status}" in the DB.`,
185
- };
186
- }
187
- for (const slice of slices) {
188
- const openTask = getSliceTasks(mid, slice.id).find((task) => !isClosedStatus(task.status));
189
- if (openTask) {
173
+ const artifactBasePath = resolveArtifactVerificationBase(unitId, basePath);
174
+ const closeoutProof = proveMilestoneCloseout(mid, {
175
+ allowOpenMilestone: true,
176
+ summaryArtifactBasePath: artifactBasePath,
177
+ implementationEvidence: {
178
+ basePath,
179
+ requirement: "present",
180
+ },
181
+ });
182
+ if (!closeoutProof.ok) {
183
+ if (closeoutProof.reason === "implementation-evidence-missing") {
190
184
  return {
191
185
  ok: false,
192
186
  fatal: true,
193
- reason: "complete-milestone-task-open",
194
- message: `Stuck recovery found complete-milestone ${unitId} artifacts, but task ${slice.id}/${openTask.id} is still "${openTask.status}" in the DB.`,
187
+ reason: "complete-milestone-implementation-missing",
188
+ message: `Stuck recovery found complete-milestone ${unitId} artifacts, but implementation evidence is not present.`,
195
189
  };
196
190
  }
197
- }
198
-
199
- if (hasImplementationArtifacts(basePath, mid) !== "present") {
200
191
  return {
201
192
  ok: false,
202
193
  fatal: true,
203
- reason: "complete-milestone-implementation-missing",
204
- message: `Stuck recovery found complete-milestone ${unitId} artifacts, but implementation evidence is not present.`,
194
+ reason: closeoutProofRecoveryReason(closeoutProof.reason),
195
+ message: `Stuck recovery found complete-milestone ${unitId} artifacts, but ${closeoutProof.message}`,
205
196
  };
206
197
  }
207
198
 
@@ -535,7 +526,7 @@ export function verifyExpectedArtifact(
535
526
  try {
536
527
  let taskIds: string[] | null = null;
537
528
  if (isDbAvailable()) {
538
- const refreshed = refreshOpenDatabaseFromDisk();
529
+ const refreshed = refreshWorkflowDatabaseFromDisk();
539
530
  if (refreshed) {
540
531
  const tasks = getSliceTasks(mid, sid);
541
532
  if (tasks.length > 0) taskIds = tasks.map(t => t.id);
@@ -642,14 +633,23 @@ export function verifyExpectedArtifact(
642
633
  // A milestone with only .gsd/ plan files and zero implementation code is
643
634
  // not genuinely complete — the LLM wrote plan files but skipped actual work.
644
635
  if (unitType === "complete-milestone") {
645
- const summaryOutcome = classifyMilestoneSummaryContent(readFileSync(absPath, "utf-8"));
646
- if (summaryOutcome === "failure") return false;
647
636
  const { milestone: mid } = parseUnitId(unitId);
648
- if (mid && isDbAvailable()) {
649
- const closeoutGate = checkCloseoutConsistencyGate(mid, { refreshFromDisk: true });
650
- if (!closeoutGate.ok) return false;
637
+ if (!mid) return false;
638
+ const closeoutProof = proveMilestoneCloseout(mid, {
639
+ refreshFromDisk: true,
640
+ summaryArtifactBasePath: artifactBase,
641
+ implementationEvidence: {
642
+ basePath: base,
643
+ requirement: "not-absent",
644
+ },
645
+ });
646
+ if (!closeoutProof.ok) {
647
+ if (!isDbAvailable() && closeoutProof.reason === "db-unavailable") {
648
+ const summaryOutcome = classifyMilestoneSummaryContent(readFileSync(absPath, "utf-8"));
649
+ return summaryOutcome !== "failure" && hasImplementationArtifacts(base, mid) !== "absent";
650
+ }
651
+ return false;
651
652
  }
652
- if (hasImplementationArtifacts(base, mid) === "absent") return false;
653
653
  }
654
654
 
655
655
  return true;
@@ -9,8 +9,23 @@ import {
9
9
  markToolEnd as markTrackedToolEnd,
10
10
  markToolStart as markTrackedToolStart,
11
11
  } from "./auto-tool-tracking.js";
12
+ // Re-exported as a pure pass-through. Must stay UNGATED (no autoSession.active
13
+ // argument, unlike markToolStart at the bottom of this file) so it is true in
14
+ // foreground where the foreground approval-gate pause consults it.
15
+ export { isInteractiveElicitationInFlight } from "./auto-tool-tracking.js";
16
+ import {
17
+ createToolSurfaceSnapshot,
18
+ type ToolSurfaceSnapshot,
19
+ type ToolSurfaceSnapshotInput,
20
+ } from "./tool-surface-snapshot.js";
21
+
22
+ export type {
23
+ ToolSurfaceSnapshot,
24
+ ToolSurfaceSnapshotInput,
25
+ } from "./tool-surface-snapshot.js";
12
26
 
13
27
  export const autoSession = new AutoSession();
28
+ let currentToolSurfaceSnapshot: ToolSurfaceSnapshot | null = null;
14
29
 
15
30
  export type AutoRuntimeSnapshot = {
16
31
  active: boolean;
@@ -20,6 +35,7 @@ export type AutoRuntimeSnapshot = {
20
35
  orchestrationPhase?: "idle" | "running" | "paused" | "stopped" | "error";
21
36
  orchestrationTransitionCount?: number;
22
37
  orchestrationLastTransitionAt?: number;
38
+ toolSurface: ToolSurfaceSnapshot | null;
23
39
  };
24
40
 
25
41
  export function getAutoRuntimeSnapshot(): AutoRuntimeSnapshot {
@@ -32,9 +48,19 @@ export function getAutoRuntimeSnapshot(): AutoRuntimeSnapshot {
32
48
  orchestrationPhase: orchestrationStatus?.phase,
33
49
  orchestrationTransitionCount: orchestrationStatus?.transitionCount,
34
50
  orchestrationLastTransitionAt: orchestrationStatus?.lastTransitionAt,
51
+ toolSurface: autoSession.active || autoSession.paused ? currentToolSurfaceSnapshot : null,
35
52
  };
36
53
  }
37
54
 
55
+ export function recordAutoToolSurfaceSnapshot(input: ToolSurfaceSnapshotInput): ToolSurfaceSnapshot {
56
+ currentToolSurfaceSnapshot = createToolSurfaceSnapshot(input);
57
+ return currentToolSurfaceSnapshot;
58
+ }
59
+
60
+ export function clearAutoToolSurfaceSnapshot(): void {
61
+ currentToolSurfaceSnapshot = null;
62
+ }
63
+
38
64
  export function isAutoActive(): boolean {
39
65
  return autoSession.active;
40
66
  }
@@ -66,7 +66,13 @@ import { initRoutingHistory } from "./routing-history.js";
66
66
  import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
67
67
  import { resetProactiveHealing, setLevelChangeCallback } from "./doctor-proactive.js";
68
68
  import { snapshotSkills } from "./skill-discovery.js";
69
- import { isDbAvailable, getMilestone, getAllMilestones, insertMilestone, openDatabase, getDbStatus, updateMilestoneStatus } from "./gsd-db.js";
69
+ import { isDbAvailable, getMilestone, getAllMilestones, insertMilestone, updateMilestoneStatus } from "./gsd-db.js";
70
+ import {
71
+ getWorkflowDatabaseStatus,
72
+ openExistingWorkflowDatabase,
73
+ openWorkflowDatabase,
74
+ resolveProjectRootDbPath,
75
+ } from "./db-workspace.js";
70
76
  import { isClosedStatus } from "./status-guards.js";
71
77
  import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
72
78
  import { extractVerdict } from "./verdict-parser.js";
@@ -92,7 +98,6 @@ import {
92
98
  import { join } from "node:path";
93
99
  import { sep as pathSep } from "node:path";
94
100
 
95
- import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
96
101
  import { validateDirectory } from "./validate-directory.js";
97
102
  import {
98
103
  isCustomProvider,
@@ -150,10 +155,9 @@ export async function openProjectDbIfPresent(basePath: string): Promise<void> {
150
155
  const gsdDbPath = resolveProjectRootDbPath(basePath);
151
156
  if (!existsSync(gsdDbPath) || isDbAvailable()) return;
152
157
 
153
- try {
154
- openDatabase(gsdDbPath);
155
- } catch (err) {
156
- logWarning("engine", `gsd-db: failed to open existing database: ${err instanceof Error ? err.message : String(err)}`);
158
+ const result = openExistingWorkflowDatabase(basePath);
159
+ if (!result.ok && result.reason === "open-failed") {
160
+ logWarning("engine", `gsd-db: failed to open existing database: ${result.error?.message ?? "open failed"}`);
157
161
  }
158
162
  }
159
163
 
@@ -1673,21 +1677,14 @@ export async function bootstrapAutoSession(
1673
1677
 
1674
1678
  // ── DB lifecycle ──
1675
1679
  const gsdDbPath = resolveProjectRootDbPath(s.basePath);
1676
- const gsdDirPath = join(s.basePath, ".gsd");
1677
- if (existsSync(gsdDirPath) && !existsSync(gsdDbPath)) {
1678
- try {
1679
- const { openDatabase: openDb } = await import("./gsd-db.js");
1680
- openDb(gsdDbPath);
1681
- } catch (err) {
1682
- logError("engine", `failed to initialize project database: ${(err as Error).message}`);
1683
- }
1680
+ const initialDbOpen = openWorkflowDatabase(s.basePath);
1681
+ if (!initialDbOpen.ok && initialDbOpen.reason === "open-failed") {
1682
+ logError("engine", `failed to initialize project database: ${initialDbOpen.error?.message ?? "open failed"}`);
1684
1683
  }
1685
1684
  if (_shouldAbortBootstrapForUnavailableDbForTest(gsdDbPath, isDbAvailable())) {
1686
- try {
1687
- const { openDatabase: openDb } = await import("./gsd-db.js");
1688
- openDb(gsdDbPath);
1689
- } catch (err) {
1690
- logError("engine", `failed to open existing database: ${(err as Error).message}`);
1685
+ const retryDbOpen = openWorkflowDatabase(s.basePath);
1686
+ if (!retryDbOpen.ok && retryDbOpen.reason === "open-failed") {
1687
+ logError("engine", `failed to open existing database: ${retryDbOpen.error?.message ?? "open failed"}`);
1691
1688
  }
1692
1689
  }
1693
1690
 
@@ -1697,7 +1694,7 @@ export async function bootstrapAutoSession(
1697
1694
  // call returns "db_unavailable", triggering artifact-retry which
1698
1695
  // re-dispatches the same task — producing an infinite loop (#2419).
1699
1696
  if (existsSync(gsdDbPath) && !isDbAvailable()) {
1700
- const dbStatus = getDbStatus();
1697
+ const dbStatus = getWorkflowDatabaseStatus();
1701
1698
  const phaseHint = dbStatus.lastPhase === "open"
1702
1699
  ? "The database file could not be opened"
1703
1700
  : dbStatus.lastPhase === "initSchema"