@opengsd/gsd-pi 1.1.1-dev.b2556262 → 1.2.0-dev.4813ead6

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 (500) 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/project-sessions.js +4 -2
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/extensions/ask-user-questions.js +78 -23
  7. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +101 -237
  8. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
  9. package/dist/resources/extensions/github-sync/templates.js +3 -3
  10. package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
  11. package/dist/resources/extensions/gsd/auto/contracts.js +8 -1
  12. package/dist/resources/extensions/gsd/auto/loop.js +74 -56
  13. package/dist/resources/extensions/gsd/auto/orchestrator.js +763 -63
  14. package/dist/resources/extensions/gsd/auto/phases.js +28 -3
  15. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
  16. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  17. package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
  18. package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
  19. package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
  20. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
  21. package/dist/resources/extensions/gsd/auto-prompts.js +191 -9
  22. package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
  23. package/dist/resources/extensions/gsd/auto-runtime-state.js +17 -0
  24. package/dist/resources/extensions/gsd/auto-start.js +12 -23
  25. package/dist/resources/extensions/gsd/auto-timers.js +16 -2
  26. package/dist/resources/extensions/gsd/auto-tool-tracking.js +37 -0
  27. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +33 -29
  28. package/dist/resources/extensions/gsd/auto-verification.js +7 -7
  29. package/dist/resources/extensions/gsd/auto-worktree.js +45 -36
  30. package/dist/resources/extensions/gsd/auto.js +73 -471
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
  32. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +11 -37
  33. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +103 -138
  35. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +63 -4
  36. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
  37. package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
  38. package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
  39. package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
  40. package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
  41. package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
  42. package/dist/resources/extensions/gsd/commands-ship.js +2 -2
  43. package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
  44. package/dist/resources/extensions/gsd/db-workspace.js +103 -0
  45. package/dist/resources/extensions/gsd/debug-logger.js +10 -0
  46. package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
  47. package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
  48. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  49. package/dist/resources/extensions/gsd/doctor-proactive.js +7 -2
  50. package/dist/resources/extensions/gsd/doctor.js +16 -9
  51. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  52. package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
  53. package/dist/resources/extensions/gsd/gsd-db.js +12 -0
  54. package/dist/resources/extensions/gsd/guided-flow.js +36 -470
  55. package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
  56. package/dist/resources/extensions/gsd/markdown-renderer.js +33 -33
  57. package/dist/resources/extensions/gsd/mcp-filter.js +8 -1
  58. package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
  59. package/dist/resources/extensions/gsd/md-importer.js +4 -3
  60. package/dist/resources/extensions/gsd/migrate/safety.js +2 -2
  61. package/dist/resources/extensions/gsd/migration-auto-check.js +3 -2
  62. package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
  63. package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
  64. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
  65. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
  66. package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
  67. package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
  68. package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
  69. package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
  70. package/dist/resources/extensions/gsd/native-git-bridge.js +45 -0
  71. package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
  72. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
  73. package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
  74. package/dist/resources/extensions/gsd/preferences.js +147 -29
  75. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  76. package/dist/resources/extensions/gsd/prompts/discuss.md +6 -7
  77. package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
  78. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
  79. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +6 -6
  80. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
  81. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
  82. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  83. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -1
  84. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  85. package/dist/resources/extensions/gsd/prompts/research-milestone.md +2 -2
  86. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  87. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
  88. package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
  89. package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
  90. package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
  91. package/dist/resources/extensions/gsd/question-transport.js +86 -0
  92. package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
  93. package/dist/resources/extensions/gsd/schemas/parsers.js +6 -1
  94. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
  95. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +21 -1
  96. package/dist/resources/extensions/gsd/state.js +13 -5
  97. package/dist/resources/extensions/gsd/templates/plan.md +7 -0
  98. package/dist/resources/extensions/gsd/templates/project.md +1 -0
  99. package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
  100. package/dist/resources/extensions/gsd/templates/uat.md +5 -1
  101. package/dist/resources/extensions/gsd/tool-contract.js +52 -8
  102. package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
  103. package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
  104. package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
  105. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
  106. package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
  107. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +169 -20
  108. package/dist/resources/extensions/gsd/uat-policy.js +16 -10
  109. package/dist/resources/extensions/gsd/uat-run.js +9 -14
  110. package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
  111. package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
  112. package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
  113. package/dist/resources/extensions/gsd/user-input-boundary.js +65 -4
  114. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  115. package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
  116. package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
  117. package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
  118. package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
  119. package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
  120. package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
  121. package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
  122. package/dist/resources/extensions/shared/interview-ui.js +2 -2
  123. package/dist/resources/shared/claude-runtime-floor.js +182 -0
  124. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  125. package/dist/update-cmd.js +20 -0
  126. package/dist/web/standalone/.next/BUILD_ID +1 -1
  127. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  128. package/dist/web/standalone/.next/build-manifest.json +3 -3
  129. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  130. package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
  131. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  173. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  174. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  176. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  178. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  182. package/dist/web/standalone/.next/server/app/index.html +1 -1
  183. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  184. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  190. package/dist/web/standalone/.next/server/chunks/5047.js +2 -0
  191. package/dist/web/standalone/.next/server/chunks/5124.js +1 -0
  192. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  193. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  196. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  197. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  198. package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
  199. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
  200. package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
  201. package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
  202. package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
  203. package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
  204. package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
  205. package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
  206. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  207. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  208. package/dist/web/standalone/node_modules/postcss/lib/container.js +26 -18
  209. package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
  210. package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
  211. package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
  212. package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
  213. package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
  214. package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
  215. package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
  216. package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
  217. package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
  218. package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
  219. package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
  220. package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
  221. package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
  222. package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
  223. package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
  224. package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
  225. package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
  226. package/dist/web/standalone/node_modules/postcss/package.json +48 -48
  227. package/dist/web-mode.d.ts +2 -0
  228. package/dist/web-mode.js +20 -8
  229. package/package.json +17 -11
  230. package/packages/cloud-mcp-gateway/package.json +2 -2
  231. package/packages/contracts/package.json +1 -1
  232. package/packages/daemon/package.json +4 -4
  233. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
  234. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  235. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
  236. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  237. package/packages/gsd-agent-core/package.json +5 -5
  238. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  239. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -0
  240. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  241. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +1 -1
  242. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  243. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  244. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
  245. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  246. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  247. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
  248. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  249. package/packages/gsd-agent-modes/package.json +7 -7
  250. package/packages/mcp-server/dist/server.d.ts +10 -0
  251. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  252. package/packages/mcp-server/dist/server.js +8 -0
  253. package/packages/mcp-server/dist/server.js.map +1 -1
  254. package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
  255. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  256. package/packages/mcp-server/dist/workflow-tools.js +2 -1
  257. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  258. package/packages/mcp-server/package.json +3 -3
  259. package/packages/native/package.json +1 -1
  260. package/packages/pi-agent-core/package.json +1 -1
  261. package/packages/pi-ai/dist/image-models.generated.d.ts +30 -0
  262. package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  263. package/packages/pi-ai/dist/image-models.generated.js +30 -0
  264. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  265. package/packages/pi-ai/dist/models.generated.d.ts +8 -127
  266. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  267. package/packages/pi-ai/dist/models.generated.js +47 -166
  268. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  269. package/packages/pi-ai/package.json +1 -1
  270. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/auth-storage.js +11 -3
  272. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  273. package/packages/pi-coding-agent/package.json +7 -7
  274. package/packages/pi-tui/dist/components/input.js +1 -1
  275. package/packages/pi-tui/dist/components/input.js.map +1 -1
  276. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  277. package/packages/pi-tui/dist/keys.js +39 -30
  278. package/packages/pi-tui/dist/keys.js.map +1 -1
  279. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  280. package/packages/pi-tui/dist/stdin-buffer.js +22 -0
  281. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  282. package/packages/pi-tui/package.json +2 -2
  283. package/packages/rpc-client/package.json +2 -2
  284. package/pkg/package.json +1 -1
  285. package/scripts/install/deps.js +10 -0
  286. package/scripts/link-workspace-packages.cjs +7 -40
  287. package/src/resources/extensions/ask-user-questions.ts +87 -24
  288. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +126 -289
  289. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +242 -2
  290. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
  291. package/src/resources/extensions/github-sync/templates.ts +3 -3
  292. package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
  293. package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
  294. package/src/resources/extensions/gsd/auto/contracts.ts +40 -121
  295. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
  296. package/src/resources/extensions/gsd/auto/loop.ts +83 -61
  297. package/src/resources/extensions/gsd/auto/orchestrator.ts +913 -64
  298. package/src/resources/extensions/gsd/auto/phases.ts +35 -3
  299. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
  300. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  301. package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
  302. package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
  303. package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
  304. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -3
  305. package/src/resources/extensions/gsd/auto-prompts.ts +220 -9
  306. package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
  307. package/src/resources/extensions/gsd/auto-runtime-state.ts +30 -0
  308. package/src/resources/extensions/gsd/auto-start.ts +17 -20
  309. package/src/resources/extensions/gsd/auto-timers.ts +16 -2
  310. package/src/resources/extensions/gsd/auto-tool-tracking.ts +40 -0
  311. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +42 -30
  312. package/src/resources/extensions/gsd/auto-verification.ts +7 -8
  313. package/src/resources/extensions/gsd/auto-worktree.ts +57 -42
  314. package/src/resources/extensions/gsd/auto.ts +96 -508
  315. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
  316. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +10 -37
  317. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  318. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +120 -151
  319. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +107 -3
  320. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
  321. package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
  322. package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
  323. package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
  324. package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
  325. package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
  326. package/src/resources/extensions/gsd/commands-ship.ts +2 -2
  327. package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
  328. package/src/resources/extensions/gsd/db-workspace.ts +170 -0
  329. package/src/resources/extensions/gsd/debug-logger.ts +11 -0
  330. package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
  331. package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
  332. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  333. package/src/resources/extensions/gsd/doctor-proactive.ts +8 -2
  334. package/src/resources/extensions/gsd/doctor.ts +15 -5
  335. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  336. package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
  337. package/src/resources/extensions/gsd/gsd-db.ts +12 -0
  338. package/src/resources/extensions/gsd/guided-flow.ts +49 -560
  339. package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
  340. package/src/resources/extensions/gsd/markdown-renderer.ts +40 -20
  341. package/src/resources/extensions/gsd/mcp-filter.ts +9 -1
  342. package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
  343. package/src/resources/extensions/gsd/md-importer.ts +3 -3
  344. package/src/resources/extensions/gsd/migrate/safety.ts +2 -2
  345. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  346. package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
  347. package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
  348. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
  349. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
  350. package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
  351. package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
  352. package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
  353. package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
  354. package/src/resources/extensions/gsd/native-git-bridge.ts +48 -0
  355. package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
  356. package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
  357. package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
  358. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  359. package/src/resources/extensions/gsd/preferences.ts +173 -28
  360. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  361. package/src/resources/extensions/gsd/prompts/discuss.md +6 -7
  362. package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
  363. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
  364. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +6 -6
  365. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
  366. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
  367. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  368. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -1
  369. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  370. package/src/resources/extensions/gsd/prompts/research-milestone.md +2 -2
  371. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  372. package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
  373. package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
  374. package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
  375. package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
  376. package/src/resources/extensions/gsd/question-transport.ts +138 -0
  377. package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
  378. package/src/resources/extensions/gsd/schemas/parsers.ts +6 -1
  379. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
  380. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +31 -10
  381. package/src/resources/extensions/gsd/state.ts +15 -5
  382. package/src/resources/extensions/gsd/templates/plan.md +7 -0
  383. package/src/resources/extensions/gsd/templates/project.md +1 -0
  384. package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
  385. package/src/resources/extensions/gsd/templates/uat.md +5 -1
  386. package/src/resources/extensions/gsd/tests/artifact-db-drift-memo.test.ts +66 -0
  387. package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
  388. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
  389. package/src/resources/extensions/gsd/tests/auto-dispatch-baseline-harness.test.ts +53 -0
  390. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +321 -5
  391. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
  392. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
  393. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +709 -845
  394. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +38 -10
  395. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
  396. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
  397. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  398. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
  399. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
  400. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +15 -0
  401. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
  402. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
  403. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
  404. package/src/resources/extensions/gsd/tests/execute-summary-save-empty-project.test.ts +64 -1
  405. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
  406. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
  407. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
  408. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
  409. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +157 -0
  410. package/src/resources/extensions/gsd/tests/markdown-renderer-parse-cache.test.ts +75 -0
  411. package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
  412. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +58 -0
  413. package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
  414. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
  415. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
  416. package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
  417. package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
  418. package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
  419. package/src/resources/extensions/gsd/tests/native-merge-regular.test.ts +139 -0
  420. package/src/resources/extensions/gsd/tests/orchestrator-legacy-parity.test.ts +127 -0
  421. package/src/resources/extensions/gsd/tests/parse-project-milestone-bridge.test.ts +77 -0
  422. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
  423. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +6 -2
  424. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
  425. package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
  426. package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
  427. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +75 -2
  428. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
  429. package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
  430. package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
  431. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +94 -0
  432. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +65 -0
  433. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
  434. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
  435. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
  436. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +101 -1
  437. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
  438. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +21 -6
  439. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +38 -0
  440. package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
  441. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
  442. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
  443. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
  444. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +147 -0
  445. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
  446. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
  447. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
  448. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
  449. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +21 -0
  450. package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
  451. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +24 -0
  452. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
  453. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -3
  454. package/src/resources/extensions/gsd/tests/write-gate.test.ts +79 -0
  455. package/src/resources/extensions/gsd/tool-contract.ts +86 -8
  456. package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
  457. package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
  458. package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
  459. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
  460. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
  461. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +183 -21
  462. package/src/resources/extensions/gsd/uat-policy.ts +19 -10
  463. package/src/resources/extensions/gsd/uat-run.ts +10 -14
  464. package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
  465. package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
  466. package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
  467. package/src/resources/extensions/gsd/user-input-boundary.ts +55 -5
  468. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  469. package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
  470. package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
  471. package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
  472. package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
  473. package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
  474. package/src/resources/extensions/gsd/worktree-lifecycle.ts +7 -16
  475. package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
  476. package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
  477. package/src/resources/extensions/shared/interview-ui.ts +15 -2
  478. package/src/resources/shared/claude-runtime-floor.ts +248 -0
  479. package/dist/web/standalone/.next/server/chunks/678.js +0 -2
  480. package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
  481. package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
  482. package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
  483. package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
  484. package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
  485. package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
  486. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +0 -21
  487. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +0 -1
  488. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +0 -213
  489. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +0 -1
  490. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts +0 -28
  491. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts.map +0 -1
  492. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js +0 -249
  493. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js.map +0 -1
  494. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts +0 -19
  495. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts.map +0 -1
  496. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js +0 -797
  497. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js.map +0 -1
  498. package/scripts/ensure-workspace-builds.cjs +0 -129
  499. /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → tkLHUSzPA2kMmWz4DmGwI}/_buildManifest.js +0 -0
  500. /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → tkLHUSzPA2kMmWz4DmGwI}/_ssgManifest.js +0 -0
