@opengsd/gsd-pi 1.2.0-dev.4c756166 → 1.2.0-dev.822c9439

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 (688) 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 +9 -5
  10. package/dist/resource-loader.js +116 -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 +5 -2
  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/models.js +9 -0
  27. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +38 -6
  28. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  29. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  30. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  31. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  32. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  33. package/dist/resources/extensions/gsd/auto/orchestrator.js +122 -58
  34. package/dist/resources/extensions/gsd/auto/phases.js +54 -6
  35. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  36. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  37. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  38. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  39. package/dist/resources/extensions/gsd/auto-post-unit.js +43 -14
  40. package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
  41. package/dist/resources/extensions/gsd/auto-start.js +24 -26
  42. package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
  43. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  44. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
  45. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  46. package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
  47. package/dist/resources/extensions/gsd/auto-worktree.js +49 -353
  48. package/dist/resources/extensions/gsd/auto.js +45 -21
  49. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  50. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
  51. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -12
  52. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  53. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  54. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +229 -36
  55. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +319 -71
  56. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  57. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  58. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  59. package/dist/resources/extensions/gsd/captures.js +5 -15
  60. package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
  61. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  62. package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
  63. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  64. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  65. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  66. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  67. package/dist/resources/extensions/gsd/constants.js +0 -2
  68. package/dist/resources/extensions/gsd/crash-recovery.js +12 -15
  69. package/dist/resources/extensions/gsd/db/engine.js +755 -0
  70. package/dist/resources/extensions/gsd/db/queries.js +398 -0
  71. package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
  72. package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
  73. package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
  74. package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
  75. package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
  76. package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
  77. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  78. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  79. package/dist/resources/extensions/gsd/doctor-environment.js +5 -11
  80. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  81. package/dist/resources/extensions/gsd/doctor-git-checks.js +6 -21
  82. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
  83. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  84. package/dist/resources/extensions/gsd/error-classifier.js +9 -0
  85. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  86. package/dist/resources/extensions/gsd/files.js +33 -19
  87. package/dist/resources/extensions/gsd/git-service.js +1 -0
  88. package/dist/resources/extensions/gsd/gitignore.js +3 -0
  89. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  90. package/dist/resources/extensions/gsd/gsd-db.js +172 -2048
  91. package/dist/resources/extensions/gsd/guidance.js +158 -0
  92. package/dist/resources/extensions/gsd/guided-flow.js +57 -8
  93. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  94. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  95. package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
  96. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  97. package/dist/resources/extensions/gsd/migrate/safety.js +20 -9
  98. package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
  99. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  100. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  101. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  102. package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
  103. package/dist/resources/extensions/gsd/model-router.js +3 -0
  104. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  105. package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
  106. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
  107. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  108. package/dist/resources/extensions/gsd/paths.js +37 -24
  109. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  110. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  111. package/dist/resources/extensions/gsd/preferences.js +14 -0
  112. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  113. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  114. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  115. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  116. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  117. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  118. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  119. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  120. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  121. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  122. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  123. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  124. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
  125. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  126. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  127. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  128. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  129. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  130. package/dist/resources/extensions/gsd/publication.js +87 -0
  131. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  132. package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
  133. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  134. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  135. package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
  136. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
  137. package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
  138. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  139. package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
  140. package/dist/resources/extensions/gsd/state.js +6 -20
  141. package/dist/resources/extensions/gsd/status-guards.js +56 -8
  142. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  143. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  144. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  145. package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
  146. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  147. package/dist/resources/extensions/gsd/tools/complete-slice.js +46 -55
  148. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
  149. package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
  150. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
  151. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  152. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  153. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +13 -31
  154. package/dist/resources/extensions/gsd/tools/reopen-slice.js +16 -35
  155. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  156. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  157. package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
  158. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  159. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  160. package/dist/resources/extensions/gsd/undo.js +8 -7
  161. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  162. package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
  163. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  164. package/dist/resources/extensions/gsd/unit-registry.js +337 -0
  165. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
  166. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  167. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  168. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  169. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  170. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  171. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  172. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  173. package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
  174. package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
  175. package/dist/resources/extensions/gsd/worktree-lifecycle.js +12 -3
  176. package/dist/resources/extensions/gsd/worktree-manager.js +52 -29
  177. package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
  178. package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
  179. package/dist/resources/extensions/gsd/worktree-root.js +28 -6
  180. package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
  181. package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
  182. package/dist/resources/extensions/gsd/worktree.js +8 -1
  183. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  184. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  185. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  186. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  187. package/dist/resources/shared/package-manager-detection.js +1 -1
  188. package/dist/resources/shared/package.json +3 -0
  189. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  190. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  191. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  192. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  193. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  194. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  195. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  196. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  197. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  198. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  199. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  200. package/dist/update-check.d.ts +2 -0
  201. package/dist/update-check.js +24 -1
  202. package/dist/update-cmd.js +20 -3
  203. package/dist/web/standalone/.next/BUILD_ID +1 -1
  204. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  205. package/dist/web/standalone/.next/build-manifest.json +3 -3
  206. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  207. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  208. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  209. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  210. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  211. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  212. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  213. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  214. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  215. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  216. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  217. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  218. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  219. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  220. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  221. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  222. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  223. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  224. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  225. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  226. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  227. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  228. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  229. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  230. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  231. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  232. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  233. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  234. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  235. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  236. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  237. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  238. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  239. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  240. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  241. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  242. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  243. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  244. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  245. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  246. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  247. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  248. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  249. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  250. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  251. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  252. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  253. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  254. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  255. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  256. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  257. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  258. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  259. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  260. package/dist/web/standalone/.next/server/app/index.html +1 -1
  261. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  262. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  263. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  264. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  265. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  266. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  267. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  268. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  269. package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
  270. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  271. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  272. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  273. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  274. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  275. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  276. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  277. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  278. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  279. package/dist/web/standalone/package.json +1 -1
  280. package/dist/worktree-cli.js +3 -6
  281. package/dist/worktree-status-banner.js +7 -11
  282. package/package.json +1 -1
  283. package/packages/cloud-mcp-gateway/package.json +2 -2
  284. package/packages/contracts/dist/rpc.d.ts +1 -0
  285. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  286. package/packages/contracts/dist/rpc.js.map +1 -1
  287. package/packages/contracts/dist/workflow.d.ts +4 -0
  288. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  289. package/packages/contracts/dist/workflow.js.map +1 -1
  290. package/packages/contracts/package.json +1 -1
  291. package/packages/daemon/package.json +4 -4
  292. package/packages/gsd-agent-core/package.json +5 -5
  293. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  294. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  295. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  296. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  297. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  298. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  299. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  300. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  301. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  302. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  303. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  304. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  305. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  306. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  307. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  308. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  309. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  310. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  311. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  312. package/packages/gsd-agent-modes/package.json +7 -7
  313. package/packages/mcp-server/dist/cli.js +9 -1
  314. package/packages/mcp-server/dist/cli.js.map +1 -1
  315. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  316. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  317. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  318. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  319. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  320. package/packages/mcp-server/dist/server.js +4 -0
  321. package/packages/mcp-server/dist/server.js.map +1 -1
  322. package/packages/mcp-server/dist/workflow-tools.d.ts +26 -18
  323. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  324. package/packages/mcp-server/dist/workflow-tools.js +145 -59
  325. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  326. package/packages/mcp-server/package.json +5 -4
  327. package/packages/native/package.json +1 -1
  328. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  329. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  330. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  331. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  332. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  333. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  334. package/packages/pi-agent-core/dist/index.js +3 -0
  335. package/packages/pi-agent-core/dist/index.js.map +1 -1
  336. package/packages/pi-agent-core/package.json +1 -1
  337. package/packages/pi-ai/README.md +1 -0
  338. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  339. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  340. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  341. package/packages/pi-ai/dist/index.d.ts +2 -0
  342. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  343. package/packages/pi-ai/dist/index.js +2 -0
  344. package/packages/pi-ai/dist/index.js.map +1 -1
  345. package/packages/pi-ai/dist/models.generated.d.ts +158 -17
  346. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  347. package/packages/pi-ai/dist/models.generated.js +132 -17
  348. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  349. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  350. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  351. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  352. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  353. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  354. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  355. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  356. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  357. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  358. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  359. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  360. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  361. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  362. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  363. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  364. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  365. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  366. package/packages/pi-ai/package.json +3 -2
  367. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  368. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  370. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
  372. package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
  373. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  376. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  377. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  378. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  380. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  382. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  383. package/packages/pi-coding-agent/dist/index.js +1 -1
  384. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  385. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  386. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  387. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  388. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  389. package/packages/pi-coding-agent/package.json +7 -7
  390. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  391. package/packages/pi-tui/dist/tui.js +9 -0
  392. package/packages/pi-tui/dist/tui.js.map +1 -1
  393. package/packages/pi-tui/package.json +2 -2
  394. package/packages/rpc-client/package.json +2 -2
  395. package/pkg/package.json +1 -1
  396. package/src/resources/GSD-WORKFLOW.md +5 -4
  397. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  398. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  399. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  400. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  401. package/src/resources/extensions/async-jobs/index.ts +79 -0
  402. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  403. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  404. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  405. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  406. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  407. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  408. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  409. package/src/resources/extensions/bg-shell/utilities.ts +5 -2
  410. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  411. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  412. package/src/resources/extensions/browser-tools/index.ts +71 -13
  413. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  414. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  415. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  416. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  417. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +40 -4
  418. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
  419. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  420. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  421. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  422. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  423. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
  424. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  425. package/src/resources/extensions/gsd/auto/orchestrator.ts +137 -61
  426. package/src/resources/extensions/gsd/auto/phases.ts +74 -26
  427. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  428. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  429. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  430. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  431. package/src/resources/extensions/gsd/auto-post-unit.ts +52 -13
  432. package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
  433. package/src/resources/extensions/gsd/auto-start.ts +24 -29
  434. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  435. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  436. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
  437. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  438. package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
  439. package/src/resources/extensions/gsd/auto-worktree.ts +55 -365
  440. package/src/resources/extensions/gsd/auto.ts +64 -25
  441. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  442. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
  443. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +33 -12
  444. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  445. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  446. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +270 -37
  447. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +368 -78
  448. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  449. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  450. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  451. package/src/resources/extensions/gsd/captures.ts +5 -16
  452. package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
  453. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  454. package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
  455. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  456. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  457. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  458. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  459. package/src/resources/extensions/gsd/constants.ts +0 -3
  460. package/src/resources/extensions/gsd/crash-recovery.ts +13 -11
  461. package/src/resources/extensions/gsd/db/engine.ts +809 -0
  462. package/src/resources/extensions/gsd/db/queries.ts +490 -0
  463. package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
  464. package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
  465. package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
  466. package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
  467. package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
  468. package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
  469. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  470. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  471. package/src/resources/extensions/gsd/doctor-environment.ts +5 -13
  472. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  473. package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -22
  474. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
  475. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  476. package/src/resources/extensions/gsd/error-classifier.ts +11 -0
  477. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  478. package/src/resources/extensions/gsd/files.ts +33 -12
  479. package/src/resources/extensions/gsd/git-service.ts +1 -0
  480. package/src/resources/extensions/gsd/gitignore.ts +3 -0
  481. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  482. package/src/resources/extensions/gsd/gsd-db.ts +176 -2375
  483. package/src/resources/extensions/gsd/guidance.ts +217 -0
  484. package/src/resources/extensions/gsd/guided-flow.ts +71 -31
  485. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  486. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  487. package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
  488. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  489. package/src/resources/extensions/gsd/migrate/safety.ts +18 -7
  490. package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
  491. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  492. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  493. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  494. package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
  495. package/src/resources/extensions/gsd/model-router.ts +3 -0
  496. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  497. package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
  498. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
  499. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  500. package/src/resources/extensions/gsd/paths.ts +42 -22
  501. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  502. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  503. package/src/resources/extensions/gsd/preferences.ts +18 -0
  504. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  505. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  506. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  507. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  508. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  509. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  510. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  511. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  512. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  513. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  514. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  515. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  516. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
  517. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  518. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  519. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  520. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  521. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  522. package/src/resources/extensions/gsd/publication.ts +122 -0
  523. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  524. package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
  525. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  526. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  527. package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
  528. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
  529. package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
  530. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  531. package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
  532. package/src/resources/extensions/gsd/state.ts +9 -21
  533. package/src/resources/extensions/gsd/status-guards.ts +59 -8
  534. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  535. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +123 -0
  536. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  537. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
  538. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
  539. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
  540. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  541. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
  542. package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
  543. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  544. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  545. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  546. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  547. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  548. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
  549. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
  550. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  551. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  552. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  553. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  554. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  555. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  556. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  557. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  558. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  559. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  560. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  561. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
  562. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  563. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  564. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  565. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
  566. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  567. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  568. package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
  569. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
  570. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
  571. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +74 -59
  572. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  573. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  574. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  575. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  576. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +85 -1
  577. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  578. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  579. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  580. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  581. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  582. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
  583. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  584. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  585. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  586. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  587. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  588. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  589. package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
  590. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +248 -1
  591. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  592. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -1
  593. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
  594. package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
  595. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +43 -6
  596. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
  597. package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
  598. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  599. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  600. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  601. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  602. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
  603. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  604. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  605. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  606. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  607. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
  608. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  609. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  610. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  611. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  612. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  613. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  614. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  615. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
  616. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
  617. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
  618. package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
  619. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
  620. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
  621. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
  622. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +24 -2
  623. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  624. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  625. package/src/resources/extensions/gsd/tests/write-gate.test.ts +109 -1
  626. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  627. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  628. package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
  629. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  630. package/src/resources/extensions/gsd/tools/complete-slice.ts +45 -70
  631. package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
  632. package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
  633. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
  634. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  635. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  636. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +13 -40
  637. package/src/resources/extensions/gsd/tools/reopen-slice.ts +16 -44
  638. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  639. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  640. package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
  641. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  642. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  643. package/src/resources/extensions/gsd/undo.ts +9 -8
  644. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  645. package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
  646. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  647. package/src/resources/extensions/gsd/unit-registry.ts +412 -0
  648. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
  649. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  650. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  651. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  652. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  653. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  654. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  655. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  656. package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
  657. package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
  658. package/src/resources/extensions/gsd/worktree-lifecycle.ts +13 -9
  659. package/src/resources/extensions/gsd/worktree-manager.ts +53 -29
  660. package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
  661. package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
  662. package/src/resources/extensions/gsd/worktree-root.ts +29 -6
  663. package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
  664. package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
  665. package/src/resources/extensions/gsd/worktree.ts +7 -1
  666. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  667. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  668. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  669. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  670. package/src/resources/shared/package-manager-detection.ts +1 -1
  671. package/src/resources/shared/package.json +3 -0
  672. package/src/resources/skills/create-skill/SKILL.md +3 -0
  673. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  674. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  675. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  676. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  677. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  678. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  679. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  680. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  681. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  682. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  683. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  684. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  685. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  686. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  687. /package/dist/web/standalone/.next/static/{DUFWcMFRH3iXh7d2fbrOF → yWwBo-w09Y_W-nmeeWFRp}/_buildManifest.js +0 -0
  688. /package/dist/web/standalone/.next/static/{DUFWcMFRH3iXh7d2fbrOF → yWwBo-w09Y_W-nmeeWFRp}/_ssgManifest.js +0 -0
