@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
@@ -7,6 +7,7 @@
7
7
  import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
8
8
 
9
9
  import type { AutoSession } from "./session.js";
10
+ import type { AutoTerminalOutcome } from "./contracts.js";
10
11
  import type { ErrorContext } from "./types.js";
11
12
  import type { GSDPreferences } from "../preferences.js";
12
13
  import type { GSDState } from "../types.js";
@@ -33,6 +34,7 @@ export interface StopAutoOptions {
33
34
  milestoneTitle?: string | null;
34
35
  allMilestonesComplete?: boolean;
35
36
  };
37
+ terminalOutcome?: AutoTerminalOutcome;
36
38
  /**
37
39
  * Foreground closeout-boundary stops already have the useful final surface in
38
40
  * the transcript. Preserve it instead of installing a replacement widget.
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * auto/loop.ts — Main auto-mode execution loop.
5
5
  *
6
- * Iterates: derivedispatch → guards → runUnit → finalize → repeat.
6
+ * Iterates: orchestration.advance → guards → runUnit → finalize → repeat.
7
7
  * Exits when s.active becomes false or a terminal condition is reached.
8
8
  *
9
9
  * Imports from: auto/types, auto/resolve, auto/phases
@@ -15,6 +15,7 @@ import { randomUUID } from "node:crypto";
15
15
  import { mkdirSync, writeFileSync } from "node:fs";
16
16
  import { join } from "node:path";
17
17
  import type { AutoSession } from "./session.js";
18
+ import type { AutoTerminalOutcome } from "./contracts.js";
18
19
  import type { LoopDeps, StopAutoOptions } from "./loop-deps.js";
19
20
  import type { GSDState } from "../types.js";
20
21
  import {
@@ -24,13 +25,7 @@ import {
24
25
  type IterationData,
25
26
  } from "./types.js";
26
27
  import { _clearCurrentResolve } from "./resolve.js";
27
- import {
28
- runPreDispatch,
29
- runDispatch,
30
- runGuards,
31
- runFinalize,
32
- STUCK_WINDOW_SIZE,
33
- } from "./phases.js";
28
+ import { runGuards, runFinalize, STUCK_WINDOW_SIZE } from "./phases.js";
34
29
  import { debugLog } from "../debug-logger.js";
35
30
  import { isInfrastructureError, isTransientCooldownError, getCooldownRetryAfterMs, COOLDOWN_FALLBACK_WAIT_MS, MAX_COOLDOWN_RETRIES } from "./infra-errors.js";
36
31
  import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
@@ -146,6 +141,25 @@ function resolveCompletionStopFromState(
146
141
  };
147
142
  }
148
143
 
144
+ function resolveCompletionStopFromOutcome(
145
+ outcome: AutoTerminalOutcome | undefined,
146
+ stateSnapshot: GSDState | undefined,
147
+ ): { reason: string; options: StopAutoOptions } | null {
148
+ if (outcome?.code !== "all-complete") return null;
149
+ const completedMilestone = stateSnapshot?.lastCompletedMilestone ?? stateSnapshot?.activeMilestone;
150
+ return {
151
+ reason: outcome.displayReason,
152
+ options: {
153
+ completionWidget: {
154
+ milestoneId: completedMilestone?.id ?? null,
155
+ milestoneTitle: completedMilestone?.title ?? null,
156
+ allMilestonesComplete: true,
157
+ },
158
+ terminalOutcome: outcome,
159
+ },
160
+ };
161
+ }
162
+
149
163
  // ── Stuck detection persistence (#3704) ──────────────────────────────────
150
164
  // Phase C migration: stuck-state.json deleted in favor of DB-backed
151
165
  // equivalents. recentUnits is rebuilt from unit_dispatches (Phase B
@@ -158,6 +172,8 @@ function resolveCompletionStopFromState(
158
172
  // tolerates — same behavior as a fresh session.
159
173
  const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
160
174
  const MAX_CONSECUTIVE_ALREADY_ACTIVE_SKIPS = 3;
175
+ const ORCHESTRATION_MISSING_REASON =
176
+ "Auto Orchestration Module is not wired; cannot dispatch built-in GSD Unit.";
161
177
 
162
178
  function stableStuckStateScopeId(s: AutoSession): string {
163
179
  return normalizeRealPath(s.scope?.workspace.projectRoot ?? (s.originalBasePath || s.basePath));
@@ -353,9 +369,9 @@ function closeOutCrashedUnit(s: AutoSession, iterData: IterationData, err: unkno
353
369
  }
354
370
 
355
371
  /**
356
- * Main auto-mode execution loop. Iterates: derivedispatch → guards →
357
- * runUnit → finalize → repeat. Exits when s.active becomes false or a
358
- * terminal condition is reached.
372
+ * Main auto-mode execution loop. Iterates: orchestration.advance → guards →
373
+ * runUnit → finalize → repeat. Exits when s.active becomes false or a terminal
374
+ * condition is reached.
359
375
  *
360
376
  * This is the linear replacement for the recursive
361
377
  * dispatchNextUnit → resolveAgentEnd → dispatchNextUnit chain.
@@ -572,10 +588,9 @@ export async function autoLoop(
572
588
  let iterData: IterationData;
573
589
 
574
590
  // ── Custom engine path ──────────────────────────────────────────────
575
- // When activeEngineId is a non-dev value, bypass runPreDispatch and
576
- // runDispatch entirely the custom engine drives its own state via
577
- // GRAPH.yaml. Shares runGuards and runUnitPhase with the dev path.
578
- // After unit execution, verifies then reconciles via the engine layer.
591
+ // When activeEngineId is a non-dev value, the custom engine drives its own
592
+ // state via GRAPH.yaml. It shares guards and Unit execution with the dev
593
+ // path, then verifies and reconciles via the engine layer.
579
594
  //
580
595
  // GSD_ENGINE_BYPASS=1 skips the engine layer entirely — falls through
581
596
  // to the dev path below.
@@ -656,7 +671,7 @@ export async function autoLoop(
656
671
  observedUnitType = iterData.unitType;
657
672
  observedUnitId = iterData.unitId;
658
673
 
659
- // ── Progress widget (mirrors dev path in runDispatch) ──
674
+ // ── Progress widget (mirrors the dev path) ──
660
675
  deps.updateProgressWidget(ctx, iterData.unitType, iterData.unitId, iterData.state);
661
676
 
662
677
  // ── Guards (shared with dev path) ──
@@ -876,14 +891,22 @@ export async function autoLoop(
876
891
 
877
892
  if (orchestrationResult.kind === "blocked") {
878
893
  s.pendingOrchestrationDispatch = null;
894
+ const blockMessage = orchestrationResult.terminalOutcome?.code === "settlement-blocked"
895
+ ? [
896
+ orchestrationResult.terminalOutcome.displayReason,
897
+ `Next: ${orchestrationResult.terminalOutcome.nextAction}`,
898
+ ].join("\n")
899
+ : orchestrationResult.reason;
879
900
  if (orchestrationResult.action === "pause") {
880
901
  await deps.pauseAuto(ctx, pi, {
881
- message: orchestrationResult.reason,
902
+ message: blockMessage,
882
903
  category: "unknown",
904
+ }, {
905
+ expectedCurrentUnit: null,
883
906
  });
884
907
  finishTurn("paused", "manual-attention", "orchestration-blocked");
885
908
  } else {
886
- await deps.stopAuto(ctx, pi, orchestrationResult.reason);
909
+ await deps.stopAuto(ctx, pi, blockMessage);
887
910
  finishTurn("stopped", "manual-attention", "orchestration-blocked");
888
911
  }
889
912
  finishIncompleteIteration({
@@ -894,8 +917,20 @@ export async function autoLoop(
894
917
  break;
895
918
  }
896
919
 
920
+ if (orchestrationResult.kind === "skipped") {
921
+ s.pendingOrchestrationDispatch = null;
922
+ emitIterationEnd({ skipped: true });
923
+ completeIteration();
924
+ finishTurn("skipped");
925
+ continue;
926
+ }
927
+
897
928
  if (orchestrationResult.kind === "paused") {
898
929
  s.pendingOrchestrationDispatch = null;
930
+ finishIncompleteIteration({
931
+ status: "paused",
932
+ reason: orchestrationResult.reason,
933
+ });
899
934
  finishTurn("skipped");
900
935
  continue;
901
936
  }
@@ -917,7 +952,11 @@ export async function autoLoop(
917
952
 
918
953
  if (orchestrationResult.kind === "stopped") {
919
954
  s.pendingOrchestrationDispatch = null;
920
- const completionStop = resolveCompletionStopFromState(orchestrationResult.stateSnapshot);
955
+ let completionStop = resolveCompletionStopFromOutcome(
956
+ orchestrationResult.terminalOutcome,
957
+ orchestrationResult.stateSnapshot,
958
+ );
959
+ completionStop ??= resolveCompletionStopFromState(orchestrationResult.stateSnapshot);
921
960
  if (completionStop) {
922
961
  await deps.stopAuto(ctx, pi, completionStop.reason, completionStop.options);
923
962
  } else {
@@ -998,54 +1037,37 @@ export async function autoLoop(
998
1037
  });
999
1038
  observedUnitType = iterData.unitType;
1000
1039
  observedUnitId = iterData.unitId;
1001
- } else {
1002
- const preDispatchResult = await runPreDispatch(ic, loopState);
1003
- phaseReporter.report("pre-dispatch", preDispatchResult.action);
1004
- if (preDispatchResult.action === "break") {
1005
- finishTurn("stopped", "manual-attention", "pre-dispatch-break");
1040
+
1041
+ const guardMilestoneId = iterData.mid ?? s.currentMilestoneId ?? "workflow";
1042
+ const guardsResult = await runGuards(ic, guardMilestoneId);
1043
+ phaseReporter.report("guard", guardsResult.action, {
1044
+ unitType: iterData.unitType,
1045
+ unitId: iterData.unitId,
1046
+ });
1047
+ if (guardsResult.action === "break") {
1048
+ finishTurn("stopped", "manual-attention", "guard-break");
1006
1049
  finishIncompleteIteration({
1007
1050
  status: "stopped",
1008
- reason: "pre-dispatch-break",
1051
+ reason: "guard-break",
1052
+ unitType: iterData.unitType,
1053
+ unitId: iterData.unitId,
1009
1054
  failureClass: "manual-attention",
1010
1055
  });
1011
1056
  break;
1012
1057
  }
1013
- if (preDispatchResult.action === "continue") {
1014
- emitIterationEnd({ skipped: true });
1015
- completeIteration();
1016
- finishTurn("skipped");
1017
- continue;
1018
- }
1019
- if (preDispatchResult.action === "retry") {
1020
- finishTurn("retry", "execution", preDispatchResult.reason);
1021
- continue;
1022
- }
1023
- const preData = preDispatchResult.data;
1024
- const guardsResult = await runGuards(ic, preData.mid);
1025
- phaseReporter.report("guard", guardsResult.action);
1026
- if (guardsResult.action === "break") {
1027
- finishTurn("stopped", "manual-attention", "guard-break");
1028
- break;
1029
- }
1030
- const dispatchResult = await runDispatch(ic, preData, loopState);
1031
- phaseReporter.report("dispatch", dispatchResult.action);
1032
- if (dispatchResult.action === "break") {
1033
- finishTurn("stopped", "manual-attention", "dispatch-break");
1034
- break;
1035
- }
1036
- if (dispatchResult.action === "continue") {
1037
- emitIterationEnd({ skipped: true });
1038
- completeIteration();
1039
- finishTurn("skipped");
1040
- continue;
1041
- }
1042
- if (dispatchResult.action === "retry") {
1043
- finishTurn("retry", "execution", dispatchResult.reason);
1044
- continue;
1045
- }
1046
- iterData = dispatchResult.data;
1047
- observedUnitType = iterData.unitType;
1048
- observedUnitId = iterData.unitId;
1058
+ } else {
1059
+ s.pendingOrchestrationDispatch = null;
1060
+ await deps.pauseAuto(ctx, pi, {
1061
+ message: ORCHESTRATION_MISSING_REASON,
1062
+ category: "unknown",
1063
+ });
1064
+ finishTurn("paused", "manual-attention", "orchestration-missing");
1065
+ finishIncompleteIteration({
1066
+ status: "paused",
1067
+ reason: ORCHESTRATION_MISSING_REASON,
1068
+ failureClass: "manual-attention",
1069
+ });
1070
+ break;
1049
1071
  }
1050
1072
  } else {
1051
1073
  iterData = await buildSidecarIterationData({
@@ -12,11 +12,13 @@
12
12
 
13
13
  import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
14
14
 
15
- import type { AutoAdvanceResult, AutoOrchestrationModule, AutoSessionContext, AutoStatus } from "./contracts.js";
15
+ import type { AutoAdvanceResult, AutoOrchestrationModule, AutoSessionContext, AutoStatus, AutoTerminalOutcome } from "./contracts.js";
16
16
  import type { AutoSession, PendingOrchestrationDispatch } from "./session.js";
17
17
  import type { GSDState } from "../types.js";
18
18
  import type { MinimalModelRegistry } from "../context-budget.js";
19
19
 
20
+ type BlockedAdvanceResult = Extract<AutoAdvanceResult, { kind: "blocked" }>;
21
+
20
22
  import { debugCount, debugTime } from "../debug-logger.js";
21
23
  import { reconcileBeforeDispatch } from "../state-reconciliation.js";
22
24
  import { resolveDispatch } from "../auto-dispatch.js";
@@ -36,13 +38,20 @@ import { getSessionLockStatus } from "../session-lock.js";
36
38
  import { resolveUokFlags } from "../uok/flags.js";
37
39
  import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
38
40
  import { loadEffectiveGSDPreferences, getIsolationMode } from "../preferences.js";
39
- import { detectWorktreeName, resolveProjectRoot } from "../worktree.js";
41
+ import {
42
+ detectWorktreeName,
43
+ getMainBranch,
44
+ resolveProjectRoot,
45
+ resolveWorktreeProjectRoot,
46
+ } from "../worktree.js";
47
+ import { getPriorSliceCompletionBlocker } from "../dispatch-guard.js";
40
48
  import { GitServiceImpl } from "../git-service.js";
41
49
  import { WorktreeStateProjection } from "../worktree-state-projection.js";
42
50
  import { WorktreeLifecycle } from "../worktree-lifecycle.js";
51
+ import { createMilestoneMergeTransaction } from "../milestone-merge-transaction.js";
43
52
  import { createWorkspace, scopeMilestone } from "../workspace.js";
44
53
  import { supportsStructuredQuestions } from "../workflow-mcp.js";
45
- import { getToolBaselineSnapshot } from "../auto-model-selection.js";
54
+ import { getRegisteredToolSnapshot, getToolBaselineSnapshot } from "../auto-model-selection.js";
46
55
  import { deriveState } from "../state.js";
47
56
  import { parseUnitId } from "../unit-id.js";
48
57
  import { isClosedStatus } from "../status-guards.js";
@@ -50,12 +59,13 @@ import {
50
59
  isDbAvailable,
51
60
  getSlice,
52
61
  getTask,
53
- refreshOpenDatabaseFromDisk,
54
62
  } from "../gsd-db.js";
63
+ import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
55
64
  import { getErrorMessage } from "../error-utils.js";
56
65
  import { logWarning } from "../workflow-logger.js";
57
66
  import { existsSync, readFileSync } from "node:fs";
58
67
  import { join } from "node:path";
68
+ import { evaluateAllCompleteSettlement } from "../milestone-settlement.js";
59
69
 
60
70
  function now(): number {
61
71
  return Date.now();
@@ -71,11 +81,19 @@ function now(): number {
71
81
  */
