@opengsd/gsd-pi 1.2.0-dev.955e4da0 → 1.2.0-dev.9ad8ae33

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 (575) hide show
  1. package/dist/cli-style.d.ts +17 -0
  2. package/dist/cli-style.js +28 -0
  3. package/dist/cli.js +1 -1
  4. package/dist/headless-events.d.ts +4 -2
  5. package/dist/headless-events.js +14 -34
  6. package/dist/mcp-server.js +2 -1
  7. package/dist/models-resolver.d.ts +3 -13
  8. package/dist/models-resolver.js +3 -22
  9. package/dist/resource-loader.d.ts +10 -5
  10. package/dist/resource-loader.js +123 -20
  11. package/dist/resources/.managed-resources-content-hash +1 -1
  12. package/dist/resources/GSD-WORKFLOW.md +5 -4
  13. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  14. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  15. package/dist/resources/extensions/async-jobs/index.js +65 -0
  16. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  17. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  18. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  19. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  20. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  21. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  22. package/dist/resources/extensions/bg-shell/utilities.js +3 -0
  23. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  24. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  25. package/dist/resources/extensions/browser-tools/index.js +69 -12
  26. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +30 -4
  27. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  28. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  29. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  30. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  31. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  32. package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
  33. package/dist/resources/extensions/gsd/auto/phases.js +49 -6
  34. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  35. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  36. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  37. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  38. package/dist/resources/extensions/gsd/auto-post-unit.js +35 -8
  39. package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
  40. package/dist/resources/extensions/gsd/auto-start.js +41 -18
  41. package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
  42. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  43. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
  44. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  45. package/dist/resources/extensions/gsd/auto-worktree.js +44 -91
  46. package/dist/resources/extensions/gsd/auto.js +41 -14
  47. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  48. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
  49. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
  50. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  51. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  52. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +212 -48
  53. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +303 -77
  54. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  55. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  56. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  57. package/dist/resources/extensions/gsd/captures.js +4 -6
  58. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  59. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  60. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  61. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  62. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  63. package/dist/resources/extensions/gsd/constants.js +0 -2
  64. package/dist/resources/extensions/gsd/crash-recovery.js +12 -15
  65. package/dist/resources/extensions/gsd/db/queries.js +26 -0
  66. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  67. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  68. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  69. package/dist/resources/extensions/gsd/doctor-environment.js +2 -6
  70. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  71. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  72. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -15
  73. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  74. package/dist/resources/extensions/gsd/error-classifier.js +9 -0
  75. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  76. package/dist/resources/extensions/gsd/files.js +33 -19
  77. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  78. package/dist/resources/extensions/gsd/gsd-db.js +2 -1
  79. package/dist/resources/extensions/gsd/guidance.js +158 -0
  80. package/dist/resources/extensions/gsd/guided-flow.js +23 -5
  81. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  82. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  83. package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
  84. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  85. package/dist/resources/extensions/gsd/migrate/safety.js +4 -1
  86. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  87. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  88. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  89. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  90. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -4
  91. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  92. package/dist/resources/extensions/gsd/paths.js +27 -0
  93. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  94. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  95. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  96. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  97. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  98. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  99. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  100. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  101. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  102. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  103. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  104. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  105. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  106. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  107. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
  108. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  109. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  110. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  111. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  112. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  113. package/dist/resources/extensions/gsd/publication.js +87 -0
  114. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  115. package/dist/resources/extensions/gsd/recovery-classification.js +37 -94
  116. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  117. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  118. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  119. package/dist/resources/extensions/gsd/state.js +6 -20
  120. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  121. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  122. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  123. package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
  124. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  125. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  126. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
  127. package/dist/resources/extensions/gsd/tools/exec-tool.js +9 -7
  128. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
  129. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  130. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  131. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  132. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  133. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  134. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  135. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  136. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  137. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  138. package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
  139. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  140. package/dist/resources/extensions/gsd/unit-registry.js +337 -0
  141. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
  142. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  143. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  144. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  145. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  146. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  147. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  148. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  149. package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
  150. package/dist/resources/extensions/gsd/worktree-git-recovery.js +15 -9
  151. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  152. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  153. package/dist/resources/extensions/gsd/worktree-root.js +11 -0
  154. package/dist/resources/extensions/gsd/worktree-session-state.js +4 -5
  155. package/dist/resources/extensions/gsd/worktree.js +8 -1
  156. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  157. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  158. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  159. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  160. package/dist/resources/shared/package-manager-detection.js +1 -1
  161. package/dist/resources/shared/package.json +3 -0
  162. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  163. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  164. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  165. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  166. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  167. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  168. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  169. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  170. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  171. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  172. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  173. package/dist/update-check.d.ts +2 -0
  174. package/dist/update-check.js +24 -1
  175. package/dist/update-cmd.js +20 -3
  176. package/dist/web/standalone/.next/BUILD_ID +1 -1
  177. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  178. package/dist/web/standalone/.next/build-manifest.json +3 -3
  179. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  180. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  181. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  182. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  183. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  184. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  190. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  191. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  192. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  193. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  194. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  195. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  196. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  197. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/index.html +1 -1
  200. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  205. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  207. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  208. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  209. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  212. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  213. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  214. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  215. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  216. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  217. package/dist/web/standalone/package.json +1 -1
  218. package/dist/worktree-cli.js +3 -6
  219. package/dist/worktree-status-banner.js +7 -15
  220. package/package.json +2 -2
  221. package/packages/cloud-mcp-gateway/package.json +2 -2
  222. package/packages/contracts/dist/rpc.d.ts +1 -0
  223. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  224. package/packages/contracts/dist/rpc.js.map +1 -1
  225. package/packages/contracts/dist/workflow.d.ts +4 -0
  226. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  227. package/packages/contracts/dist/workflow.js.map +1 -1
  228. package/packages/contracts/package.json +1 -1
  229. package/packages/daemon/package.json +4 -4
  230. package/packages/gsd-agent-core/package.json +5 -5
  231. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  232. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  233. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  234. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  235. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  236. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  237. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  238. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  239. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  240. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  241. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  242. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  243. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  244. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  245. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  246. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  247. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  248. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  249. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  250. package/packages/gsd-agent-modes/package.json +7 -7
  251. package/packages/mcp-server/dist/cli.js +9 -1
  252. package/packages/mcp-server/dist/cli.js.map +1 -1
  253. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  254. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  255. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  256. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  257. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  258. package/packages/mcp-server/dist/server.js +4 -0
  259. package/packages/mcp-server/dist/server.js.map +1 -1
  260. package/packages/mcp-server/dist/workflow-tools.d.ts +26 -18
  261. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  262. package/packages/mcp-server/dist/workflow-tools.js +116 -39
  263. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  264. package/packages/mcp-server/package.json +5 -4
  265. package/packages/native/package.json +1 -1
  266. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  267. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  268. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  269. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  270. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  271. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  272. package/packages/pi-agent-core/dist/index.js +3 -0
  273. package/packages/pi-agent-core/dist/index.js.map +1 -1
  274. package/packages/pi-agent-core/package.json +1 -1
  275. package/packages/pi-ai/README.md +1 -0
  276. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  277. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  278. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  279. package/packages/pi-ai/dist/index.d.ts +2 -0
  280. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  281. package/packages/pi-ai/dist/index.js +2 -0
  282. package/packages/pi-ai/dist/index.js.map +1 -1
  283. package/packages/pi-ai/dist/models.generated.d.ts +35 -125
  284. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  285. package/packages/pi-ai/dist/models.generated.js +46 -120
  286. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  287. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  288. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  289. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  290. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  291. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  292. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  293. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  294. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  295. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  296. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  297. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  298. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  299. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  300. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  301. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  302. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  303. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  304. package/packages/pi-ai/package.json +3 -2
  305. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  306. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  307. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  308. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  311. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  313. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  315. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  317. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/index.js +1 -1
  319. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  321. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  323. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  324. package/packages/pi-coding-agent/package.json +7 -7
  325. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  326. package/packages/pi-tui/dist/tui.js +9 -0
  327. package/packages/pi-tui/dist/tui.js.map +1 -1
  328. package/packages/pi-tui/package.json +2 -2
  329. package/packages/rpc-client/package.json +2 -2
  330. package/pkg/package.json +1 -1
  331. package/src/resources/GSD-WORKFLOW.md +5 -4
  332. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  333. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  334. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  335. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  336. package/src/resources/extensions/async-jobs/index.ts +79 -0
  337. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  338. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  339. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  340. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  341. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  342. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  343. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  344. package/src/resources/extensions/bg-shell/utilities.ts +3 -0
  345. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  346. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  347. package/src/resources/extensions/browser-tools/index.ts +71 -13
  348. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  349. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  350. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  351. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +34 -4
  352. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  353. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  354. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  355. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  356. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  357. package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
  358. package/src/resources/extensions/gsd/auto/phases.ts +65 -26
  359. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  360. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  361. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  362. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  363. package/src/resources/extensions/gsd/auto-post-unit.ts +40 -8
  364. package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
  365. package/src/resources/extensions/gsd/auto-start.ts +42 -21
  366. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  367. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  368. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
  369. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  370. package/src/resources/extensions/gsd/auto-worktree.ts +44 -94
  371. package/src/resources/extensions/gsd/auto.ts +52 -16
  372. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  373. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
  374. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
  375. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  376. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  377. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +251 -47
  378. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +352 -84
  379. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  380. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  381. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  382. package/src/resources/extensions/gsd/captures.ts +4 -6
  383. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  384. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  385. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  386. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  387. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  388. package/src/resources/extensions/gsd/constants.ts +0 -3
  389. package/src/resources/extensions/gsd/crash-recovery.ts +13 -11
  390. package/src/resources/extensions/gsd/db/queries.ts +37 -0
  391. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  392. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  393. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  394. package/src/resources/extensions/gsd/doctor-environment.ts +2 -7
  395. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  396. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  397. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +13 -15
  398. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  399. package/src/resources/extensions/gsd/error-classifier.ts +11 -0
  400. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  401. package/src/resources/extensions/gsd/files.ts +33 -12
  402. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  403. package/src/resources/extensions/gsd/gsd-db.ts +4 -3
  404. package/src/resources/extensions/gsd/guidance.ts +217 -0
  405. package/src/resources/extensions/gsd/guided-flow.ts +37 -28
  406. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  407. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  408. package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
  409. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  410. package/src/resources/extensions/gsd/migrate/safety.ts +4 -1
  411. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  412. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  413. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  414. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  415. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -4
  416. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  417. package/src/resources/extensions/gsd/paths.ts +33 -0
  418. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  419. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  420. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  421. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  422. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  423. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  424. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  425. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  426. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  427. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  428. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  429. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  430. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  431. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  432. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
  433. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  434. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  435. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  436. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  437. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  438. package/src/resources/extensions/gsd/publication.ts +122 -0
  439. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  440. package/src/resources/extensions/gsd/recovery-classification.ts +42 -96
  441. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  442. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  443. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  444. package/src/resources/extensions/gsd/state.ts +9 -21
  445. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  446. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  447. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
  448. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  449. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  450. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  451. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  452. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  453. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  454. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  455. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
  456. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
  457. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  458. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  459. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  460. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  461. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  462. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  463. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  464. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  465. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  466. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  467. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  468. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  469. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  470. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  471. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  472. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  473. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  474. package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
  475. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
  476. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +53 -11
  477. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +73 -58
  478. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  479. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  480. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  481. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  482. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  483. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  484. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  485. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  486. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
  487. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  488. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  489. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  490. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  491. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  492. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  493. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +157 -0
  494. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  495. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -1
  496. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  497. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  498. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  499. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  500. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
  501. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  502. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  503. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  504. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  505. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
  506. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  507. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  508. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  509. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  510. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  511. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  512. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  513. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
  514. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  515. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  516. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  517. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  518. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  519. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  520. package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
  521. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  522. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  523. package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
  524. package/src/resources/extensions/gsd/tools/exec-tool.ts +8 -7
  525. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
  526. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  527. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  528. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  529. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  530. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  531. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  532. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  533. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  534. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  535. package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
  536. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  537. package/src/resources/extensions/gsd/unit-registry.ts +412 -0
  538. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
  539. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  540. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  541. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  542. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  543. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  544. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  545. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  546. package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
  547. package/src/resources/extensions/gsd/worktree-git-recovery.ts +15 -9
  548. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  549. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  550. package/src/resources/extensions/gsd/worktree-root.ts +12 -0
  551. package/src/resources/extensions/gsd/worktree-session-state.ts +3 -5
  552. package/src/resources/extensions/gsd/worktree.ts +7 -1
  553. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  554. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  555. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  556. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  557. package/src/resources/shared/package-manager-detection.ts +1 -1
  558. package/src/resources/shared/package.json +3 -0
  559. package/src/resources/skills/create-skill/SKILL.md +3 -0
  560. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  561. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  562. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  563. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  564. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  565. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  566. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  567. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  568. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  569. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  570. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  571. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  572. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  573. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  574. /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_buildManifest.js +0 -0
  575. /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_ssgManifest.js +0 -0