@@ -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
  }
@@ -47,6 +73,10 @@ export function isAutoCompletionStopInProgress(): boolean {
47
73
  return autoSession.completionStopInProgress;
48
74
  }
49
75
 
76
+ export function clearAutoCompletionStopInProgress(): void {
77
+ autoSession.completionStopInProgress = false;
78
+ }
79
+
50
80
  export function markToolStart(toolCallId: string, toolName?: string): void {
51
81
  markTrackedToolStart(toolCallId, autoSession.active, toolName);
52
82
  }
@@ -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"
@@ -287,10 +287,23 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
287
287
  }, 15000);
288
288
 
289
289
  // ── 3. Hard timeout ──
290
- s.unitTimeoutHandle = setTimeout(async () => {
290
+ const hardTimeoutBody = async () => {
291
291
  try {
292
292
  s.unitTimeoutHandle = null;
293
293
  if (!s.active) return;
294
+ // User-interactive tools (ask_user_questions, secure_env_collect) block
295
+ // waiting for human input by design. Unlike the idle watchdog (above),
296
+ // the hard timeout had no interactive exemption, so a long human
297
+ // deliberation crossing the hard cap would still closeout + recover
298
+ // (triggerTurn) and abort the turn hosting the elicitation, reintroducing
299
+ // the self-cancel loop on slow answers (#2676). Re-arm instead of firing
300
+ // while a human is being asked, mirroring the idle watchdog's
301
+ // refresh-and-return. Conditional on hasInteractiveToolInFlight(), so a
302
+ // genuinely hung non-interactive unit still hits the hard cap.
303
+ if (getInFlightToolCount() > 0 && hasInteractiveToolInFlight()) {
304
+ s.unitTimeoutHandle = setTimeout(hardTimeoutBody, hardTimeoutMs);
305
+ return;
306
+ }
294
307
  const expectedCurrentUnit = s.currentUnit
295
308
  ? { type: s.currentUnit.type, id: s.currentUnit.id, startedAt: s.currentUnit.startedAt }
296
309
  : null;
@@ -323,7 +336,8 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
323
336
  logWarning("timer", `notification failed: ${err instanceof Error ? err.message : String(err)}`);
324
337
  }
325
338
  }
326
- }, hardTimeoutMs);
339
+ };
340
+ s.unitTimeoutHandle = setTimeout(hardTimeoutBody, hardTimeoutMs);
327
341
 