72
82
  export const STUCK_WINDOW_SIZE = 6;
73
83
 
74
- function noRemainingUnitsReason(stateSnapshot: GSDState): string {
84
+ function noRemainingUnitsOutcome(stateSnapshot: GSDState): AutoTerminalOutcome {
75
85
  if (stateSnapshot.phase === "complete") {
76
- return "all milestones complete";
86
+ return {
87
+ code: "all-complete",
88
+ displayReason: "All milestones complete",
89
+ allMilestonesComplete: true,
90
+ };
77
91
  }
78
- return "no remaining units";
92
+ return {
93
+ code: "no-remaining-units",
94
+ displayReason: "No remaining units",
95
+ allMilestonesComplete: false,
96
+ };
79
97
  }
80
98
 
81
99
  /**
@@ -118,7 +136,7 @@ export interface DispatchDecisionInput {
118
136
 
119
137
  function getAlreadyClosedDispatchReason(unitType: string, unitId: string): string | null {
120
138
  if (!isDbAvailable()) return null;
121
- refreshOpenDatabaseFromDisk();
139
+ refreshWorkflowDatabaseFromDisk();
122
140
  const { milestone, slice, task } = parseUnitId(unitId);
123
141
  if (unitType === "execute-task" && milestone && slice && task) {
124
142
  const row = getTask(milestone, slice, task);
@@ -201,6 +219,7 @@ export async function decideOrchestratorDispatch(
201
219
  // active set may be narrowed by the prior unit before selectAndApplyModel
202
220
  // restores it, causing false transport-preflight failures (#477 follow-up).
203
221
  const activeTools = getToolBaselineSnapshot(pi);
222
+ const registeredTools = getRegisteredToolSnapshot(pi);
204
223
  // Mirrors runDispatch: deep-planning keeps approval gates in plain chat
205
224
  // because structured questions can be cancelled outside the chat turn on
206
225
  // some transports.
@@ -248,6 +267,7 @@ export async function decideOrchestratorDispatch(
248
267
  sessionProvider,
249
268
  modelRegistry,
250
269
  activeTools,
270
+ registeredTools,
251
271
  sessionAuthMode: authMode,
252
272
  sessionBaseUrl: ctx.model?.baseUrl,
253
273
  });
@@ -532,6 +552,55 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
532
552
  return decideOrchestratorDispatch(this.ctx, this.pi, this.dispatchBasePath, this.s, input);
533
553
  }
534
554
 
555
+ private evaluateNoRemainingUnitsSettlement(stateSnapshot: GSDState): BlockedAdvanceResult | null {
556
+ const settlement = evaluateAllCompleteSettlement({
557
+ milestoneId: this.s.currentMilestoneId ?? stateSnapshot.activeMilestone?.id,
558
+ statePhase: stateSnapshot.phase,
559
+ basePath: this.s.basePath || this.getLiveDispatchBasePath(),
560
+ originalBasePath: this.s.originalBasePath || this.runtimeBasePath,
561
+ milestoneMerged: this.s.milestoneMergedInPhases,
562
+ });
563
+ this.s.milestoneSettlement = settlement;
564
+ if (settlement.ok) return null;
565
+ return {
566
+ kind: "blocked",
567
+ reason: settlement.message,
568
+ action: settlement.action,
569
+ stateSnapshot,
570
+ terminalOutcome: {
571
+ code: "settlement-blocked",
572
+ displayReason: settlement.message,
573
+ nextAction: settlement.nextAction,
574
+ milestoneId: settlement.milestoneId,
575
+ allMilestonesComplete: false,
576
+ },
577
+ };
578
+ }
579
+
580
+ private clearPendingDispatch(): void {
581
+ this.s.pendingOrchestrationDispatch = null;
582
+ }
583
+
584
+ private findPriorSliceCompletionBlocker(unitType: string, unitId: string): string | null {
585
+ const guardBasePath = resolveWorktreeProjectRoot(
586
+ this.getLiveDispatchBasePath(),
587
+ this.s.originalBasePath,
588
+ );
589
+ let mainBranch = "main";
590
+ try {
591
+ mainBranch = getMainBranch(guardBasePath);
592
+ } catch (err) {
593
+ // Preserve legacy dispatch behavior: fall back to main when branch
594
+ // discovery fails, then let the guard make the progression decision.
595
+ logWarning(
596
+ "engine",
597
+ `branch discovery failed, falling back to main: ${getErrorMessage(err)}`,
598
+ { file: "orchestrator.ts" },
599
+ );
600
+ }
601
+ return getPriorSliceCompletionBlocker(guardBasePath, mainBranch, unitType, unitId);
602
+ }
603
+
535
604
  // ── ToolContractAdapter (folded) ─────────────────────────────────────────
536
605
 
537
606
  private compileUnitToolContract(unitType: string): { ok: true; reason: string } | { ok: false; reason: string } {
@@ -554,7 +623,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
554
623
  return new GitServiceImpl(basePath, gitConfig);
555
624
  },
556
625
  worktreeProjection: new WorktreeStateProjection(),
557
- mergeMilestoneToMain,
626
+ mergeMilestoneToMain: createMilestoneMergeTransaction(mergeMilestoneToMain),
558
627
  });
559
628
  }
560
629
 
@@ -809,10 +878,23 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
809
878
 
810
879
  const decision = await this.decideNextUnit({ stateSnapshot: reconciliation.stateSnapshot });
811
880
  if (!decision) {
881
+ const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
882
+ if (settlementBlock) {
883
+ this.status.phase = "paused";
884
+ this.status.activeUnit = undefined;
885
+ this.lastAdvanceKey = null;
886
+ this.dispatchKeyWindow = [];
887
+ this.bumpTransition();
888
+ this.journalTransition({ name: "advance-blocked", reason: settlementBlock.reason });
889
+ this.postAdvanceRecord(settlementBlock);
890
+ return settlementBlock;
891
+ }
892
+ const terminalOutcome = noRemainingUnitsOutcome(reconciliation.stateSnapshot);
812
893
  const stopped: AutoAdvanceResult = {
813
894
  kind: "stopped",
814
- reason: noRemainingUnitsReason(reconciliation.stateSnapshot),
895
+ reason: terminalOutcome.displayReason,
815
896
  stateSnapshot: reconciliation.stateSnapshot,
897
+ terminalOutcome,
816
898
  };
817
899
  this.status.phase = "stopped";
818
900
  this.status.activeUnit = undefined;
@@ -848,6 +930,25 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
848
930
  return blocked;
849
931
  }
850
932
 
933
+ const priorSliceBlocker = this.findPriorSliceCompletionBlocker(decision.unitType, decision.unitId);
934
+ if (priorSliceBlocker) {
935
+ this.clearPendingDispatch();
936
+ const blocked: AutoAdvanceResult = {
937
+ kind: "blocked",
938
+ reason: priorSliceBlocker,
939
+ action: "stop",
940
+ stateSnapshot: reconciliation.stateSnapshot,
941
+ };
942
+ this.journalTransition({
943
+ name: "advance-blocked",
944
+ reason: blocked.reason,
945
+ unitType: decision.unitType,
946
+ unitId: decision.unitId,
947
+ });
948
+ this.postAdvanceRecord(blocked);
949
+ return blocked;
950
+ }
951
+
851
952
  const nextKey = `${decision.unitType}:${decision.unitId}`;
852
953
 
853
954
  // Record every dispatch decision in the ring buffer before pre-flight
@@ -865,8 +966,10 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
865
966
  // actually completed on disk with a stale DB. Verify + recover before
866
967
  // hard-stopping (legacy graduated stuck-recovery parity).
867
968
  if (this.tryStuckArtifactRecovery(decision.unitType, decision.unitId)) {
969
+ this.clearPendingDispatch();
868
970
  return this.stuckRecovered(decision, reconciliation.stateSnapshot);
869
971
  }
972
+ this.clearPendingDispatch();
870
973
  const blocked: AutoAdvanceResult = {
871
974
  kind: "blocked",
872
975
  reason: `state did not advance after finalized ${decision.unitType} ${decision.unitId}`,
@@ -890,6 +993,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
890
993
  // checks coexist: idempotency for the common immediate-repeat case,
891
994
  // stuck-loop for the saturated-window case.
892
995
  if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
996
+ this.clearPendingDispatch();
893
997
  const blocked: AutoAdvanceResult = { kind: "blocked", reason: "idempotent advance: unit already active", action: "pause" };
894
998
  this.journalTransition({
895
999
  name: "advance-blocked",
@@ -910,8 +1014,10 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
910
1014
  // complete on disk (stale DB) and recover if so — legacy graduated
911
1015
  // stuck-recovery parity. Otherwise hard-stop with a diagnosable reason.
912
1016
  if (this.tryStuckArtifactRecovery(decision.unitType, decision.unitId)) {
1017
+ this.clearPendingDispatch();
913
1018
  return this.stuckRecovered(decision, reconciliation.stateSnapshot);
914
1019
  }
1020
+ this.clearPendingDispatch();
915
1021
  const blocked: AutoAdvanceResult = {
916
1022
  kind: "blocked",
917
1023
  reason: `stuck-loop: ${nextKey} picked ${matchingCount} times`,
@@ -929,6 +1035,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
929
1035
 
930
1036
  const contract = this.compileUnitToolContract(decision.unitType);
931
1037
  if (!contract.ok) {
1038
+ this.clearPendingDispatch();
932
1039
  const blocked: AutoAdvanceResult = {
933
1040
  kind: "blocked",
934
1041
  reason: contract.reason,
@@ -947,6 +1054,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
947
1054
 
948
1055
  const worktree = await this.prepareWorktreeForUnit(decision.unitType, decision.unitId);
949
1056
  if (!worktree.ok) {
1057
+ this.clearPendingDispatch();
950
1058
  const blocked: AutoAdvanceResult = {
951
1059
  kind: "blocked",
952
1060
  reason: worktree.reason,
@@ -1035,7 +1143,8 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1035
1143
  public async resume(): Promise<AutoAdvanceResult> {
1036
1144
  this.lastAdvanceKey = null;
1037
1145
  this.lastFinalizedUnitKey = null;
1038
- this.dispatchKeyWindow = [];
1146
+ // Preserve dispatchKeyWindow across resume so stuck-loop detection
1147
+ // accumulates across pause/resume cycles rather than resetting each time.
1039
1148
  this.lastStuckRecoveryKey = null;
1040
1149
  this.status.phase = "running";
1041
1150
  this.bumpTransition();
@@ -1053,7 +1162,11 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1053
1162
  this.status.activeUnit = undefined;
1054
1163
  this.lastAdvanceKey = null;
1055
1164
  this.lastFinalizedUnitKey = null;
1056
- this.dispatchKeyWindow = [];
1165
+ // Preserve dispatchKeyWindow on pause so stuck-loop detection accumulates
1166
+ // across pause/resume cycles. Only clear on a hard stop.
1167
+ if (reason !== "pause") {
1168
+ this.dispatchKeyWindow = [];
1169
+ }
1057
1170
  this.lastStuckRecoveryKey = null;
1058
1171
  this.bumpTransition();
1059
1172
  this.journalTransition({ name: "stop", reason });
@@ -60,7 +60,8 @@ import { writeUnitRuntimeRecord } from "../unit-runtime.js";
60
60
  import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "./finalize-timeout.js";
61
61
  import { getEligibleSlices } from "../slice-parallel-eligibility.js";
62
62
  import { isSliceParallelActive, startSliceParallel } from "../slice-parallel-orchestrator.js";
63
- import { isDbAvailable, getMilestoneSlices, getSlice, getTask, refreshOpenDatabaseFromDisk } from "../gsd-db.js";
63
+ import { isDbAvailable, getMilestoneSlices, getSlice, getTask } from "../gsd-db.js";
64
+ import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
64
65
  import { isClosedStatus } from "../status-guards.js";
65
66
  import { setRuntimeKv } from "../db/runtime-kv.js";
66
67
  import { getLatestForUnit } from "../db/unit-dispatches.js";
@@ -85,7 +86,12 @@ import {
85
86
  supportsStructuredQuestions,
86
87
  } from "../workflow-mcp.js";
87
88
  import { prepareWorkflowMcpForProject } from "../workflow-mcp-auto-prep.js";
88
- import { getToolBaselineSnapshot, applyThinkingLevelForModel, floorThinkingLevelForUnit } from "../auto-model-selection.js";
89
+ import {
90
+ applyThinkingLevelForModel,
91
+ floorThinkingLevelForUnit,
92
+ getRegisteredToolSnapshot,
93
+ getToolBaselineSnapshot,
94
+ } from "../auto-model-selection.js";
89
95
  import type { DispatchAction } from "../auto-dispatch.js";
90
96
  import { resolveManifest } from "../unit-context-manifest.js";
91
97
  import { createWorktreeSafetyModule, type WorktreeSafetyResult } from "../worktree-safety.js";
@@ -225,7 +231,7 @@ function rememberRetryDispatch(
225
231
 
226
232
  function getAlreadyClosedDispatchReason(unitType: string, unitId: string): string | null {
227
233
  if (!isDbAvailable()) return null;
228
- refreshOpenDatabaseFromDisk();
234
+ refreshWorkflowDatabaseFromDisk();
229
235
  const { milestone, slice, task } = parseUnitId(unitId);
230
236
  if (unitType === "execute-task" && milestone && slice && task) {
231
237
  const row = getTask(milestone, slice, task);
@@ -624,6 +630,16 @@ export async function _runMilestoneMergeWithStashRestore(
624
630
  );
625
631
  if (exitResult.ok) {
626
632
  s.milestoneMergedInPhases = true;
633
+ try {
634
+ const projectRoot = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
635
+ const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
636
+ await rebuildMarkdownProjectionsFromDb(projectRoot);
637
+ } catch (err) {
638
+ logWarning(
639
+ "engine",
640
+ `markdown projection rebuild after milestone merge failed: ${err instanceof Error ? err.message : String(err)}`,
641
+ );
642
+ }
627
643
  } else {
628
644
  mergeError = exitResult.cause ?? new Error(`exit ${exitResult.reason}`);
629
645
  }
@@ -1232,6 +1248,19 @@ export async function runPreDispatch(
1232
1248
  } catch (e) {
1233
1249
  logWarning("engine", "STATE.md rebuild failed after milestone transition", { error: String(e) });
1234
1250
  }
1251
+
1252
+ // Re-project ROADMAP/PLAN markdown from the authoritative DB. Worktree DB
1253
+ // reconciliation during merge can leave main-branch markdown stale relative
1254
+ // to gsd.db (the 3M/3S/10T vs 3M/5S/16T drift class at /gsd startup).
1255
+ try {
1256
+ const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
1257
+ await rebuildMarkdownProjectionsFromDb(s.canonicalProjectRoot);
1258
+ if (s.basePath !== s.canonicalProjectRoot) {
1259
+ await rebuildMarkdownProjectionsFromDb(s.basePath);
1260
+ }
1261
+ } catch (e) {
1262
+ logWarning("engine", "markdown projection rebuild failed after milestone transition", { error: String(e) });
1263
+ }
1235
1264
  }
1236
1265
 
1237
1266
  if (mid) {
@@ -1458,6 +1487,7 @@ export async function runDispatch(
1458
1487
  // Checking a stale-narrowed set causes false transport-preflight warnings
1459
1488
  // that repeat on every /gsd auto resume (#477 follow-up).
1460
1489
  const activeTools = getToolBaselineSnapshot(pi);
1490
+ const registeredTools = getRegisteredToolSnapshot(pi);
1461
1491
  // Deep planning intentionally keeps human checkpoints in plain chat. In
1462
1492
  // Claude Code/local MCP transports, structured question requests can be
1463
1493
  // cancelled outside the normal chat flow, which made approval gates easy to
@@ -1482,6 +1512,7 @@ export async function runDispatch(
1482
1512
  sessionProvider: ctx.model?.provider,
1483
1513
  modelRegistry: ctx.modelRegistry as MinimalModelRegistry | undefined,
1484
1514
  activeTools,
1515
+ registeredTools,
1485
1516
  sessionBaseUrl: ctx.model?.baseUrl,
1486
1517
  sessionAuthMode: authMode,
1487
1518
  });
@@ -1508,6 +1539,7 @@ export async function runDispatch(
1508
1539
  sessionProvider: ctx.model?.provider,
1509
1540
  modelRegistry: ctx.modelRegistry as MinimalModelRegistry | undefined,
1510
1541
  activeTools,
1542
+ registeredTools,
1511
1543
  sessionBaseUrl: ctx.model?.baseUrl,
1512
1544
  sessionAuthMode: authMode,
1513
1545
  });
@@ -130,7 +130,8 @@ export async function runUnit(
130
130
  unitId,
131
131
  error: msg,
132
132
  });
133
- return { status: "cancelled", errorContext: { message: `Session creation failed: ${msg}`, category: "session-failed", isTransient: true } };
133
+ const isStructural = sessionErr instanceof TypeError || /is not a function/i.test(msg);
134
+ return { status: "cancelled", errorContext: { message: `Session creation failed: ${msg}`, category: "session-failed", isTransient: !isStructural } };
134
135
  }
135
136
  if (sessionTimeoutHandle) clearTimeout(sessionTimeoutHandle);
136
137
 
@@ -29,6 +29,7 @@ import { resolveWorktreeProjectRoot } from "../worktree-root.js";
29
29
  import { normalizeRealPath } from "../paths.js";
30
30
  import type { MilestoneScope } from "../workspace.js";
31
31
  import type { RootDirtySnapshot } from "../root-write-leak-guard.js";
32
+ import type { MilestoneSettlementOutcome } from "../milestone-settlement.js";
32
33
 
33
34
  // ─── Exported Types ──────────────────────────────────────────────────────────
34
35
 
@@ -230,6 +231,8 @@ export class AutoSession {
230
231
  /** Set to true after phases.ts successfully calls mergeAndExit, so that
231
232
  * stopAuto does not attempt the same merge a second time (#2645). */
232
233
  milestoneMergedInPhases = false;
234
+ /** Last milestone settlement result observed by Auto Orchestration. */
235
+ milestoneSettlement: MilestoneSettlementOutcome | null = null;
233
236
 
234
237
  // #4765 — slice-cadence collapse: main-branch SHAs at the moment each
235
238
  // milestone's first slice merge began. Used by resquashMilestoneOnMain at
@@ -410,6 +413,7 @@ export class AutoSession {
410
413
  this.strandedRecoveryIsolationMode = null;
411
414
  this.rootWriteBaseline = null;
412
415
  this.milestoneMergedInPhases = false;
416
+ this.milestoneSettlement = null;
413
417
  this.milestoneStartShas = new Map();
414
418
  this.checkpointSha = null;
415
419