@@ -12,7 +12,7 @@
12
12
  import { debugCount, debugLog, debugTime } from "../debug-logger.js";
13
13
  import { reconcileBeforeDispatch } from "../state-reconciliation.js";
14
14
  import { isLegalEdge, IllegalPhaseTransitionError } from "../state-transition-matrix.js";
15
- import { resolveDispatch } from "../auto-dispatch.js";
15
+ import { hasPendingDeepStage, resolveDispatch } from "../auto-dispatch.js";
16
16
  import { classifyFailure } from "../recovery-classification.js";
17
17
  import { verifyExpectedArtifact, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
18
18
  import { invalidateAllCaches } from "../cache.js";
@@ -42,21 +42,14 @@ import { isDbAvailable, getSlice, getTask, } from "../gsd-db.js";
42
42
  import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
43
43
  import { getErrorMessage } from "../error-utils.js";
44
44
  import { logWarning } from "../workflow-logger.js";
45
+ import { normalizeRealPath } from "../paths.js";
46
+ import { buildDispatchKey, createDispatchHistory, STUCK_WINDOW_SIZE, } from "./dispatch-history.js";
45
47
  import { existsSync, readFileSync } from "node:fs";
46
48
  import { join } from "node:path";
47
49
  import { evaluateAllCompleteSettlement } from "../milestone-settlement.js";
48
50
  function now() {
49
51
  return Date.now();
50
52
  }
51
- /**
52
- * Size of the dispatch-decision ring buffer used by the Auto Orchestration
53
- * module's stuck-loop detector. When the same `${unitType}:${unitId}` key
54
- * fills the window, advance() blocks with `action: "stop"`.
55
- *
56
- * Mirrors the legacy `STUCK_WINDOW_SIZE` in auto/phases.ts so behaviour is
57
- * preserved across the eventual cutover (issue #5791).
58
- */
59
- export const STUCK_WINDOW_SIZE = 6;
60
53
  function noRemainingUnitsOutcome(stateSnapshot) {
61
54
  if (stateSnapshot.phase === "complete") {
62
55
  return {
@@ -118,14 +111,25 @@ function shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath
118
111
  export async function decideOrchestratorDispatch(ctx, pi, dispatchBasePath, session, input) {
119
112
  const state = input.stateSnapshot;
120
113
  const active = state.activeMilestone;
121
- if (!active)
122
- return null;
123
114
  const activeSession = input.session ?? session;
124
115
  const activeDispatchBasePath = activeSession?.basePath || dispatchBasePath;
125
- if (activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
116
+ const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
117
+ if (!active) {
118
+ if (state.phase !== "pre-planning")
119
+ return null;
120
+ if (!hasPendingDeepStage(prefs, activeDispatchBasePath)) {
121
+ return {
122
+ kind: "blocked",
123
+ reason: state.nextAction || "No active milestone. Run /gsd unpark <id> or create a new milestone.",
124
+ action: "stop",
125
+ };
126
+ }
127
+ }
128
+ if (active && activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
126
129
  activeSession.currentMilestoneId = active.id;
127
130
  }
128
- const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
131
+ const dispatchMid = active?.id ?? activeSession?.currentMilestoneId ?? "";
132
+ const dispatchMidTitle = active?.title ?? "";
129
133
  // Derive session-derived dispatch inputs the same way phases.ts:runDispatch does
130
134
  // (#5789). Prefer caller-supplied values when present so test harnesses and
131
135
  // alternative wirings can inject deterministic snapshots; otherwise pull from
@@ -153,8 +157,15 @@ export async function decideOrchestratorDispatch(ctx, pi, dispatchBasePath, sess
153
157
  })
154
158
  ? "true"
155
159
  : "false");
160
+ // Only replay a milestone-scoped verification retry when a milestone is
161
+ // active. Pre-PR (#712 fix), `!active` returned null before reaching this
162
+ // block, so the retry was preserved for a future tick. The new
163
+ // pre-planning + deep-pending fall-through must keep that contract:
164
+ // otherwise a stale execute-task / complete-slice / complete-milestone
165
+ // retry whose target milestone has since been parked would preempt
166
+ // project-level deep rules like `discuss-project`.
156
167
  const pendingRetry = session?.pendingVerificationRetryDispatch;
157
- if (session && pendingRetry) {
168
+ if (session && pendingRetry && active) {
158
169
  session.pendingVerificationRetryDispatch = null;
159
170
  const alreadyClosedReason = getAlreadyClosedDispatchReason(pendingRetry.unitType, pendingRetry.unitId);
160
171
  if (alreadyClosedReason) {
@@ -172,8 +183,8 @@ export async function decideOrchestratorDispatch(ctx, pi, dispatchBasePath, sess
172
183
  }
173
184
  const action = await resolveDispatch({
174
185
  basePath: activeDispatchBasePath,
175
- mid: active.id,
176
- midTitle: active.title,
186
+ mid: dispatchMid,
187
+ midTitle: dispatchMidTitle,
177
188
  state,
178
189
  prefs,
179
190
  session: activeSession,
@@ -218,8 +229,8 @@ export async function decideOrchestratorDispatch(ctx, pi, dispatchBasePath, sess
218
229
  prompt: action.prompt,
219
230
  pauseAfterUatDispatch: action.pauseAfterDispatch ?? false,
220
231
  state,
221
- mid: active.id,
222
- midTitle: active.title,
232
+ mid: dispatchMid,
233
+ midTitle: dispatchMidTitle,
223
234
  };
224
235
  session.pendingOrchestrationDispatch = pending;
225
236
  }
@@ -244,7 +255,9 @@ export class AutoOrchestrator {
244
255
  seq = 0;
245
256
  lastAdvanceKey = null;
246
257
  lastFinalizedUnitKey = null;
247
- dispatchKeyWindow = [];
258
+ // Dispatch History module (#482): the dispatch-decision window with
259
+ // cross-session DB rehydration and full detect-stuck rules.
260
+ dispatchHistory;
248
261
  // ADR-030 Phase Transition Invariant: the prior advance's reconciled Phase,
249
262
  // the "from" endpoint of the edge check. In-memory; reset on start/resume/stop
250
263
  // so the first advance of a session has no edge to assert.
@@ -260,6 +273,13 @@ export class AutoOrchestrator {
260
273
  this.runtimeBasePath = context.runtimeBasePath;
261
274
  this.s = context.session;
262
275
  this.flowId = `auto-orchestrator-${Date.now()}`;
276
+ this.dispatchHistory = createDispatchHistory({
277
+ windowSize: STUCK_WINDOW_SIZE,
278
+ // Same stable scope the auto-loop uses for stuck-state persistence so
279
+ // rehydration reads the rows the dispatch ledger wrote for this project.
280
+ resolveScopeId: () => normalizeRealPath(this.s.scope?.workspace.projectRoot ??
281
+ (this.s.originalBasePath || this.s.basePath || this.runtimeBasePath)) || null,
282
+ });
263
283
  }
264
284
  // ── Live base-path resolution (was the wiring factory's getLiveDispatchBasePath) ──
265
285
  getLiveDispatchBasePath() {
@@ -612,7 +632,7 @@ export class AutoOrchestrator {
612
632
  * skipped result) instead of stopping.
613
633
  */
614
634
  tryStuckArtifactRecovery(unitType, unitId) {
615
- const key = `${unitType}:${unitId}`;
635
+ const key = buildDispatchKey(unitType, unitId);
616
636
  if (this.lastStuckRecoveryKey === key)
617
637
  return false; // already tried this episode
618
638
  const basePath = this.getLiveDispatchBasePath();
@@ -627,7 +647,7 @@ export class AutoOrchestrator {
627
647
  return false;
628
648
  this.lastStuckRecoveryKey = key;
629
649
  invalidateAllCaches();
630
- this.dispatchKeyWindow = [];
650
+ this.dispatchHistory.clearOnRecovery();
631
651
  this.lastAdvanceKey = null;
632
652
  this.lastFinalizedUnitKey = null;
633
653
  return true;
@@ -653,7 +673,12 @@ export class AutoOrchestrator {
653
673
  async start(_sessionContext) {
654
674
  this.lastAdvanceKey = null;
655
675
  this.lastFinalizedUnitKey = null;
656
- this.dispatchKeyWindow = [];
676
+ // #482: the DB dispatch ledger is the source of truth across sessions.
677
+ // Discard any in-memory window and rebuild it from the ledger so a unit
678
+ // that was re-dispatched in previous sessions is detected as stuck here
679
+ // instead of silently re-dispatching forever.
680
+ this.dispatchHistory.clearOnRecovery();
681
+ this.dispatchHistory.rehydrate();
657
682
  this.lastStuckRecoveryKey = null;
658
683
  this.lastDerivedPhase = null;
659
684
  this.status.phase = "running";
@@ -753,7 +778,7 @@ export class AutoOrchestrator {
753
778
  this.status.phase = "paused";
754
779
  this.status.activeUnit = undefined;
755
780
  this.lastAdvanceKey = null;
756
- this.dispatchKeyWindow = [];
781
+ this.dispatchHistory.clearOnRecovery();
757
782
  this.bumpTransition();
758
783
  this.journalTransition({ name: "advance-blocked", reason: settlementBlock.reason });
759
784
  this.postAdvanceRecord(settlementBlock);
@@ -769,7 +794,7 @@ export class AutoOrchestrator {
769
794
  this.status.phase = "stopped";
770
795
  this.status.activeUnit = undefined;
771
796
  this.lastAdvanceKey = null;
772
- this.dispatchKeyWindow = [];
797
+ this.dispatchHistory.clearOnRecovery();
773
798
  this.bumpTransition();
774
799
  this.journalTransition({ name: "advance-stopped", reason: stopped.reason });
775
800
  this.postAdvanceRecord(stopped);
@@ -817,16 +842,12 @@ export class AutoOrchestrator {
817
842
  this.postAdvanceRecord(blocked);
818
843
  return blocked;
819
844
  }
820
- const nextKey = `${decision.unitType}:${decision.unitId}`;
821
- // Record every dispatch decision in the ring buffer before pre-flight
845
+ // Record every dispatch decision in the history window before pre-flight
822
846
  // checks so the stuck-loop detector observes the full decision history
823
847
  // (including decisions that idempotency would otherwise short-circuit).
824
- // The ring is capped at STUCK_WINDOW_SIZE and evicts oldest-first.
825
- this.dispatchKeyWindow.push(nextKey);
826
- if (this.dispatchKeyWindow.length > STUCK_WINDOW_SIZE) {
827
- this.dispatchKeyWindow.shift();
828
- }
829
- const matchingCount = this.dispatchKeyWindow.filter((k) => k === nextKey).length;
848
+ // The window is capped at STUCK_WINDOW_SIZE and evicts oldest-first.
849
+ const nextKey = this.dispatchHistory.recordDispatch(decision.unitType, decision.unitId);
850
+ const matchingCount = this.dispatchHistory.countMatching(nextKey);
830
851
  if (this.lastFinalizedUnitKey === nextKey) {
831
852
  // #442: the unit re-dispatched immediately after finalizing may have
832
853
  // actually completed on disk with a stale DB. Verify + recover before
@@ -858,22 +879,30 @@ export class AutoOrchestrator {
858
879
  // checks coexist: idempotency for the common immediate-repeat case,
859
880
  // stuck-loop for the saturated-window case.
860
881
  if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
882
+ // Unit already active — benign no-op. Return skipped so the loop re-polls
883
+ // without cancelling the in-flight unit (blocked+pause would force-cancel it).
861
884
  this.clearPendingDispatch();
862
- const blocked = { kind: "blocked", reason: "idempotent advance: unit already active", action: "pause" };
885
+ const skipped = { kind: "skipped", reason: "idempotent advance: unit already active" };
863
886
  this.journalTransition({
864
- name: "advance-blocked",
865
- reason: blocked.reason,
887
+ name: "advance-skipped",
888
+ reason: skipped.reason,
866
889
  unitType: decision.unitType,
867
890
  unitId: decision.unitId,
868
891
  });
869
- this.postAdvanceRecord(blocked);
870
- return blocked;
892
+ this.postAdvanceRecord(skipped);
893
+ return skipped;
871
894
  }
872
- // Stuck-loop detection: when the ring is saturated with copies of
873
- // `nextKey` (count >= STUCK_WINDOW_SIZE), the orchestrator has been
874
- // picking the same unit across the whole window and must hard-stop with
875
- // a diagnosable reason.
876
- if (matchingCount >= STUCK_WINDOW_SIZE) {
895
+ // Stuck-loop detection: when the window is saturated with copies of
896
+ // `nextKey` (count >= STUCK_WINDOW_SIZE), consult the Dispatch History
897
+ // module's full detect-stuck rule set for the verdict instead of the old
898
+ // bare saturation count. This keeps the saturation threshold (the window
899
+ // deliberately records benign idempotent repeats, so earlier-firing
900
+ // rules would false-positive on pause/resume re-advances) while gaining
901
+ // retry-budget suppression and diagnosable rule reasons. A saturated
902
+ // window with no verdict means the dispatch ledger says we are inside
903
+ // the unit's retry-backoff budget — let the retry proceed.
904
+ const stuckVerdict = matchingCount >= STUCK_WINDOW_SIZE ? this.dispatchHistory.detectStuck() : null;
905
+ if (stuckVerdict) {
877
906
  // #442: before declaring a stuck loop, verify the unit didn't actually
878
907
  // complete on disk (stale DB) and recover if so — legacy graduated
879
908
  // stuck-recovery parity. Otherwise hard-stop with a diagnosable reason.
@@ -884,7 +913,7 @@ export class AutoOrchestrator {
884
913
  this.clearPendingDispatch();
885
914
  const blocked = {
886
915
  kind: "blocked",
887
- reason: `stuck-loop: ${nextKey} picked ${matchingCount} times`,
916
+ reason: `stuck-loop: ${stuckVerdict.reason}`,
888
917
  action: "stop",
889
918
  };
890
919
  this.journalTransition({
@@ -974,7 +1003,7 @@ export class AutoOrchestrator {
974
1003
  if (result.kind === "stopped") {
975
1004
  this.lastAdvanceKey = null;
976
1005
  this.lastFinalizedUnitKey = null;
977
- this.dispatchKeyWindow = [];
1006
+ this.dispatchHistory.clearOnRecovery();
978
1007
  this.status.activeUnit = undefined;
979
1008
  }
980
1009
  this.bumpTransition();
@@ -1003,8 +1032,14 @@ export class AutoOrchestrator {
1003
1032
  async resume() {
1004
1033
  this.lastAdvanceKey = null;
1005
1034
  this.lastFinalizedUnitKey = null;
1006
- // Preserve dispatchKeyWindow across resume so stuck-loop detection
1007
- // accumulates across pause/resume cycles rather than resetting each time.
1035
+ // Preserve the dispatch-history window across an in-process resume so
1036
+ // stuck-loop detection accumulates across pause/resume cycles rather than
1037
+ // resetting each time (#572 regression). When the window is empty (fresh
1038
+ // orchestrator resuming a prior session), rehydrate it from the DB
1039
+ // dispatch ledger so cross-session re-dispatch loops are detected (#482).
1040
+ if (this.dispatchHistory.getRecentWindow().length === 0) {
1041
+ this.dispatchHistory.rehydrate();
1042
+ }
1008
1043
  this.lastStuckRecoveryKey = null;
1009
1044
  // ADR-030: drop the prior "from" — the first advance after resume has no
1010
1045
  // edge to assert (avoids a false illegal-edge across the pause boundary).
@@ -1025,10 +1060,10 @@ export class AutoOrchestrator {
1025
1060
  this.lastAdvanceKey = null;
1026
1061
  this.lastFinalizedUnitKey = null;
1027
1062
  this.lastDerivedPhase = null;
1028
- // Preserve dispatchKeyWindow on pause so stuck-loop detection accumulates
1029
- // across pause/resume cycles. Only clear on a hard stop.
1063
+ // Preserve the dispatch-history window on pause so stuck-loop detection
1064
+ // accumulates across pause/resume cycles. Only clear on a hard stop.
1030
1065
  if (reason !== "pause") {
1031
- this.dispatchKeyWindow = [];
1066
+ this.dispatchHistory.clearOnRecovery();
1032
1067
  }
1033
1068
  this.lastStuckRecoveryKey = null;
1034
1069
  this.bumpTransition();
@@ -1040,9 +1075,9 @@ export class AutoOrchestrator {
1040
1075
  return { ...this.status, activeUnit: this.status.activeUnit ? { ...this.status.activeUnit } : undefined };
1041
1076
  }
1042
1077
  async completeActiveUnit(unit) {
1043
- const unitKey = `${unit.unitType}:${unit.unitId}`;
1078
+ const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
1044
1079
  const activeUnitKey = this.status.activeUnit
1045
- ? `${this.status.activeUnit.unitType}:${this.status.activeUnit.unitId}`
1080
+ ? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
1046
1081
  : null;
1047
1082
  if (activeUnitKey !== unitKey)
1048
1083
  return;
@@ -1059,9 +1094,9 @@ export class AutoOrchestrator {
1059
1094
  });
1060
1095
  }
1061
1096
  async retryActiveUnit(unit) {
1062
- const unitKey = `${unit.unitType}:${unit.unitId}`;
1097
+ const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
1063
1098
  const activeUnitKey = this.status.activeUnit
1064
- ? `${this.status.activeUnit.unitType}:${this.status.activeUnit.unitId}`
1099
+ ? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
1065
1100
  : null;
1066
1101
  if (activeUnitKey !== unitKey && this.lastFinalizedUnitKey !== unitKey)
1067
1102
  return;
@@ -10,10 +10,11 @@
10
10
  */
11
11
  import { importExtensionModule } from "@gsd/pi-coding-agent";
12
12
  import { USER_DRIVEN_DEEP_UNITS, isAwaitingUserInput, } from "../auto-post-unit.js";
13
- import { lastAssistantText } from "../user-input-boundary.js";
14
- import { resolveEffectiveUnitIsolationMode } from "../preferences.js";
13
+ import { lastAssistantText } from "../consent-question.js";
14
+ import { resolveEffectiveUnitIsolationMode, getIsolationMode } from "../preferences.js";
15
15
  import { MAX_RECOVERY_CHARS, BUDGET_THRESHOLDS, MAX_FINALIZE_TIMEOUTS, } from "./types.js";
16
16
  import { detectStuck } from "./detect-stuck.js";
17
+ import { STUCK_WINDOW_SIZE } from "./dispatch-history.js";
17
18
  import { runUnit } from "./run-unit.js";
18
19
  import { debugLog } from "../debug-logger.js";
19
20
  import { resolveWorktreeProjectRoot, normalizeWorktreePathForCompare } from "../worktree-root.js";
@@ -34,9 +35,10 @@ import { writeUnitRuntimeRecord } from "../unit-runtime.js";
34
35
  import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "./finalize-timeout.js";
35
36
  import { getEligibleSlices } from "../slice-parallel-eligibility.js";
36
37
  import { isSliceParallelActive, startSliceParallel } from "../slice-parallel-orchestrator.js";
37
- import { isDbAvailable, getMilestoneSlices, getSlice, getTask } from "../gsd-db.js";
38
+ import { isDbAvailable, getMilestone, getMilestoneSlices, getSlice, getTask } from "../gsd-db.js";
38
39
  import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
39
40
  import { isClosedStatus } from "../status-guards.js";
41
+ import { findUnmergedCompletedMilestones } from "../unmerged-milestone-guard.js";
40
42
  import { setRuntimeKv } from "../db/runtime-kv.js";
41
43
  import { getLatestForUnit } from "../db/unit-dispatches.js";
42
44
  import { reconcileBeforeSpawn } from "../state-reconciliation.js";
@@ -49,7 +51,8 @@ import { parseUnitId } from "../unit-id.js";
49
51
  import { createCheckpoint, cleanupCheckpoint, rollbackToCheckpoint } from "../safety/git-checkpoint.js";
50
52
  import { resolveSafetyHarnessConfig } from "../safety/safety-harness.js";
51
53
  import { getContextPauseAction } from "../auto-budget.js";
52
- import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit, supportsStructuredQuestions, } from "../workflow-mcp.js";
54
+ import { supportsStructuredQuestions } from "../workflow-mcp.js";
55
+ import { getUnitWorkflowDispatchReadinessError } from "../tool-contract.js";
53
56
  import { prepareWorkflowMcpForProject } from "../workflow-mcp-auto-prep.js";
54
57
  import { applyThinkingLevelForModel, floorThinkingLevelForUnit, getRegisteredToolSnapshot, getToolBaselineSnapshot, } from "../auto-model-selection.js";
55
58
  import { resolveManifest } from "../unit-context-manifest.js";
@@ -60,7 +63,6 @@ import { buildPhaseHandoffOutcome, setAutoActiveStatus, setAutoOutcomeWidget } f
60
63
  import { getConsecutiveDispatchBlocker } from "../dispatch-guard.js";
61
64
  import { captureRootDirtySnapshot, detectRootWriteLeak, formatRootWriteLeakMessage, } from "../root-write-leak-guard.js";
62
65
  import { classifyError, isTransient } from "../error-classifier.js";
63
- export const STUCK_WINDOW_SIZE = 6;
64
66
  const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
65
67
  const ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE = /^(?:api error(?::|$|\s*\()|provider error(?::|$|\s*\()|request failed\b|(?:http\s*)?(?:429|500|502|503)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|socket hang up\b|fetch failed\b|(?:network|connection|server) error(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|dns\b.*(?:fail|error|timeout)|unexpected eof\b|stream idle timeout\b|partial response received\b|stream_exhausted\b|terminated(?::|$)|(?:connection|stream|request)\b.{0,40}\bterminated\b|other side closed\b|rate.?limit(?:ed| exceeded| reached| error)|too many requests\b|you(?:'ve| have) (?:hit|reached) your (?:\w+ )?limit\b|.*\b(?:usage|session|weekly|daily|monthly|quota) limit\b|limit\b.{0,40}\bresets?\b|out of extra usage\b|service.?unavailable\b|internal(?: server)? error(?::|$)|internal(?:[_-]server)?[_-]error\b|server[_-]error\b|(?:provider|server|api|model|codex|claude|openai|anthropic|gemini)\b.{0,80}\boverloaded\b|overloaded\b.{0,80}\b(?:provider|server|api|model)\b|context (?:window|length) exceed|context window exceed)/i;
66
68
  const ZERO_TOOL_PROVIDER_ERROR_SIGNAL_RE = /(?:\b(?:http|status(?: code)?|code|error:)\s*(?:429|500|502|503)\b|\b(?:api|provider) error\s*[:(]?\s*(?:429|500|502|503)\b|\b(?:typeerror|error):\s*(?:fetch failed\b|socket hang up\b|terminated(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|(?:network|connection|server) error(?::|$)|stream idle timeout\b|partial response received\b|unexpected eof\b)|\b(?:server_error|api_error|stream_exhausted(?:_without_result)?)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|context (?:window|length) exceed|context window exceed)/i;
@@ -600,6 +602,36 @@ async function failClosedOnFinalizeTimeout(ic, iterData, loopState, stage, start
600
602
  drainLogs();
601
603
  return { action: "break", reason: progressKind };
602
604
  }
605
+ export async function shouldSkipTerminalMilestoneCloseout(s, state, mid) {
606
+ const closeoutMilestoneId = mid ?? s.currentMilestoneId ?? state.lastCompletedMilestone?.id;
607
+ if (s.completionStopInProgress) {
608
+ return { skip: true, milestoneId: closeoutMilestoneId };
609
+ }
610
+ if (!closeoutMilestoneId) {
611
+ return { skip: false };
612
+ }
613
+ if (isDbAvailable())
614
+ refreshWorkflowDatabaseFromDisk();
615
+ const closeoutBasePath = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
616
+ let closeoutMergePending = false;
617
+ if (getIsolationMode(closeoutBasePath) !== "none") {
618
+ try {
619
+ const blockers = await findUnmergedCompletedMilestones(closeoutBasePath);
620
+ closeoutMergePending = blockers.some((blocker) => blocker.milestoneId === closeoutMilestoneId);
621
+ }
622
+ catch {
623
+ // Fail open: without git/DB inspection we cannot safely treat closeout as done.
624
+ closeoutMergePending = true;
625
+ }
626
+ }
627
+ const milestoneAlreadyClosedOut = isDbAvailable()
628
+ && isClosedStatus(getMilestone(closeoutMilestoneId)?.status ?? "")
629
+ && !closeoutMergePending;
630
+ if (milestoneAlreadyClosedOut) {
631
+ return { skip: true, milestoneId: closeoutMilestoneId };
632
+ }
633
+ return { skip: false, milestoneId: closeoutMilestoneId };
634
+ }
603
635
  // ─── runPreDispatch ───────────────────────────────────────────────────────────
604
636
  /**
605
637
  * Phase 1: Pre-dispatch — resource guard, health gate, state derivation,
@@ -962,6 +994,13 @@ export async function runPreDispatch(ic, loopState) {
962
994
  deps.setActiveMilestoneId(s.basePath, mid);
963
995
  }
964
996
  // ── Terminal conditions ──────────────────────────────────────────────
997
+ if (state.phase === "complete") {
998
+ const closeoutSkip = await shouldSkipTerminalMilestoneCloseout(s, state, mid);
999
+ if (closeoutSkip.skip) {
1000
+ debugLog("autoLoop", { phase: "complete", reason: "milestone-already-closed", milestoneId: closeoutSkip.milestoneId });
1001
+ return { action: "break", reason: "milestone-complete" };
1002
+ }
1003
+ }
965
1004
  if (!mid) {
966
1005
  if (s.currentUnit) {
967
1006
  await deps.closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, deps.buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
@@ -1769,7 +1808,8 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
1769
1808
  s.currentDispatchedModelId = s.currentUnitModel
1770
1809
  ? `${s.currentUnitModel.provider ?? ""}/${s.currentUnitModel.id ?? ""}`
1771
1810
  : null;
1772
- const compatibilityError = getWorkflowTransportSupportError(s.currentUnitModel?.provider ?? ctx.model?.provider, getRequiredWorkflowToolsForAutoUnit(unitType), {
1811
+ const compatibilityError = getUnitWorkflowDispatchReadinessError({
1812
+ provider: s.currentUnitModel?.provider ?? ctx.model?.provider,
1773
1813
  projectRoot: s.basePath,
1774
1814
  surface: "auto-mode",
1775
1815
  unitType,
@@ -1848,6 +1888,9 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
1848
1888
  causedBy: "unit-start",
1849
1889
  });
1850
1890
  s.lastToolInvocationError = null; // #2883: clear stale error from previous unit
1891
+ if (nextDispatchCount <= 1) {
1892
+ s.toolUnavailableRetries = 0;
1893
+ }
1851
1894
  const unitStartSeq = ic.nextSeq();
1852
1895
  deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: unitStartSeq, eventType: "unit-start", data: { unitType, unitId } });
1853
1896
  deps.captureAvailableSkills();
@@ -126,6 +126,8 @@ export class AutoSession {
126
126
  /** Set when a GSD tool execution ends with isError due to malformed/truncated
127
127
  * JSON arguments. Checked by postUnitPreVerification to break retry loops. */
128
128
  lastToolInvocationError = null;
129
+ /** Consecutive tool-unavailable retries for the current unit (MCP startup race). */
130
+ toolUnavailableRetries = 0;
129
131
  /** Agent-end messages from the just-finished unit, consumed during finalize. */
130
132
  lastUnitAgentEndMessages = null;
131
133
  /** Set when turn-level git action fails during closeout. */
@@ -306,6 +308,7 @@ export class AutoSession {
306
308
  this.lastPreExecFailure = null;
307
309
  this.preExecRetryCount.clear();
308
310
  this.lastToolInvocationError = null;
311
+ this.toolUnavailableRetries = 0;
309
312
  this.lastUnitAgentEndMessages = null;
310
313
  this.lastGitActionFailure = null;
311
314
  this.lastGitActionStatus = null;
@@ -4,14 +4,13 @@
4
4
  */
5
5
  import { deriveState } from "./state.js";
6
6
  import { loadFile } from "./files.js";
7
- import { isDbAvailable, getMilestoneSlices } from "./gsd-db.js";
8
- import { parseRoadmap } from "./parsers-legacy.js";
9
- import { resolveMilestoneFile, resolveSliceFile, relSliceFile, } from "./paths.js";
7
+ import { isDbAvailable, getClosedSliceIds } from "./gsd-db.js";
8
+ import { resolveSliceFile, relSliceFile, } from "./paths.js";
10
9
  import { buildResearchSlicePrompt, buildResearchMilestonePrompt, buildPlanSlicePrompt, buildPlanMilestonePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReassessRoadmapPrompt, buildRunUatPrompt, buildReplanSlicePrompt, } from "./auto-prompts.js";
11
10
  import { loadEffectiveGSDPreferences } from "./preferences.js";
12
11
  import { pauseAuto } from "./auto.js";
13
12
  import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
14
- import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit, } from "./workflow-mcp.js";
13
+ import { getUnitWorkflowDispatchReadinessError } from "./tool-contract.js";
15
14
  export async function dispatchDirectPhase(ctx, pi, phase, base) {
16
15
  const state = await deriveState(base);
17
16
  const mid = state.activeMilestone?.id;
@@ -135,21 +134,9 @@ export async function dispatchDirectPhase(ctx, pi, phase, base) {
135
134
  }
136
135
  case "reassess":
137
136
  case "reassess-roadmap": {
138
- // DB primary pathget completed slices, fall back to file parsing when DB has no data
139
- let completedSliceIds = [];
140
- if (isDbAvailable()) {
141
- completedSliceIds = getMilestoneSlices(mid).filter(s => s.status === "complete").map(s => s.id);
142
- }
143
- if (completedSliceIds.length === 0) {
144
- // File-based fallback: parse roadmap checkboxes
145
- const roadmapPath = resolveMilestoneFile(dispatchBase, mid, "ROADMAP");
146
- if (roadmapPath) {
147
- const roadmapContent = await loadFile(roadmapPath);
148
- if (roadmapContent) {
149
- completedSliceIds = parseRoadmap(roadmapContent).slices.filter(s => s.done).map(s => s.id);
150
- }
151
- }
152
- }
137
+ // DB-authoritative read (ADR-017)markdown projections are never
138
+ // consulted for dispatch decisions. No DB rows means no completed slices.
139
+ const completedSliceIds = isDbAvailable() ? getClosedSliceIds(mid) : [];
153
140
  if (completedSliceIds.length === 0) {
154
141
  ctx.ui.notify("Cannot dispatch reassess-roadmap: no completed slices.", "warning");
155
142
  return;
@@ -173,20 +160,9 @@ export async function dispatchDirectPhase(ctx, pi, phase, base) {
173
160
  // incomplete) slice. After slice completion, state.activeSlice advances
174
161
  // to the next incomplete slice, so we find the last done slice from the
175
162
  // roadmap instead (#1693).
176
- let uatCompletedSliceIds = [];
177
- if (isDbAvailable()) {
178
- uatCompletedSliceIds = getMilestoneSlices(mid).filter(s => s.status === "complete").map(s => s.id);
179
- }
180
- if (uatCompletedSliceIds.length === 0) {
181
- // File-based fallback: parse roadmap checkboxes
182
- const roadmapPath = resolveMilestoneFile(dispatchBase, mid, "ROADMAP");
183
- if (roadmapPath) {
184
- const roadmapContent = await loadFile(roadmapPath);
185
- if (roadmapContent) {
186
- uatCompletedSliceIds = parseRoadmap(roadmapContent).slices.filter(s => s.done).map(s => s.id);
187
- }
188
- }
189
- }
163
+ // DB-authoritative read (ADR-017) — no markdown fallback for dispatch
164
+ // decisions.
165
+ const uatCompletedSliceIds = isDbAvailable() ? getClosedSliceIds(mid) : [];
190
166
  if (uatCompletedSliceIds.length === 0) {
191
167
  ctx.ui.notify("Cannot dispatch run-uat: no completed slices.", "warning");
192
168
  return;
@@ -225,7 +201,8 @@ export async function dispatchDirectPhase(ctx, pi, phase, base) {
225
201
  ctx.ui.notify(`Unknown phase "${phase}". Valid phases: research, plan, execute, complete, validate, reassess, uat, replan.`, "warning");
226
202
  return;
227
203
  }
228
- const compatibilityError = getWorkflowTransportSupportError(ctx.model?.provider, getRequiredWorkflowToolsForAutoUnit(unitType), {
204
+ const compatibilityError = getUnitWorkflowDispatchReadinessError({
205
+ provider: ctx.model?.provider,
229
206
  projectRoot,
230
207
  surface: "direct phase dispatch",
231
208
  unitType,