328
342
  // ── 4. Context-pressure continue-here monitor ──
329
343
  if (s.continueHereHandle) {
@@ -19,6 +19,17 @@ const inFlightTools = new Map<string, InFlightTool>();
19
19
  */
20
20
  const INTERACTIVE_TOOLS = new Set(["ask_user_questions", "secure_env_collect"]);
21
21
 
22
+ /**
23
+ * Mode-agnostic refcount of in-flight interactive elicitations that are an
24
+ * active human boundary (the model ASKED via ask_user_questions). Unlike the
25
+ * `inFlightTools` Map, this is NOT gated by auto-session.active, so it is true
26
+ * in FOREGROUND (where s.active is false). Kept SEPARATE from inFlightTools so
27
+ * getInFlightToolCount()/getOldestInFlightToolAgeMs()/hasInteractiveToolInFlight()
28
+ * and the auto-watchdog accounting are byte-for-byte unchanged. A refcount (not
29
+ * a boolean) handles nested/back-to-back elicitations in a single turn.
30
+ */
31
+ let interactiveElicitationDepth = 0;
32
+
22
33
  /**
23
34
  * Mark a tool execution as in-flight.
24
35
  * Records start time and tool name so the idle watchdog can detect tools
@@ -36,6 +47,29 @@ export function markToolEnd(toolCallId: string): void {
36
47
  inFlightTools.delete(toolCallId);
37
48
  }
38
49
 
50
+ /**
51
+ * Mark an interactive elicitation (the model asking via ask_user_questions) as
52
+ * in flight. Ungated by auto-session.active so it is observable in foreground.
53
+ */
54
+ export function markInteractiveElicitationStart(): void {
55
+ interactiveElicitationDepth++;
56
+ }
57
+
58
+ /**
59
+ * Mark an interactive elicitation as completed. Idempotent below zero.
60
+ */
61
+ export function markInteractiveElicitationEnd(): void {
62
+ if (interactiveElicitationDepth > 0) interactiveElicitationDepth--;
63
+ }
64
+
65
+ /**
66
+ * Returns true if any interactive elicitation is currently the active human
67
+ * boundary. True in ALL modes (foreground and auto) while one is in flight.
68
+ */
69
+ export function isInteractiveElicitationInFlight(): boolean {
70
+ return interactiveElicitationDepth > 0;
71
+ }
72
+
39
73
  /**
40
74
  * Returns the age (ms) of the oldest currently in-flight tool, or 0 if none.
41
75
  */
@@ -84,6 +118,7 @@ export function hasInteractiveToolInFlight(): boolean {
84
118
  */
85
119
  export function clearInFlightTools(): void {
86
120
  inFlightTools.clear();
121
+ interactiveElicitationDepth = 0;
87
122
  }
88
123
 
89
124
  // ─── Tool invocation error classification (#2883) ────────────────────────
@@ -136,6 +171,11 @@ export const DETERMINISTIC_POLICY_ERROR_STRINGS = [
136
171
  // "Cannot write to milestone CONTEXT.md without depth verification." for direct
137
172
  // write tool calls to *-CONTEXT.md paths (different code path than gsd_summary_save).
138
173
  "CONTEXT.md without depth verification",
174
+ // Section-close gate units (execute-task, complete-slice, validate-milestone) that
175
+ // reach for gsd_save_gate_result get the calm redirect from softGateToolRedirect
176
+ // (auto-unit-tool-scope.ts) instead of a HARD BLOCK. Still deterministic — those
177
+ // phases never own that tool, so a retry hits the same redirect every time.
178
+ "closes its quality gates by writing summary sections",
139
179
  ] as const;
140
180
 
141
181
  /**
@@ -3,38 +3,35 @@ import {
3
3
  AUTO_UNIT_SCOPED_TOOLS,
4
4
  getForbiddenGsdToolReason,
5
5
  } from "./unit-tool-contracts.js";
6
+ import {
7
+ WORKFLOW_TOOL_ALIAS_PAIRS,
8
+ canonicalWorkflowSurfaceToolName,
9
+ isWorkflowSurfaceAliasTool,
10
+ stripMcpToolPrefix,
11
+ } from "./workflow-tool-surface.js";
6
12
 
7
13
  export {
8
14
  AUTO_UNIT_SCOPED_TOOLS,
9
15
  RUN_UAT_BROWSER_TOOL_NAMES,
10
16
  } from "./unit-tool-contracts.js";
11
17
 
12
- const WORKFLOW_TOOL_ALIASES: Record<string, string> = {
13
- gsd_save_decision: "gsd_decision_save",
14
- gsd_update_requirement: "gsd_requirement_update",
15
- gsd_save_requirement: "gsd_requirement_save",
16
- gsd_save_summary: "gsd_summary_save",
17
- gsd_generate_milestone_id: "gsd_milestone_generate_id",
18
- gsd_milestone_plan: "gsd_plan_milestone",
19
- gsd_slice_plan: "gsd_plan_slice",
20
- gsd_task_plan: "gsd_plan_task",
21
- gsd_slice_replan: "gsd_replan_slice",
22
- gsd_complete_slice: "gsd_slice_complete",
23
- gsd_milestone_complete: "gsd_complete_milestone",
24
- gsd_milestone_validate: "gsd_validate_milestone",
25
- gsd_roadmap_reassess: "gsd_reassess_roadmap",
26
- gsd_complete_task: "gsd_task_complete",
27
- gsd_reopen_task: "gsd_task_reopen",
28
- gsd_reopen_slice: "gsd_slice_reopen",
29
- gsd_reopen_milestone: "gsd_milestone_reopen",
30
- };
31
-
32
18
  const EXECUTE_TASK_UNIT_TYPES = new Set([
33
19
  "execute-task",
34
20
  "execute-task-simple",
35
21
  "reactive-execute",
36
22
  ]);
37
23
 
24
+ // These units own quality gates, but their completion handlers persist verdicts
25
+ // from artifact sections. gsd_save_gate_result belongs to gate-evaluate, so keep
26
+ // blocking it here with a calm redirect to the section-write path.
27
+ const SECTION_CLOSE_GATE_UNIT_TYPES = new Set([
28
+ "execute-task",
29
+ "execute-task-simple",
30
+ "reactive-execute",
31
+ "complete-slice",
32
+ "validate-milestone",
33
+ ]);
34
+
38
35
  const EXTRA_SCOPED_GSD_LIFECYCLE_TOOLS = [
39
36
  "gsd_skip_slice",
40
37
  "gsd_slice_reopen",
@@ -44,7 +41,7 @@ const EXTRA_SCOPED_GSD_LIFECYCLE_TOOLS = [
44
41
  const SCOPED_GSD_LIFECYCLE_TOOLS = new Set(
45
42
  [
46
43
  ...Object.values(AUTO_UNIT_SCOPED_TOOLS).flat(),
47
- ...Object.values(WORKFLOW_TOOL_ALIASES),
44
+ ...WORKFLOW_TOOL_ALIAS_PAIRS.map(({ canonical }) => canonical),
48
45
  ...EXTRA_SCOPED_GSD_LIFECYCLE_TOOLS,
49
46
  ]
50
47
  .filter((tool) => tool.startsWith("gsd_"))
@@ -52,6 +49,8 @@ const SCOPED_GSD_LIFECYCLE_TOOLS = new Set(
52
49
  );
53
50
 
54
51
  export const GSD_PHASE_SCOPE_DISPLAY_REASON = "This GSD phase only allows its scoped workflow tools.";
52
+ export const GSD_SECTION_CLOSE_GATE_DISPLAY_REASON =
53
+ "Gates here close by writing summary sections — gsd_save_gate_result isn't needed.";
55
54
 
56
55
  type AutoUnitToolScopeResult = {
57
56
  block: boolean;
@@ -59,19 +58,12 @@ type AutoUnitToolScopeResult = {
59
58
  displayReason?: string;
60
59
  };
61
60
 
62
- function stripMcpToolPrefix(toolName: string): string {
63
- if (!toolName.startsWith("mcp__")) return toolName;
64
- const toolSeparator = toolName.indexOf("__", "mcp__".length);
65
- return toolSeparator >= 0 ? toolName.slice(toolSeparator + 2) : toolName;
66
- }
67
-
68
61
  export function canonicalWorkflowToolName(toolName: string): string {
69
- const base = stripMcpToolPrefix(toolName);
70
- return WORKFLOW_TOOL_ALIASES[base] ?? base;
62
+ return canonicalWorkflowSurfaceToolName(toolName);
71
63
  }
72
64
 
73
65
  export function isWorkflowAliasTool(toolName: string): boolean {
74
- return Object.prototype.hasOwnProperty.call(WORKFLOW_TOOL_ALIASES, stripMcpToolPrefix(toolName));
66
+ return isWorkflowSurfaceAliasTool(toolName);
75
67
  }
76
68
 
77
69
  function hardBlockReason(unitType: string, what: string): string {
@@ -90,6 +82,22 @@ function hardBlock(unitType: string, what: string): AutoUnitToolScopeResult {
90
82
  };
91
83
  }
92
84
 
85
+ // This stable marker is registered in auto-tool-tracking.ts so auto-mode treats
86
+ // the redirect as deterministic policy, not a retryable execution failure.
87
+ function softGateToolRedirect(unitType: string): AutoUnitToolScopeResult {
88
+ return {
89
+ block: true,
90
+ reason: [
91
+ `Skip this call — the "${unitType}" phase closes its quality gates by writing summary sections,`,
92
+ "not by calling gsd_save_gate_result (that tool belongs to the gate-evaluate phase).",
93
+ "Record each gate by filling its named section in your summary: a populated section records `pass`,",
94
+ "an empty one records `omitted`. Then call your completion tool and the handler persists every verdict.",
95
+ "This is expected, not an error — continue without gsd_save_gate_result.",
96
+ ].join(" "),
97
+ displayReason: GSD_SECTION_CLOSE_GATE_DISPLAY_REASON,
98
+ };
99
+ }
100
+
93
101
  function allowedGsdToolsForUnit(unitType: string): string[] {
94
102
  return [...new Set(
95
103
  (AUTO_UNIT_SCOPED_TOOLS[unitType] ?? [])
@@ -171,6 +179,10 @@ export function shouldBlockAutoUnitToolCall(
171
179
  );
172
180
  }
173
181
 
182
+ if (canonicalTool === "gsd_save_gate_result" && SECTION_CLOSE_GATE_UNIT_TYPES.has(unitType)) {
183
+ return softGateToolRedirect(unitType);
184
+ }
185
+
174
186
  return hardBlock(
175
187
  unitType,
176
188
  `GSD lifecycle tool "${canonicalTool}" is not permitted; allowed GSD tools: ${allowedTools.length > 0 ? allowedTools.join(", ") : "(none)"}`,
@@ -16,13 +16,13 @@
16
16
  import type { ExtensionContext, ExtensionAPI } from "@gsd/pi-coding-agent";
17
17
  import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
18
18
  import { gsdProjectionRoot, resolveSliceFile, resolveSlicePath, resolveMilestoneFile } from "./paths.js";
19
+ import { resolveMilestoneValidationVerdict } from "./milestone-validation-verdict.js";
19
20
  import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
20
21
  import { parseUnitId } from "./unit-id.js";
21
22
  import { isDbAvailable, getTask, getSliceTasks, getMilestoneSlices } from "./gsd-db.js";
22
23
  import type { TaskRow } from "./db-task-slice-rows.js";
23
24
  import { loadEffectiveGSDPreferences } from "./preferences.js";
24
25
  import type { GSDPreferences } from "./preferences-types.js";
25
- import { extractVerdict } from "./verdict-parser.js";
26
26
  import { isClosedStatus } from "./status-guards.js";
27
27
  import { loadFile } from "./files.js";
28
28
  import { parseRoadmap } from "./parsers-legacy.js";
@@ -269,28 +269,27 @@ async function runValidateMilestonePostCheck(
269
269
  mid,
270
270
  `${mid}-VALIDATION.md`,
271
271
  );
272
- if (!validationFile) {
272
+ const validationContent = await loadFile(validationFile);
273
+ if (validationContent !== null && validationContent.trim() === "") {
273
274
  if (await reassessmentInvalidatedValidation()) {
274
275
  clearValidationRetry();
275
276
  return "continue";
276
277
  }
277
278
  return setToolFailureRetry(
278
- "You must call gsd_validate_milestone to persist the validation results. No VALIDATION.md was created.",
279
+ "You must call gsd_validate_milestone to persist the validation results. VALIDATION.md exists but is empty.",
279
280
  );
280
281
  }
281
282
 
282
- const validationContent = await loadFile(validationFile);
283
- if (!validationContent) {
283
+ const verdict = await resolveMilestoneValidationVerdict(s.basePath, mid);
284
+ if (!verdict) {
284
285
  if (await reassessmentInvalidatedValidation()) {
285
286
  clearValidationRetry();
286
287
  return "continue";
287
288
  }
288
289
  return setToolFailureRetry(
289
- "You must call gsd_validate_milestone to persist the validation results. VALIDATION.md exists but is empty.",
290
+ "You must call gsd_validate_milestone to persist the validation results. No VALIDATION.md was created.",
290
291
  );
291
292
  }
292
-
293
- const verdict = extractVerdict(validationContent);
294
293
  if (verdict === "needs-attention") {
295
294
  ctx.ui.notify(
296
295
  `Milestone ${mid} validation returned verdict=needs-attention. Pausing for human review.`,