@@ -14,14 +14,15 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
14
14
 
15
15
  import type { AutoAdvanceResult, AutoOrchestrationModule, AutoSessionContext, AutoStatus, AutoTerminalOutcome } from "./contracts.js";
16
16
  import type { AutoSession, PendingOrchestrationDispatch } from "./session.js";
17
- import type { GSDState } from "../types.js";
17
+ import type { GSDState, Phase } from "../types.js";
18
18
  import type { MinimalModelRegistry } from "../context-budget.js";
19
19
 
20
20
  type BlockedAdvanceResult = Extract<AutoAdvanceResult, { kind: "blocked" }>;
21
21
 
22
- import { debugCount, debugTime } from "../debug-logger.js";
22
+ import { debugCount, debugLog, debugTime } from "../debug-logger.js";
23
23
  import { reconcileBeforeDispatch } from "../state-reconciliation.js";
24
- import { resolveDispatch } from "../auto-dispatch.js";
24
+ import { isLegalEdge, IllegalPhaseTransitionError } from "../state-transition-matrix.js";
25
+ import { hasPendingDeepStage, resolveDispatch } from "../auto-dispatch.js";
25
26
  import { classifyFailure } from "../recovery-classification.js";
26
27
  import { verifyExpectedArtifact, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
27
28
  import { invalidateAllCaches } from "../cache.js";
@@ -37,7 +38,7 @@ import { checkResourcesStale, autoWorktreeBranch, mergeMilestoneToMain } from ".
37
38
  import { getSessionLockStatus } from "../session-lock.js";
38
39
  import { resolveUokFlags } from "../uok/flags.js";
39
40
  import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
40
- import { loadEffectiveGSDPreferences, getIsolationMode } from "../preferences.js";
41
+ import { loadEffectiveGSDPreferences, getIsolationMode, resolveEffectiveUnitIsolationMode } from "../preferences.js";
41
42
  import {
42
43
  detectWorktreeName,
43
44
  getMainBranch,
@@ -63,6 +64,13 @@ import {
63
64
  import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
64
65
  import { getErrorMessage } from "../error-utils.js";
65
66
  import { logWarning } from "../workflow-logger.js";
67
+ import { normalizeRealPath } from "../paths.js";
68
+ import {
69
+ buildDispatchKey,
70
+ createDispatchHistory,
71
+ STUCK_WINDOW_SIZE,
72
+ type DispatchHistory,
73
+ } from "./dispatch-history.js";
66
74
  import { existsSync, readFileSync } from "node:fs";
67
75
  import { join } from "node:path";
68
76
  import { evaluateAllCompleteSettlement } from "../milestone-settlement.js";
@@ -71,16 +79,6 @@ function now(): number {
71
79
  return Date.now();
72
80
  }
73
81
 
74
- /**
75
- * Size of the dispatch-decision ring buffer used by the Auto Orchestration
76
- * module's stuck-loop detector. When the same `${unitType}:${unitId}` key
77
- * fills the window, advance() blocks with `action: "stop"`.
78
- *
79
- * Mirrors the legacy `STUCK_WINDOW_SIZE` in auto/phases.ts so behaviour is
80
- * preserved across the eventual cutover (issue #5791).
81
- */
82
- export const STUCK_WINDOW_SIZE = 6;
83
-
84
82
  function noRemainingUnitsOutcome(stateSnapshot: GSDState): AutoTerminalOutcome {
85
83
  if (stateSnapshot.phase === "complete") {
86
84
  return {
@@ -195,14 +193,25 @@ export async function decideOrchestratorDispatch(
195
193
  ): Promise<DispatchDecision> {
196
194
  const state = input.stateSnapshot;
197
195
  const active = state.activeMilestone;
198
- if (!active) return null;
199
-
200
196
  const activeSession = input.session ?? session;
201
197
  const activeDispatchBasePath = activeSession?.basePath || dispatchBasePath;
202
- if (activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
198
+ const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
199
+ if (!active) {
200
+ if (state.phase !== "pre-planning") return null;
201
+ if (!hasPendingDeepStage(prefs, activeDispatchBasePath)) {
202
+ return {
203
+ kind: "blocked",
204
+ reason: state.nextAction || "No active milestone. Run /gsd unpark <id> or create a new milestone.",
205
+ action: "stop",
206
+ };
207
+ }
208
+ }
209
+
210
+ if (active && activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
203
211
  activeSession.currentMilestoneId = active.id;
204
212
  }
205
- const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
213
+ const dispatchMid = active?.id ?? activeSession?.currentMilestoneId ?? "";
214
+ const dispatchMidTitle = active?.title ?? "";
206
215
 
207
216
  // Derive session-derived dispatch inputs the same way phases.ts:runDispatch does
208
217
  // (#5789). Prefer caller-supplied values when present so test harnesses and
@@ -234,8 +243,15 @@ export async function decideOrchestratorDispatch(
234
243
  ? "true"
235
244
  : "false");
236
245
 
246
+ // Only replay a milestone-scoped verification retry when a milestone is
247
+ // active. Pre-PR (#712 fix), `!active` returned null before reaching this
248
+ // block, so the retry was preserved for a future tick. The new
249
+ // pre-planning + deep-pending fall-through must keep that contract:
250
+ // otherwise a stale execute-task / complete-slice / complete-milestone
251
+ // retry whose target milestone has since been parked would preempt
252
+ // project-level deep rules like `discuss-project`.
237
253
  const pendingRetry = session?.pendingVerificationRetryDispatch;
238
- if (session && pendingRetry) {
254
+ if (session && pendingRetry && active) {
239
255
  session.pendingVerificationRetryDispatch = null;
240
256
  const alreadyClosedReason = getAlreadyClosedDispatchReason(
241
257
  pendingRetry.unitType,
@@ -257,8 +273,8 @@ export async function decideOrchestratorDispatch(
257
273
 
258
274
  const action = await resolveDispatch({
259
275
  basePath: activeDispatchBasePath,
260
- mid: active.id,
261
- midTitle: active.title,
276
+ mid: dispatchMid,
277
+ midTitle: dispatchMidTitle,
262
278
  state,
263
279
  prefs,
264
280
  session: activeSession,
@@ -302,8 +318,8 @@ export async function decideOrchestratorDispatch(
302
318
  prompt: action.prompt,
303
319
  pauseAfterUatDispatch: action.pauseAfterDispatch ?? false,
304
320
  state,
305
- mid: active.id,
306
- midTitle: active.title,
321
+ mid: dispatchMid,
322
+ midTitle: dispatchMidTitle,
307
323
  };
308
324
  session.pendingOrchestrationDispatch = pending;
309
325
  }
@@ -329,7 +345,13 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
329
345
  private seq = 0;
330
346
  private lastAdvanceKey: string | null = null;
331
347
  private lastFinalizedUnitKey: string | null = null;
332
- private dispatchKeyWindow: string[] = [];
348
+ // Dispatch History module (#482): the dispatch-decision window with
349
+ // cross-session DB rehydration and full detect-stuck rules.
350
+ private readonly dispatchHistory: DispatchHistory;
351
+ // ADR-030 Phase Transition Invariant: the prior advance's reconciled Phase,
352
+ // the "from" endpoint of the edge check. In-memory; reset on start/resume/stop
353
+ // so the first advance of a session has no edge to assert.
354
+ private lastDerivedPhase: Phase | null = null;
333
355
  // #442: the unit key we last attempted graduated stuck-recovery for. Bounds
334
356
  // recovery to one attempt per stuck episode per run (reset on start/resume/
335
357
  // stop), mirroring the legacy Level-1-then-Level-2 escalation in phases.ts.
@@ -342,6 +364,16 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
342
364
  this.runtimeBasePath = context.runtimeBasePath;
343
365
  this.s = context.session;
344
366
  this.flowId = `auto-orchestrator-${Date.now()}`;
367
+ this.dispatchHistory = createDispatchHistory({
368
+ windowSize: STUCK_WINDOW_SIZE,
369
+ // Same stable scope the auto-loop uses for stuck-state persistence so
370
+ // rehydration reads the rows the dispatch ledger wrote for this project.
371
+ resolveScopeId: () =>
372
+ normalizeRealPath(
373
+ this.s.scope?.workspace.projectRoot ??
374
+ (this.s.originalBasePath || this.s.basePath || this.runtimeBasePath),
375
+ ) || null,
376
+ });
345
377
  }
346
378
 
347
379
  // ── Live base-path resolution (was the wiring factory's getLiveDispatchBasePath) ──
@@ -612,8 +644,11 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
612
644
  // ── WorktreeAdapter (folded) ─────────────────────────────────────────────
613
645
 
614
646
  private getEffectiveUnitIsolationMode(basePath: string): ReturnType<typeof getIsolationMode> {
615
- const configuredMode = getIsolationMode(basePath);
616
- return configuredMode === "worktree" && this.s.isolationDegraded ? "branch" : configuredMode;
647
+ return resolveEffectiveUnitIsolationMode(
648
+ getIsolationMode(basePath),
649
+ this.s.isolationDegraded,
650
+ this.s.strandedRecoveryIsolationMode,
651
+ );
617
652
  }
618
653
 
619
654
  private buildLifecycle(): WorktreeLifecycle {
@@ -724,6 +759,21 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
724
759
  return { action: recovery.action, reason: recovery.reason };
725
760
  }
726
761
 
762
+ /**
763
+ * ADR-030 Phase Transition Invariant (advisory mode). The matrix is an
764
+ * assertion, not a decision-maker — deriveState already chose the phase; we
765
+ * only observe illegal *derived* edges that survived reconciliation. The
766
+ * matrix is still a sparse hardening spec, so this is telemetry-only (no
767
+ * block) until it is expanded into a validated legal-edge graph. To enforce:
768
+ * `throw violation;` instead of logging — recovery-classification maps
769
+ * IllegalPhaseTransitionError to kind "illegal-transition" (escalate).
770
+ */
771
+ private observePhaseTransition(from: Phase, to: Phase): void {
772
+ if (isLegalEdge(from, to)) return;
773
+ const violation = new IllegalPhaseTransitionError(from, to);
774
+ debugLog("phase-transition-advisory", { from, to, message: violation.message });
775
+ }
776
+
727
777
  // ── Lifecycle verbs ──────────────────────────────────────────────────────
728
778
 
729
779
  /**
@@ -742,7 +792,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
742
792
  * skipped result) instead of stopping.
743
793
  */
744
794
  private tryStuckArtifactRecovery(unitType: string, unitId: string): boolean {
745
- const key = `${unitType}:${unitId}`;
795
+ const key = buildDispatchKey(unitType, unitId);
746
796
  if (this.lastStuckRecoveryKey === key) return false; // already tried this episode
747
797
  const basePath = this.getLiveDispatchBasePath();
748
798
  if (!verifyExpectedArtifact(unitType, unitId, basePath)) return false;
@@ -754,7 +804,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
754
804
  if (!refreshed.ok && refreshed.fatal) return false;
755
805
  this.lastStuckRecoveryKey = key;
756
806
  invalidateAllCaches();
757
- this.dispatchKeyWindow = [];
807
+ this.dispatchHistory.clearOnRecovery();
758
808
  this.lastAdvanceKey = null;
759
809
  this.lastFinalizedUnitKey = null;
760
810
  return true;
@@ -785,8 +835,14 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
785
835
  public async start(_sessionContext: AutoSessionContext): Promise<AutoAdvanceResult> {
786
836
  this.lastAdvanceKey = null;
787
837
  this.lastFinalizedUnitKey = null;
788
- this.dispatchKeyWindow = [];
838
+ // #482: the DB dispatch ledger is the source of truth across sessions.
839
+ // Discard any in-memory window and rebuild it from the ledger so a unit
840
+ // that was re-dispatched in previous sessions is detected as stuck here
841
+ // instead of silently re-dispatching forever.
842
+ this.dispatchHistory.clearOnRecovery();
843
+ this.dispatchHistory.rehydrate();
789
844
  this.lastStuckRecoveryKey = null;
845
+ this.lastDerivedPhase = null;
790
846
  this.status.phase = "running";
791
847
  this.bumpTransition();
792
848
  this.journalTransition({ name: "start" });
@@ -876,6 +932,12 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
876
932
  return blocked;
877
933
  }
878
934
 
935
+ const reconciledPhase = reconciliation.stateSnapshot.phase;
936
+ if (this.lastDerivedPhase !== null) {
937
+ this.observePhaseTransition(this.lastDerivedPhase, reconciledPhase);
938
+ }
939
+ this.lastDerivedPhase = reconciledPhase;
940
+
879
941
  const decision = await this.decideNextUnit({ stateSnapshot: reconciliation.stateSnapshot });
880
942
  if (!decision) {
881
943
  const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
@@ -883,7 +945,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
883
945
  this.status.phase = "paused";
884
946
  this.status.activeUnit = undefined;
885
947
  this.lastAdvanceKey = null;
886
- this.dispatchKeyWindow = [];
948
+ this.dispatchHistory.clearOnRecovery();
887
949
  this.bumpTransition();
888
950
  this.journalTransition({ name: "advance-blocked", reason: settlementBlock.reason });
889
951
  this.postAdvanceRecord(settlementBlock);
@@ -899,7 +961,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
899
961
  this.status.phase = "stopped";
900
962
  this.status.activeUnit = undefined;
901
963
  this.lastAdvanceKey = null;
902
- this.dispatchKeyWindow = [];
964
+ this.dispatchHistory.clearOnRecovery();
903
965
  this.bumpTransition();
904
966
  this.journalTransition({ name: "advance-stopped", reason: stopped.reason });
905
967
  this.postAdvanceRecord(stopped);
@@ -949,18 +1011,13 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
949
1011
  return blocked;
950
1012
  }
951
1013
 
952
- const nextKey = `${decision.unitType}:${decision.unitId}`;
953
-
954
- // Record every dispatch decision in the ring buffer before pre-flight
1014
+ // Record every dispatch decision in the history window before pre-flight
955
1015
  // checks so the stuck-loop detector observes the full decision history
956
1016
  // (including decisions that idempotency would otherwise short-circuit).
957
- // The ring is capped at STUCK_WINDOW_SIZE and evicts oldest-first.
958
- this.dispatchKeyWindow.push(nextKey);
959
- if (this.dispatchKeyWindow.length > STUCK_WINDOW_SIZE) {
960
- this.dispatchKeyWindow.shift();
961
- }
1017
+ // The window is capped at STUCK_WINDOW_SIZE and evicts oldest-first.
1018
+ const nextKey = this.dispatchHistory.recordDispatch(decision.unitType, decision.unitId);
962
1019
 
963
- const matchingCount = this.dispatchKeyWindow.filter((k) => k === nextKey).length;
1020
+ const matchingCount = this.dispatchHistory.countMatching(nextKey);
964
1021
  if (this.lastFinalizedUnitKey === nextKey) {
965
1022
  // #442: the unit re-dispatched immediately after finalizing may have
966
1023
  // actually completed on disk with a stale DB. Verify + recover before
@@ -993,23 +1050,32 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
993
1050
  // checks coexist: idempotency for the common immediate-repeat case,
994
1051
  // stuck-loop for the saturated-window case.
995
1052
  if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
1053
+ // Unit already active — benign no-op. Return skipped so the loop re-polls
1054
+ // without cancelling the in-flight unit (blocked+pause would force-cancel it).
996
1055
  this.clearPendingDispatch();
997
- const blocked: AutoAdvanceResult = { kind: "blocked", reason: "idempotent advance: unit already active", action: "pause" };
1056
+ const skipped: AutoAdvanceResult = { kind: "skipped", reason: "idempotent advance: unit already active" };
998
1057
  this.journalTransition({
999
- name: "advance-blocked",
1000
- reason: blocked.reason,
1058
+ name: "advance-skipped",
1059
+ reason: skipped.reason,
1001
1060
  unitType: decision.unitType,
1002
1061
  unitId: decision.unitId,
1003
1062
  });
1004
- this.postAdvanceRecord(blocked);
1005
- return blocked;
1063
+ this.postAdvanceRecord(skipped);
1064
+ return skipped;
1006
1065
  }
1007
1066
 
1008
- // Stuck-loop detection: when the ring is saturated with copies of
1009
- // `nextKey` (count >= STUCK_WINDOW_SIZE), the orchestrator has been
1010
- // picking the same unit across the whole window and must hard-stop with
1011
- // a diagnosable reason.
1012
- if (matchingCount >= STUCK_WINDOW_SIZE) {
1067
+ // Stuck-loop detection: when the window is saturated with copies of
1068
+ // `nextKey` (count >= STUCK_WINDOW_SIZE), consult the Dispatch History
1069
+ // module's full detect-stuck rule set for the verdict instead of the old
1070
+ // bare saturation count. This keeps the saturation threshold (the window
1071
+ // deliberately records benign idempotent repeats, so earlier-firing
1072
+ // rules would false-positive on pause/resume re-advances) while gaining
1073
+ // retry-budget suppression and diagnosable rule reasons. A saturated
1074
+ // window with no verdict means the dispatch ledger says we are inside
1075
+ // the unit's retry-backoff budget — let the retry proceed.
1076
+ const stuckVerdict =
1077
+ matchingCount >= STUCK_WINDOW_SIZE ? this.dispatchHistory.detectStuck() : null;
1078
+ if (stuckVerdict) {
1013
1079
  // #442: before declaring a stuck loop, verify the unit didn't actually
1014
1080
  // complete on disk (stale DB) and recover if so — legacy graduated
1015
1081
  // stuck-recovery parity. Otherwise hard-stop with a diagnosable reason.
@@ -1020,7 +1086,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1020
1086
  this.clearPendingDispatch();
1021
1087
  const blocked: AutoAdvanceResult = {
1022
1088
  kind: "blocked",
1023
- reason: `stuck-loop: ${nextKey} picked ${matchingCount} times`,
1089
+ reason: `stuck-loop: ${stuckVerdict.reason}`,
1024
1090
  action: "stop",
1025
1091
  };
1026
1092
  this.journalTransition({
@@ -1114,7 +1180,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1114
1180
  if (result.kind === "stopped") {
1115
1181
  this.lastAdvanceKey = null;
1116
1182
  this.lastFinalizedUnitKey = null;
1117
- this.dispatchKeyWindow = [];
1183
+ this.dispatchHistory.clearOnRecovery();
1118
1184
  this.status.activeUnit = undefined;
1119
1185
  }
1120
1186
  this.bumpTransition();
@@ -1143,9 +1209,18 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1143
1209
  public async resume(): Promise<AutoAdvanceResult> {
1144
1210
  this.lastAdvanceKey = null;
1145
1211
  this.lastFinalizedUnitKey = null;
1146
- // Preserve dispatchKeyWindow across resume so stuck-loop detection
1147
- // accumulates across pause/resume cycles rather than resetting each time.
1212
+ // Preserve the dispatch-history window across an in-process resume so
1213
+ // stuck-loop detection accumulates across pause/resume cycles rather than
1214
+ // resetting each time (#572 regression). When the window is empty (fresh
1215
+ // orchestrator resuming a prior session), rehydrate it from the DB
1216
+ // dispatch ledger so cross-session re-dispatch loops are detected (#482).
1217
+ if (this.dispatchHistory.getRecentWindow().length === 0) {
1218
+ this.dispatchHistory.rehydrate();
1219
+ }
1148
1220
  this.lastStuckRecoveryKey = null;
1221
+ // ADR-030: drop the prior "from" — the first advance after resume has no
1222
+ // edge to assert (avoids a false illegal-edge across the pause boundary).
1223
+ this.lastDerivedPhase = null;
1149
1224
  this.status.phase = "running";
1150
1225
  this.bumpTransition();
1151
1226
  this.journalTransition({ name: "resume" });
@@ -1162,10 +1237,11 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1162
1237
  this.status.activeUnit = undefined;
1163
1238
  this.lastAdvanceKey = null;
1164
1239
  this.lastFinalizedUnitKey = null;
1165
- // Preserve dispatchKeyWindow on pause so stuck-loop detection accumulates
1166
- // across pause/resume cycles. Only clear on a hard stop.
1240
+ this.lastDerivedPhase = null;
1241
+ // Preserve the dispatch-history window on pause so stuck-loop detection
1242
+ // accumulates across pause/resume cycles. Only clear on a hard stop.
1167
1243
  if (reason !== "pause") {
1168
- this.dispatchKeyWindow = [];
1244
+ this.dispatchHistory.clearOnRecovery();
1169
1245
  }
1170
1246
  this.lastStuckRecoveryKey = null;
1171
1247
  this.bumpTransition();
@@ -1179,9 +1255,9 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1179
1255
  }
1180
1256
 
1181
1257
  public async completeActiveUnit(unit: { unitType: string; unitId: string }): Promise<void> {
1182
- const unitKey = `${unit.unitType}:${unit.unitId}`;
1258
+ const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
1183
1259
  const activeUnitKey = this.status.activeUnit
1184
- ? `${this.status.activeUnit.unitType}:${this.status.activeUnit.unitId}`
1260
+ ? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
1185
1261
  : null;
1186
1262
  if (activeUnitKey !== unitKey) return;
1187
1263
 
@@ -1199,9 +1275,9 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1199
1275
  }
1200
1276
 
1201
1277
  public async retryActiveUnit(unit: { unitType: string; unitId: string }): Promise<void> {
1202
- const unitKey = `${unit.unitType}:${unit.unitId}`;
1278
+ const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
1203
1279
  const activeUnitKey = this.status.activeUnit
1204
- ? `${this.status.activeUnit.unitType}:${this.status.activeUnit.unitId}`
1280
+ ? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
1205
1281
  : null;
1206
1282
  if (activeUnitKey !== unitKey && this.lastFinalizedUnitKey !== unitKey) return;
1207
1283
 
@@ -19,8 +19,9 @@ import {
19
19
  type PostUnitContext,
20
20
  type PreVerificationOpts,
21
21
  } from "../auto-post-unit.js";
22
- import { lastAssistantText } from "../user-input-boundary.js";
23
- import type { Phase } from "../types.js";
22
+ import { lastAssistantText } from "../consent-question.js";
23
+ import { resolveEffectiveUnitIsolationMode, getIsolationMode } from "../preferences.js";
24
+ import type { GSDState, Phase } from "../types.js";
24
25
  import {
25
26
  MAX_RECOVERY_CHARS,
26
27
  BUDGET_THRESHOLDS,
@@ -32,6 +33,7 @@ import {
32
33
  type IterationData,
33
34
  } from "./types.js";
34
35
  import { detectStuck } from "./detect-stuck.js";
36
+ import { STUCK_WINDOW_SIZE } from "./dispatch-history.js";
35
37
  import { runUnit } from "./run-unit.js";
36
38
  import { debugLog } from "../debug-logger.js";
37
39
  import { resolveWorktreeProjectRoot, normalizeWorktreePathForCompare } from "../worktree-root.js";
@@ -60,9 +62,10 @@ import { writeUnitRuntimeRecord } from "../unit-runtime.js";
60
62
  import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "./finalize-timeout.js";
61
63
  import { getEligibleSlices } from "../slice-parallel-eligibility.js";
62
64
  import { isSliceParallelActive, startSliceParallel } from "../slice-parallel-orchestrator.js";
63
- import { isDbAvailable, getMilestoneSlices, getSlice, getTask } from "../gsd-db.js";
65
+ import { isDbAvailable, getMilestone, getMilestoneSlices, getSlice, getTask } from "../gsd-db.js";
64
66
  import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
65
67
  import { isClosedStatus } from "../status-guards.js";
68
+ import { findUnmergedCompletedMilestones } from "../unmerged-milestone-guard.js";
66
69
  import { setRuntimeKv } from "../db/runtime-kv.js";
67
70
  import { getLatestForUnit } from "../db/unit-dispatches.js";
68
71
  import { reconcileBeforeSpawn } from "../state-reconciliation.js";
@@ -80,11 +83,8 @@ import { parseUnitId } from "../unit-id.js";
80
83
  import { createCheckpoint, cleanupCheckpoint, rollbackToCheckpoint } from "../safety/git-checkpoint.js";
81
84
  import { resolveSafetyHarnessConfig } from "../safety/safety-harness.js";
82
85
  import { getContextPauseAction } from "../auto-budget.js";
83
- import {
84
- getWorkflowTransportSupportError,
85
- getRequiredWorkflowToolsForAutoUnit,
86
- supportsStructuredQuestions,
87
- } from "../workflow-mcp.js";
86
+ import { supportsStructuredQuestions } from "../workflow-mcp.js";
87
+ import { getUnitWorkflowDispatchReadinessError } from "../tool-contract.js";
88
88
  import { prepareWorkflowMcpForProject } from "../workflow-mcp-auto-prep.js";
89
89
  import {
90
90
  applyThinkingLevelForModel,
@@ -106,7 +106,6 @@ import {
106
106
  } from "../root-write-leak-guard.js";
107
107
  import { classifyError, isTransient } from "../error-classifier.js";
108
108
 
109
- export const STUCK_WINDOW_SIZE = 6;
110
109
  const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
111
110
  const ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE =
112
111
  /^(?: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;
@@ -362,7 +361,15 @@ async function validateSourceWriteWorktreeSafety(
362
361
  if (!writesSource) return null;
363
362
 
364
363
  const projectRoot = s.canonicalProjectRoot ?? resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
365
- const isolationMode = deps.getIsolationMode(projectRoot);
364
+ // A degraded session already fell back to the milestone branch in the
365
+ // project root — validating against the canonical worktree root there
366
+ // would fail every dispatch with a false invalid-root. The same applies
367
+ // to a stranded-recovery session that adopted the milestone branch.
368
+ const isolationMode = resolveEffectiveUnitIsolationMode(
369
+ deps.getIsolationMode(projectRoot),
370
+ s.isolationDegraded,
371
+ s.strandedRecoveryIsolationMode,
372
+ );
366
373
  if (isolationMode !== "worktree") return null;
367
374
 
368
375
  const safety = createWorktreeSafetyModule();
@@ -829,6 +836,39 @@ async function failClosedOnFinalizeTimeout(
829
836
  return { action: "break", reason: progressKind };
830
837
  }
831
838
 
839
+ export async function shouldSkipTerminalMilestoneCloseout(
840
+ s: AutoSession,
841
+ state: Pick<GSDState, "phase" | "lastCompletedMilestone" | "activeMilestone">,
842
+ mid?: string | null,
843
+ ): Promise<{ skip: boolean; milestoneId?: string }> {
844
+ const closeoutMilestoneId = mid ?? s.currentMilestoneId ?? state.lastCompletedMilestone?.id;
845
+ if (s.completionStopInProgress) {
846
+ return { skip: true, milestoneId: closeoutMilestoneId };
847
+ }
848
+ if (!closeoutMilestoneId) {
849
+ return { skip: false };
850
+ }
851
+ if (isDbAvailable()) refreshWorkflowDatabaseFromDisk();
852
+ const closeoutBasePath = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
853
+ let closeoutMergePending = false;
854
+ if (getIsolationMode(closeoutBasePath) !== "none") {
855
+ try {
856
+ const blockers = await findUnmergedCompletedMilestones(closeoutBasePath);
857
+ closeoutMergePending = blockers.some((blocker) => blocker.milestoneId === closeoutMilestoneId);
858
+ } catch {
859
+ // Fail open: without git/DB inspection we cannot safely treat closeout as done.
860
+ closeoutMergePending = true;
861
+ }
862
+ }
863
+ const milestoneAlreadyClosedOut = isDbAvailable()
864
+ && isClosedStatus(getMilestone(closeoutMilestoneId)?.status ?? "")
865
+ && !closeoutMergePending;
866
+ if (milestoneAlreadyClosedOut) {
867
+ return { skip: true, milestoneId: closeoutMilestoneId };
868
+ }
869
+ return { skip: false, milestoneId: closeoutMilestoneId };
870
+ }
871
+
832
872
  // ─── runPreDispatch ───────────────────────────────────────────────────────────
833
873
 
834
874
  /**
@@ -1270,6 +1310,14 @@ export async function runPreDispatch(
1270
1310
 
1271
1311
  // ── Terminal conditions ──────────────────────────────────────────────
1272
1312
 
1313
+ if (state.phase === "complete") {
1314
+ const closeoutSkip = await shouldSkipTerminalMilestoneCloseout(s, state, mid);
1315
+ if (closeoutSkip.skip) {
1316
+ debugLog("autoLoop", { phase: "complete", reason: "milestone-already-closed", milestoneId: closeoutSkip.milestoneId });
1317
+ return { action: "break", reason: "milestone-complete" };
1318
+ }
1319
+ }
1320
+
1273
1321
  if (!mid) {
1274
1322
  if (s.currentUnit) {
1275
1323
  await deps.closeoutUnit(
@@ -2315,22 +2363,19 @@ export async function runUnitPhase(
2315
2363
  ? `${(s.currentUnitModel as any).provider ?? ""}/${(s.currentUnitModel as any).id ?? ""}`
2316
2364
  : null;
2317
2365
 
2318
- const compatibilityError = getWorkflowTransportSupportError(
2319
- s.currentUnitModel?.provider ?? ctx.model?.provider,
2320
- getRequiredWorkflowToolsForAutoUnit(unitType),
2321
- {
2322
- projectRoot: s.basePath,
2323
- surface: "auto-mode",
2324
- unitType,
2325
- authMode: s.currentUnitModel?.provider
2326
- ? ctx.modelRegistry.getProviderAuthMode(s.currentUnitModel.provider)
2327
- : ctx.model?.provider
2328
- ? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider)
2329
- : undefined,
2330
- baseUrl: (s.currentUnitModel as any)?.baseUrl ?? ctx.model?.baseUrl,
2331
- activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
2332
- },
2333
- );
2366
+ const compatibilityError = getUnitWorkflowDispatchReadinessError({
2367
+ provider: s.currentUnitModel?.provider ?? ctx.model?.provider,
2368
+ projectRoot: s.basePath,
2369
+ surface: "auto-mode",
2370
+ unitType,
2371
+ authMode: s.currentUnitModel?.provider
2372
+ ? ctx.modelRegistry.getProviderAuthMode(s.currentUnitModel.provider)
2373
+ : ctx.model?.provider
2374
+ ? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider)
2375
+ : undefined,
2376
+ baseUrl: (s.currentUnitModel as any)?.baseUrl ?? ctx.model?.baseUrl,
2377
+ activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
2378
+ });
2334
2379
  const workflowMcpPrepModel = s.currentUnitModel;
2335
2380
  if (compatibilityError) {
2336
2381
  s.currentUnitRouting = prevUnitRouting;
@@ -2400,6 +2445,9 @@ export async function runUnitPhase(
2400
2445
  causedBy: "unit-start",
2401
2446
  });
2402
2447
  s.lastToolInvocationError = null; // #2883: clear stale error from previous unit
2448
+ if (nextDispatchCount <= 1) {
2449
+ s.toolUnavailableRetries = 0;
2450
+ }
2403
2451
  const unitStartSeq = ic.nextSeq();
2404
2452
  deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: unitStartSeq, eventType: "unit-start", data: { unitType, unitId } });
2405
2453
  deps.captureAvailableSkills();
@@ -212,6 +212,8 @@ export class AutoSession {
212
212
  /** Set when a GSD tool execution ends with isError due to malformed/truncated
213
213
  * JSON arguments. Checked by postUnitPreVerification to break retry loops. */
214
214
  lastToolInvocationError: string | null = null;
215
+ /** Consecutive tool-unavailable retries for the current unit (MCP startup race). */
216
+ toolUnavailableRetries = 0;
215
217
  /** Agent-end messages from the just-finished unit, consumed during finalize. */
216
218
  lastUnitAgentEndMessages: unknown[] | null = null;
217
219
  /** Set when turn-level git action fails during closeout. */
@@ -406,6 +408,7 @@ export class AutoSession {
406
408
  this.lastPreExecFailure = null;
407
409
  this.preExecRetryCount.clear();
408
410
  this.lastToolInvocationError = null;
411
+ this.toolUnavailableRetries = 0;
409
412
  this.lastUnitAgentEndMessages = null;
410
413
  this.lastGitActionFailure = null;
411
414
  this.lastGitActionStatus = null;