gsd-pi 2.82.0 → 3.0.0-dev.6c9a50fd0

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 (775) hide show
  1. package/README.md +125 -32
  2. package/dist/cli.js +20 -9
  3. package/dist/headless-ui.js +13 -6
  4. package/dist/headless.js +9 -2
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/GSD-WORKFLOW.md +10 -1
  7. package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
  8. package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
  9. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  10. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
  11. package/dist/resources/extensions/cmux/index.js +5 -0
  12. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  13. package/dist/resources/extensions/gsd/auto/loop.js +112 -40
  14. package/dist/resources/extensions/gsd/auto/orchestrator.js +126 -8
  15. package/dist/resources/extensions/gsd/auto/phases.js +125 -42
  16. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  17. package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
  18. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  19. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  20. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  21. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +105 -24
  23. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  24. package/dist/resources/extensions/gsd/auto-post-unit.js +278 -137
  25. package/dist/resources/extensions/gsd/auto-prompts.js +47 -13
  26. package/dist/resources/extensions/gsd/auto-recovery.js +80 -14
  27. package/dist/resources/extensions/gsd/auto-start.js +90 -14
  28. package/dist/resources/extensions/gsd/auto-timers.js +11 -3
  29. package/dist/resources/extensions/gsd/auto-verification.js +102 -34
  30. package/dist/resources/extensions/gsd/auto-worktree.js +178 -11
  31. package/dist/resources/extensions/gsd/auto.js +251 -91
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +65 -10
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +10 -4
  35. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  36. package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
  37. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
  38. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  39. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  40. package/dist/resources/extensions/gsd/commands/handlers/core.js +39 -1
  41. package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
  42. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  43. package/dist/resources/extensions/gsd/commands-handlers.js +17 -2
  44. package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
  45. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -2
  46. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  47. package/dist/resources/extensions/gsd/context-store.js +112 -0
  48. package/dist/resources/extensions/gsd/crash-recovery.js +55 -7
  49. package/dist/resources/extensions/gsd/db/auto-workers.js +21 -0
  50. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  51. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  52. package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
  53. package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
  54. package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
  55. package/dist/resources/extensions/gsd/db-writer.js +150 -84
  56. package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
  57. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -1
  58. package/dist/resources/extensions/gsd/doctor-git-checks.js +87 -7
  59. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  60. package/dist/resources/extensions/gsd/doctor.js +2 -28
  61. package/dist/resources/extensions/gsd/export-html.js +27 -425
  62. package/dist/resources/extensions/gsd/forensics.js +10 -3
  63. package/dist/resources/extensions/gsd/git-service.js +138 -10
  64. package/dist/resources/extensions/gsd/gsd-db.js +76 -33
  65. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  66. package/dist/resources/extensions/gsd/guided-flow.js +110 -117
  67. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  68. package/dist/resources/extensions/gsd/init-wizard.js +17 -2
  69. package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
  70. package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
  71. package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
  72. package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
  73. package/dist/resources/extensions/gsd/markdown-renderer.js +20 -12
  74. package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
  75. package/dist/resources/extensions/gsd/md-importer.js +1 -1
  76. package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
  77. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
  78. package/dist/resources/extensions/gsd/migrate/command.js +5 -0
  79. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  80. package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
  81. package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
  82. package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
  83. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  84. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  85. package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
  86. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
  87. package/dist/resources/extensions/gsd/paths.js +4 -0
  88. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  89. package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
  90. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
  91. package/dist/resources/extensions/gsd/pre-execution-checks.js +38 -11
  92. package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
  93. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  94. package/dist/resources/extensions/gsd/preferences-validation.js +138 -0
  95. package/dist/resources/extensions/gsd/preferences.js +6 -0
  96. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  97. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  98. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  99. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  100. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  101. package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
  102. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  103. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  104. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  105. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  106. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  107. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  108. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  109. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  110. package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
  111. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  112. package/dist/resources/extensions/gsd/repo-identity.js +39 -22
  113. package/dist/resources/extensions/gsd/repository-registry.js +44 -0
  114. package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
  115. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
  116. package/dist/resources/extensions/gsd/session-lock.js +15 -2
  117. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +59 -2
  118. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  119. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  120. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  121. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  122. package/dist/resources/extensions/gsd/state.js +14 -4
  123. package/dist/resources/extensions/gsd/status-guards.js +14 -2
  124. package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
  125. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  126. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  127. package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -9
  128. package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -10
  129. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  130. package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
  131. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +185 -40
  132. package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
  133. package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
  134. package/dist/resources/extensions/gsd/validation.js +23 -1
  135. package/dist/resources/extensions/gsd/verification-gate.js +142 -7
  136. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  137. package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
  138. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  139. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  140. package/dist/resources/extensions/gsd/worktree-lifecycle.js +83 -19
  141. package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
  142. package/dist/resources/extensions/gsd/worktree-safety.js +43 -4
  143. package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
  144. package/dist/resources/extensions/shared/html-shell.js +388 -0
  145. package/dist/resources/extensions/shared/interview-ui.js +6 -4
  146. package/dist/resources/extensions/shared/next-action-ui.js +13 -5
  147. package/dist/resources/extensions/subagent/index.js +448 -78
  148. package/dist/resources/extensions/subagent/launch.js +77 -0
  149. package/dist/resources/extensions/subagent/run-store.js +148 -0
  150. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  151. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  152. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  153. package/dist/resources/extensions/visual-brief/index.js +5 -0
  154. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  155. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  156. package/dist/resources/skills/forensics/SKILL.md +1 -1
  157. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  158. package/dist/web/standalone/.next/BUILD_ID +1 -1
  159. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  160. package/dist/web/standalone/.next/build-manifest.json +4 -4
  161. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  162. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  163. package/dist/web/standalone/.next/required-server-files.json +4 -4
  164. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  165. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  167. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  172. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  174. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  175. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  176. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  178. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  179. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  180. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  181. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  182. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  183. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  184. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  185. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  192. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  204. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  224. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  234. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  235. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  236. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  238. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  240. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  242. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  243. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  244. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  246. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  247. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  248. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  249. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  250. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  252. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  253. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  254. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  255. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  256. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  257. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  258. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  259. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  260. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  261. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  262. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  263. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  264. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  265. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  266. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  267. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  268. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  269. package/dist/web/standalone/.next/server/app/index.html +1 -1
  270. package/dist/web/standalone/.next/server/app/index.rsc +5 -8
  271. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  272. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -8
  273. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  274. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  275. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  276. package/dist/web/standalone/.next/server/app/page.js +2 -2
  277. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  278. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  279. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  280. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  281. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  282. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  283. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  284. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  285. package/dist/web/standalone/.next/server/middleware.js +2 -2
  286. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  287. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  288. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  289. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  290. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  291. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  292. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  293. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  294. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  295. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  296. package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +1 -0
  297. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  298. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  299. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  300. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  301. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  302. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  303. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  304. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  305. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  306. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  307. package/dist/web/standalone/server.js +1 -1
  308. package/package.json +6 -5
  309. package/packages/contracts/dist/rpc.test.js +7 -0
  310. package/packages/contracts/dist/rpc.test.js.map +1 -1
  311. package/packages/contracts/dist/workflow.d.ts +21 -0
  312. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  313. package/packages/contracts/dist/workflow.js +24 -0
  314. package/packages/contracts/dist/workflow.js.map +1 -1
  315. package/packages/contracts/src/rpc.test.ts +8 -0
  316. package/packages/contracts/src/workflow.ts +24 -0
  317. package/packages/daemon/package.json +2 -2
  318. package/packages/mcp-server/README.md +14 -3
  319. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  320. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  321. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  322. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  323. package/packages/mcp-server/package.json +2 -2
  324. package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
  325. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  326. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  327. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  328. package/packages/native/package.json +1 -1
  329. package/packages/native/tsconfig.json +2 -1
  330. package/packages/native/tsconfig.tsbuildinfo +1 -1
  331. package/packages/pi-agent-core/package.json +1 -1
  332. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  333. package/packages/pi-ai/dist/index.d.ts +2 -2
  334. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  335. package/packages/pi-ai/dist/index.js +1 -1
  336. package/packages/pi-ai/dist/index.js.map +1 -1
  337. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  338. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  339. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  340. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  341. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  342. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  343. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  344. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  345. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  346. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  347. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  348. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  349. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  350. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  351. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  352. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  353. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  354. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  355. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  356. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  357. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  358. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  359. package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
  360. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  361. package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
  362. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  363. package/packages/pi-ai/package.json +1 -1
  364. package/packages/pi-ai/src/index.ts +7 -2
  365. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  366. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  367. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  368. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  369. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  370. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  371. package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
  372. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  373. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  374. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  375. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  376. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  377. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  378. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  380. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
  382. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  383. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
  384. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  385. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
  386. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  388. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  389. package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
  390. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  391. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
  392. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  393. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  394. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  395. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  396. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
  397. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  398. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  399. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
  400. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  401. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
  402. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  403. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
  404. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  405. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  406. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  407. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  408. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  409. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  410. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  411. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
  412. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
  413. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
  414. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
  415. package/packages/pi-coding-agent/package.json +1 -1
  416. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  417. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  418. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  419. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
  420. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
  421. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  422. package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
  423. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
  424. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  425. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
  426. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
  427. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
  428. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
  429. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  430. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  431. package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
  432. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  433. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  434. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  435. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  436. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  437. package/packages/pi-tui/dist/__tests__/tui.test.js +45 -2
  438. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  439. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  440. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  441. package/packages/pi-tui/dist/terminal.js +12 -0
  442. package/packages/pi-tui/dist/terminal.js.map +1 -1
  443. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  444. package/packages/pi-tui/dist/tui.js +108 -24
  445. package/packages/pi-tui/dist/tui.js.map +1 -1
  446. package/packages/pi-tui/package.json +1 -1
  447. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  448. package/packages/pi-tui/src/__tests__/tui.test.ts +59 -2
  449. package/packages/pi-tui/src/terminal.ts +11 -0
  450. package/packages/pi-tui/src/tui.ts +111 -24
  451. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  452. package/packages/rpc-client/package.json +1 -1
  453. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  454. package/pkg/package.json +1 -1
  455. package/src/resources/GSD-WORKFLOW.md +10 -1
  456. package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
  457. package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
  458. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  459. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
  460. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  461. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
  462. package/src/resources/extensions/cmux/index.ts +6 -0
  463. package/src/resources/extensions/gsd/auto/contracts.ts +64 -16
  464. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  465. package/src/resources/extensions/gsd/auto/loop.ts +113 -40
  466. package/src/resources/extensions/gsd/auto/orchestrator.ts +131 -8
  467. package/src/resources/extensions/gsd/auto/phases.ts +155 -53
  468. package/src/resources/extensions/gsd/auto/session.ts +16 -0
  469. package/src/resources/extensions/gsd/auto/types.ts +3 -0
  470. package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
  471. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  472. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  473. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  474. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  475. package/src/resources/extensions/gsd/auto-dispatch.ts +126 -23
  476. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  477. package/src/resources/extensions/gsd/auto-post-unit.ts +312 -148
  478. package/src/resources/extensions/gsd/auto-prompts.ts +47 -16
  479. package/src/resources/extensions/gsd/auto-recovery.ts +84 -11
  480. package/src/resources/extensions/gsd/auto-start.ts +99 -12
  481. package/src/resources/extensions/gsd/auto-timers.ts +10 -3
  482. package/src/resources/extensions/gsd/auto-verification.ts +124 -42
  483. package/src/resources/extensions/gsd/auto-worktree.ts +195 -11
  484. package/src/resources/extensions/gsd/auto.ts +288 -87
  485. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +66 -10
  486. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
  487. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +11 -4
  488. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  489. package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
  490. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
  491. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  492. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  493. package/src/resources/extensions/gsd/commands/handlers/core.ts +42 -1
  494. package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
  495. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  496. package/src/resources/extensions/gsd/commands-handlers.ts +21 -2
  497. package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
  498. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +11 -3
  499. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  500. package/src/resources/extensions/gsd/context-store.ts +120 -1
  501. package/src/resources/extensions/gsd/crash-recovery.ts +55 -6
  502. package/src/resources/extensions/gsd/db/auto-workers.ts +25 -0
  503. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  504. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  505. package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
  506. package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
  507. package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
  508. package/src/resources/extensions/gsd/db-writer.ts +167 -84
  509. package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
  510. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -1
  511. package/src/resources/extensions/gsd/doctor-git-checks.ts +89 -7
  512. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  513. package/src/resources/extensions/gsd/doctor-types.ts +3 -0
  514. package/src/resources/extensions/gsd/doctor.ts +2 -27
  515. package/src/resources/extensions/gsd/export-html.ts +27 -427
  516. package/src/resources/extensions/gsd/forensics.ts +9 -3
  517. package/src/resources/extensions/gsd/git-service.ts +166 -11
  518. package/src/resources/extensions/gsd/gsd-db.ts +80 -31
  519. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  520. package/src/resources/extensions/gsd/guided-flow.ts +142 -134
  521. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  522. package/src/resources/extensions/gsd/init-wizard.ts +17 -2
  523. package/src/resources/extensions/gsd/journal.ts +8 -1
  524. package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
  525. package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
  526. package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
  527. package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
  528. package/src/resources/extensions/gsd/markdown-renderer.ts +20 -12
  529. package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
  530. package/src/resources/extensions/gsd/md-importer.ts +1 -1
  531. package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
  532. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
  533. package/src/resources/extensions/gsd/migrate/command.ts +5 -0
  534. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  535. package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
  536. package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
  537. package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
  538. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  539. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  540. package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
  541. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
  542. package/src/resources/extensions/gsd/paths.ts +5 -0
  543. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  544. package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
  545. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
  546. package/src/resources/extensions/gsd/pre-execution-checks.ts +49 -11
  547. package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
  548. package/src/resources/extensions/gsd/preferences-types.ts +33 -0
  549. package/src/resources/extensions/gsd/preferences-validation.ts +145 -0
  550. package/src/resources/extensions/gsd/preferences.ts +9 -0
  551. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  552. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  553. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  554. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  555. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  556. package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
  557. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  558. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  559. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  560. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  561. package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  562. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  563. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  564. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  565. package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
  566. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  567. package/src/resources/extensions/gsd/repo-identity.ts +45 -25
  568. package/src/resources/extensions/gsd/repository-registry.ts +77 -0
  569. package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
  570. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
  571. package/src/resources/extensions/gsd/session-lock.ts +15 -2
  572. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +52 -1
  573. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  574. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  575. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  576. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  577. package/src/resources/extensions/gsd/state.ts +15 -4
  578. package/src/resources/extensions/gsd/status-guards.ts +16 -2
  579. package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
  580. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  581. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  582. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
  583. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  584. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  585. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +510 -1
  586. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +635 -16
  587. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  588. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  589. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  590. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +134 -9
  591. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
  592. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
  593. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  594. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  595. package/src/resources/extensions/gsd/tests/auto-workers.test.ts +13 -0
  596. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  597. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
  598. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  599. package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
  600. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  601. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  602. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
  603. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  604. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  605. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +55 -2
  606. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +60 -9
  607. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  608. package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
  609. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +104 -2
  610. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  611. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  612. package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
  613. package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
  614. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
  615. package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
  616. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
  617. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +111 -1
  618. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
  619. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +111 -1
  620. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  621. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
  622. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
  623. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  624. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
  625. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
  626. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
  627. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  628. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  629. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  630. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  631. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  632. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  633. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  634. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  635. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  636. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  637. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
  638. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
  639. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  640. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +199 -2
  641. package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
  642. package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
  643. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +15 -0
  644. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  645. package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +38 -0
  646. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
  647. package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
  648. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
  649. package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
  650. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
  651. package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
  652. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
  653. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
  654. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
  655. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  656. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
  657. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  658. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
  659. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  660. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
  661. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  662. package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
  663. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  664. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  665. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  666. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
  667. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  668. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  669. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
  670. package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
  671. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  672. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
  673. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  674. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  675. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +59 -0
  676. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
  677. package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
  678. package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
  679. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +78 -0
  680. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
  681. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  682. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  683. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
  684. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  685. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  686. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  687. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +28 -1
  688. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
  689. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  690. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +35 -0
  691. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
  692. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +59 -1
  693. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +72 -1
  694. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  695. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +86 -2
  696. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  697. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  698. package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
  699. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  700. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
  701. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  702. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
  703. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
  704. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
  705. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  706. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
  707. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +173 -1
  708. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  709. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  710. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  711. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  712. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +121 -1
  713. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  714. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  715. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +57 -2
  716. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
  717. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +90 -0
  718. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
  719. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
  720. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
  721. package/src/resources/extensions/gsd/tools/complete-milestone.ts +18 -10
  722. package/src/resources/extensions/gsd/tools/complete-slice.ts +57 -10
  723. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  724. package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
  725. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +166 -17
  726. package/src/resources/extensions/gsd/types.ts +1 -1
  727. package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
  728. package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
  729. package/src/resources/extensions/gsd/validation.ts +23 -1
  730. package/src/resources/extensions/gsd/verification-gate.ts +170 -6
  731. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  732. package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
  733. package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
  734. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  735. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  736. package/src/resources/extensions/gsd/worktree-lifecycle.ts +93 -20
  737. package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
  738. package/src/resources/extensions/gsd/worktree-safety.ts +57 -10
  739. package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
  740. package/src/resources/extensions/shared/html-shell.ts +412 -0
  741. package/src/resources/extensions/shared/interview-ui.ts +6 -4
  742. package/src/resources/extensions/shared/next-action-ui.ts +11 -5
  743. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
  744. package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +32 -0
  745. package/src/resources/extensions/subagent/index.ts +567 -103
  746. package/src/resources/extensions/subagent/launch.ts +131 -0
  747. package/src/resources/extensions/subagent/run-store.ts +218 -0
  748. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  749. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  750. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  751. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  752. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  753. package/src/resources/extensions/visual-brief/index.ts +8 -0
  754. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  755. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  756. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  757. package/src/resources/skills/forensics/SKILL.md +1 -1
  758. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  759. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  760. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  761. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  762. package/dist/web/standalone/.next/static/chunks/app/layout-9ecfd95f343793f0.js +0 -1
  763. package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +0 -1
  764. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  765. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  766. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  767. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  768. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  769. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  770. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  771. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  772. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  773. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  774. /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → 8wipfz6TDZ6YWoaQjgqYD}/_buildManifest.js +0 -0
  775. /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → 8wipfz6TDZ6YWoaQjgqYD}/_ssgManifest.js +0 -0
@@ -4,9 +4,20 @@
4
4
  import test from "node:test";
5
5
  import assert from "node:assert/strict";
6
6
 
7
- import { createAutoOrchestrator } from "../auto/orchestrator.js";
7
+ import { createAutoOrchestrator, STUCK_WINDOW_SIZE } from "../auto/orchestrator.js";
8
8
  import type { AutoOrchestratorDeps } from "../auto/contracts.js";
9
9
  import type { GSDState } from "../types.js";
10
+ import { createWiredDispatchAdapter } from "../auto.js";
11
+ import { resolveDispatch, type DispatchContext } from "../auto-dispatch.js";
12
+ import { RuleRegistry, setRegistry, resetRegistry } from "../rule-registry.js";
13
+ import type { UnifiedRule } from "../rule-types.js";
14
+ import { supportsStructuredQuestions } from "../workflow-mcp.js";
15
+
16
+ function assertBlockedResult(
17
+ result: Awaited<ReturnType<ReturnType<typeof createAutoOrchestrator>["advance"]>>,
18
+ ): asserts result is Extract<typeof result, { kind: "blocked" }> {
19
+ assert.equal(result.kind, "blocked");
20
+ }
10
21
 
11
22
  function makeState(): GSDState {
12
23
  return {
@@ -62,9 +73,13 @@ function makeDeps(overrides: Partial<AutoOrchestratorDeps> = {}): { deps: AutoOr
62
73
  async cleanupOnStop() { calls.push("worktree.cleanup"); },
63
74
  },
64
75
  health: {
76
+ checkResourcesStale() {
77
+ calls.push("health.stale");
78
+ return null;
79
+ },
65
80
  async preAdvanceGate() {
66
81
  calls.push("health.pre");
67
- return { allow: true };
82
+ return { kind: "pass" };
68
83
  },
69
84
  async postAdvanceRecord() { calls.push("health.post"); },
70
85
  },
@@ -75,29 +90,33 @@ function makeDeps(overrides: Partial<AutoOrchestratorDeps> = {}): { deps: AutoOr
75
90
  notifications: {
76
91
  async notifyLifecycle(event) { calls.push(`notify:${event.name}`); },
77
92
  },
93
+ uokGate: {
94
+ async emit(input) { calls.push(`gate:${input.gateId}:${input.outcome}`); },
95
+ },
78
96
  };
79
97
 
80
98
  return { deps: { ...deps, ...overrides }, calls };
81
99
  }
82
100
 
83
- test("start() advances and records active unit", async () => {
101
+ test("start() enters running phase without dispatching", async () => {
84
102
  const { deps, calls } = makeDeps();
85
103
  const orchestrator = createAutoOrchestrator(deps);
86
104
 
87
105
  const result = await orchestrator.start({ basePath: "/tmp/project", trigger: "manual" });
88
106
 
89
- assert.equal(result.kind, "advanced");
107
+ assert.equal(result.kind, "started");
90
108
  const status = orchestrator.getStatus();
91
109
  assert.equal(status.phase, "running");
92
- assert.deepEqual(status.activeUnit, { unitType: "execute-task", unitId: "T01" });
110
+ assert.equal(status.activeUnit, undefined);
93
111
  assert.ok(calls.includes("journal:start"));
94
- assert.ok(calls.includes("journal:advance"));
112
+ assert.ok(!calls.includes("journal:advance"));
95
113
  });
96
114
 
97
115
  test("advance() returns blocked when health gate denies", async () => {
98
- const { deps } = makeDeps({
116
+ const { deps, calls } = makeDeps({
99
117
  health: {
100
- async preAdvanceGate() { return { allow: false, reason: "doctor-block" }; },
118
+ checkResourcesStale: () => null,
119
+ async preAdvanceGate() { return { kind: "fail", reason: "doctor-block" }; },
101
120
  async postAdvanceRecord() {},
102
121
  },
103
122
  });
@@ -105,8 +124,146 @@ test("advance() returns blocked when health gate denies", async () => {
105
124
 
106
125
  const result = await orchestrator.advance();
107
126
 
108
- assert.equal(result.kind, "blocked");
127
+ assertBlockedResult(result);
109
128
  assert.equal(result.reason, "doctor-block");
129
+ assert.equal(result.action, "pause");
130
+ assert.ok(calls.includes("gate:pre-dispatch-health-gate:manual-attention"));
131
+ });
132
+
133
+ test("advance() returns blocked pause when resources are stale", async () => {
134
+ const { deps, calls } = makeDeps({
135
+ health: {
136
+ checkResourcesStale: () => "resources changed since session start",
137
+ async preAdvanceGate() { return { kind: "pass" }; },
138
+ async postAdvanceRecord() {},
139
+ },
140
+ });
141
+ const orchestrator = createAutoOrchestrator(deps);
142
+
143
+ const result = await orchestrator.advance();
144
+
145
+ assertBlockedResult(result);
146
+ assert.equal(result.reason, "resources changed since session start");
147
+ assert.equal(result.action, "pause");
148
+ assert.ok(calls.includes("gate:resource-version-guard:fail"));
149
+ assert.ok(!calls.includes("health.pre"));
150
+ assert.ok(!calls.includes("state.reconcile"));
151
+ });
152
+
153
+ test("advance() pre-dispatch parity: gate emissions and control-flow action match legacy branches", async () => {
154
+ type Scenario = {
155
+ name: string;
156
+ staleMsg: string | null;
157
+ gateResult: Awaited<ReturnType<AutoOrchestratorDeps["health"]["preAdvanceGate"]>>;
158
+ expectedKind: "advanced" | "blocked";
159
+ expectedAction?: "pause" | "stop";
160
+ expectedReason?: string;
161
+ expectedGates: string[];
162
+ };
163
+ const scenarios: Scenario[] = [
164
+ {
165
+ name: "pass",
166
+ staleMsg: null,
167
+ gateResult: { kind: "pass" },
168
+ expectedKind: "advanced",
169
+ expectedGates: [
170
+ "resource-version-guard:policy:pass:none:resource version guard passed:",
171
+ "pre-dispatch-health-gate:execution:pass:none:pre-dispatch health gate passed:",
172
+ ],
173
+ },
174
+ {
175
+ name: "resource-stale",
176
+ staleMsg: "resources changed since session start",
177
+ gateResult: { kind: "pass" },
178
+ expectedKind: "blocked",
179
+ expectedAction: "pause",
180
+ expectedReason: "resources changed since session start",
181
+ expectedGates: [
182
+ "resource-version-guard:policy:fail:policy:resource version guard blocked dispatch:resources changed since session start",
183
+ ],
184
+ },
185
+ {
186
+ name: "health-gate-fail",
187
+ staleMsg: null,
188
+ gateResult: { kind: "fail", reason: "doctor-block" },
189
+ expectedKind: "blocked",
190
+ expectedAction: "pause",
191
+ expectedReason: "doctor-block",
192
+ expectedGates: [
193
+ "resource-version-guard:policy:pass:none:resource version guard passed:",
194
+ "pre-dispatch-health-gate:execution:manual-attention:manual-attention:pre-dispatch health gate blocked dispatch:doctor-block",
195
+ ],
196
+ },
197
+ ];
198
+
199
+ for (const scenario of scenarios) {
200
+ const gateEvents: string[] = [];
201
+ const { deps } = makeDeps({
202
+ health: {
203
+ checkResourcesStale: () => scenario.staleMsg,
204
+ async preAdvanceGate() { return scenario.gateResult; },
205
+ async postAdvanceRecord() {},
206
+ },
207
+ uokGate: {
208
+ async emit(input) {
209
+ gateEvents.push(
210
+ `${input.gateId}:${input.gateType}:${input.outcome}:${input.failureClass}:${input.rationale}:${input.findings ?? ""}`,
211
+ );
212
+ },
213
+ },
214
+ });
215
+ const orchestrator = createAutoOrchestrator(deps);
216
+ const result = await orchestrator.advance();
217
+
218
+ assert.equal(result.kind, scenario.expectedKind, `${scenario.name} result kind`);
219
+ if (scenario.expectedKind === "blocked") {
220
+ assertBlockedResult(result);
221
+ assert.equal(result.action, scenario.expectedAction, `${scenario.name} blocked action`);
222
+ assert.equal(result.reason, scenario.expectedReason, `${scenario.name} blocked reason`);
223
+ }
224
+ assert.deepEqual(gateEvents, scenario.expectedGates, `${scenario.name} gate parity`);
225
+ }
226
+ });
227
+
228
+ test("advance() continues past pre-dispatch health gate when it throws", async () => {
229
+ const { deps, calls } = makeDeps({
230
+ health: {
231
+ checkResourcesStale: () => null,
232
+ async preAdvanceGate() { return { kind: "threw", error: new Error("boom") }; },
233
+ async postAdvanceRecord() {},
234
+ },
235
+ });
236
+ const orchestrator = createAutoOrchestrator(deps);
237
+
238
+ const result = await orchestrator.advance();
239
+
240
+ assert.equal(result.kind, "advanced");
241
+ assert.ok(calls.includes("gate:pre-dispatch-health-gate:manual-attention"));
242
+ assert.ok(calls.includes("state.reconcile"));
243
+ assert.ok(calls.includes("dispatch.decide"));
244
+ });
245
+
246
+ test("advance() forwards fixesApplied into pre-dispatch-health-gate pass findings", async () => {
247
+ let observed = "";
248
+ const { deps } = makeDeps({
249
+ health: {
250
+ checkResourcesStale: () => null,
251
+ async preAdvanceGate() { return { kind: "pass", fixesApplied: ["fix-a", "fix-b"] }; },
252
+ async postAdvanceRecord() {},
253
+ },
254
+ uokGate: {
255
+ async emit(input) {
256
+ if (input.gateId === "pre-dispatch-health-gate" && input.outcome === "pass") {
257
+ observed = input.findings ?? "";
258
+ }
259
+ },
260
+ },
261
+ });
262
+ const orchestrator = createAutoOrchestrator(deps);
263
+
264
+ await orchestrator.advance();
265
+
266
+ assert.equal(observed, "fix-a, fix-b");
110
267
  });
111
268
 
112
269
  test("advance() follows the ADR-015 invariant sequence before journaling advance", async () => {
@@ -116,9 +273,13 @@ test("advance() follows the ADR-015 invariant sequence before journaling advance
116
273
  const result = await orchestrator.advance();
117
274
 
118
275
  assert.equal(result.kind, "advanced");
276
+ assert.deepEqual(result.unit, { unitType: "execute-task", unitId: "T01" });
119
277
  assert.deepEqual(calls, [
120
278
  "runtime.lock",
279
+ "health.stale",
280
+ "gate:resource-version-guard:pass",
121
281
  "health.pre",
282
+ "gate:pre-dispatch-health-gate:pass",
122
283
  "state.reconcile",
123
284
  "dispatch.decide",
124
285
  "tool.compile",
@@ -142,8 +303,9 @@ test("advance() blocks before dispatch when State Reconciliation blocks", async
142
303
 
143
304
  const result = await orchestrator.advance();
144
305
 
145
- assert.equal(result.kind, "blocked");
306
+ assertBlockedResult(result);
146
307
  assert.equal(result.reason, "state drift blocked");
308
+ assert.equal(result.action, "pause");
147
309
  assert.ok(!calls.includes("dispatch.decide"));
148
310
  assert.ok(calls.includes("journal:advance-blocked"));
149
311
  });
@@ -161,8 +323,9 @@ test("advance() blocks before Runtime persistence when Tool Contract fails", asy
161
323
 
162
324
  const result = await orchestrator.advance();
163
325
 
164
- assert.equal(result.kind, "blocked");
326
+ assertBlockedResult(result);
165
327
  assert.equal(result.reason, "unknown Unit");
328
+ assert.equal(result.action, "pause");
166
329
  assert.ok(!calls.includes("worktree.prepare"));
167
330
  assert.ok(!calls.includes("journal:advance"));
168
331
  assert.ok(calls.includes("journal:advance-blocked"));
@@ -183,13 +346,34 @@ test("advance() blocks before Runtime persistence when Worktree Safety fails", a
183
346
 
184
347
  const result = await orchestrator.advance();
185
348
 
186
- assert.equal(result.kind, "blocked");
349
+ assertBlockedResult(result);
187
350
  assert.equal(result.reason, "worktree invalid");
351
+ assert.equal(result.action, "pause");
188
352
  assert.ok(!calls.includes("journal:advance"));
189
353
  assert.ok(!calls.includes("worktree.sync"));
190
354
  assert.ok(calls.includes("journal:advance-blocked"));
191
355
  });
192
356
 
357
+ test("advance() allows non-worktree isolation prepare result", async () => {
358
+ const { deps, calls } = makeDeps({
359
+ worktree: {
360
+ async prepareForUnit() {
361
+ calls.push("worktree.prepare");
362
+ return { ok: true, reason: "isolation-not-worktree" };
363
+ },
364
+ async syncAfterUnit() { calls.push("worktree.sync"); },
365
+ async cleanupOnStop() { calls.push("worktree.cleanup"); },
366
+ },
367
+ });
368
+ const orchestrator = createAutoOrchestrator(deps);
369
+
370
+ const result = await orchestrator.advance();
371
+
372
+ assert.equal(result.kind, "advanced");
373
+ assert.ok(calls.includes("journal:advance"));
374
+ assert.ok(calls.includes("worktree.sync"));
375
+ });
376
+
193
377
  test("advance() stops when dispatch has no next unit", async () => {
194
378
  const { deps } = makeDeps({
195
379
  dispatch: {
@@ -204,6 +388,42 @@ test("advance() stops when dispatch has no next unit", async () => {
204
388
  assert.equal(orchestrator.getStatus().phase, "stopped");
205
389
  });
206
390
 
391
+ test("advance() surfaces dispatch blocker reason instead of generic no remaining units", async () => {
392
+ const { deps, calls } = makeDeps({
393
+ dispatch: {
394
+ async decideNextUnit() {
395
+ return {
396
+ kind: "blocked",
397
+ reason: "Milestone M001 validation verdict is needs-remediation but all slices are complete.",
398
+ action: "pause",
399
+ };
400
+ },
401
+ },
402
+ });
403
+ const orchestrator = createAutoOrchestrator(deps);
404
+
405
+ const result = await orchestrator.advance();
406
+
407
+ assert.equal(result.kind, "blocked");
408
+ if (result.kind !== "blocked") return;
409
+ assert.equal(result.reason, "Milestone M001 validation verdict is needs-remediation but all slices are complete.");
410
+ assert.equal(result.action, "pause");
411
+ assert.ok(calls.includes("journal:advance-blocked"));
412
+ assert.ok(!calls.includes("journal:advance-stopped"));
413
+ });
414
+
415
+ test("resume() enters running phase without dispatching", async () => {
416
+ const { deps, calls } = makeDeps();
417
+ const orchestrator = createAutoOrchestrator(deps);
418
+
419
+ const result = await orchestrator.resume();
420
+
421
+ assert.equal(result.kind, "resumed");
422
+ assert.equal(orchestrator.getStatus().phase, "running");
423
+ assert.ok(!calls.includes("journal:advance"));
424
+ assert.ok(!calls.includes("dispatch.decide"));
425
+ });
426
+
207
427
  test("advance() uses recovery on error", async () => {
208
428
  const { deps, calls } = makeDeps({
209
429
  runtime: {
@@ -232,20 +452,22 @@ test("advance() is idempotent for the same active unit", async () => {
232
452
  const second = await orchestrator.advance();
233
453
 
234
454
  assert.equal(first.kind, "advanced");
455
+ assert.deepEqual(first.unit, { unitType: "execute-task", unitId: "T01" });
235
456
  assert.equal(second.kind, "blocked");
236
457
  assert.equal(second.reason, "idempotent advance: unit already active");
458
+ assert.equal(second.action, "pause");
237
459
 
238
460
  const prepareCalls = calls.filter((c) => c === "worktree.prepare").length;
239
461
  assert.equal(prepareCalls, 1);
240
462
  });
241
463
 
242
- test("resume() re-enters running flow via advance", async () => {
464
+ test("resume() re-enters running phase", async () => {
243
465
  const { deps } = makeDeps();
244
466
  const orchestrator = createAutoOrchestrator(deps);
245
467
 
246
468
  const result = await orchestrator.resume();
247
469
 
248
- assert.equal(result.kind, "advanced");
470
+ assert.equal(result.kind, "resumed");
249
471
  assert.equal(orchestrator.getStatus().phase, "running");
250
472
  });
251
473
 
@@ -256,10 +478,12 @@ test("resume() clears idempotent lock and allows re-advance", async () => {
256
478
  const first = await orchestrator.advance();
257
479
  const blocked = await orchestrator.advance();
258
480
  const resumed = await orchestrator.resume();
481
+ const next = await orchestrator.advance();
259
482
 
260
483
  assert.equal(first.kind, "advanced");
261
484
  assert.equal(blocked.kind, "blocked");
262
- assert.equal(resumed.kind, "advanced");
485
+ assert.equal(resumed.kind, "resumed");
486
+ assert.equal(next.kind, "advanced");
263
487
  });
264
488
 
265
489
  test("transitionCount increases across lifecycle transitions", async () => {
@@ -374,9 +598,11 @@ test("start() clears prior idempotent lock", async () => {
374
598
  await orchestrator.advance();
375
599
  const blocked = await orchestrator.advance();
376
600
  const restarted = await orchestrator.start({ basePath: "/tmp/project", trigger: "manual" });
601
+ const next = await orchestrator.advance();
377
602
 
378
603
  assert.equal(blocked.kind, "blocked");
379
- assert.equal(restarted.kind, "advanced");
604
+ assert.equal(restarted.kind, "started");
605
+ assert.equal(next.kind, "advanced");
380
606
  });
381
607
 
382
608
  test("error path emits error notification", async () => {
@@ -468,3 +694,396 @@ test("stop() cleans up worktree and transitions to stopped", async () => {
468
694
  assert.ok(calls.includes("journal:stop"));
469
695
  assert.ok(calls.includes("notify:stop"));
470
696
  });
697
+
698
+ // ────────────────────────────────────────────────────────────────────────
699
+ // Stuck-loop ring buffer (issue #5787)
700
+ // ────────────────────────────────────────────────────────────────────────
701
+
702
+ test("STUCK_WINDOW_SIZE matches the legacy auto/phases.ts constant", () => {
703
+ assert.equal(STUCK_WINDOW_SIZE, 6);
704
+ });
705
+
706
+ test("stuck-loop: empty ring on a freshly constructed orchestrator advances normally", async () => {
707
+ const { deps } = makeDeps();
708
+ const orchestrator = createAutoOrchestrator(deps);
709
+
710
+ const result = await orchestrator.advance();
711
+
712
+ assert.equal(result.kind, "advanced");
713
+ });
714
+
715
+ test("stuck-loop: partial fill of mixed units does not block", async () => {
716
+ // Alternate A/B for STUCK_WINDOW_SIZE rounds. No single key saturates the
717
+ // window, so neither idempotency nor stuck-loop should fire.
718
+ let i = 0;
719
+ const sequence = ["A", "B", "A", "B", "A", "B"];
720
+ const { deps } = makeDeps({
721
+ dispatch: {
722
+ async decideNextUnit() {
723
+ const id = sequence[i++ % sequence.length];
724
+ return { unitType: "execute-task", unitId: id, reason: "ready", preconditions: [] };
725
+ },
726
+ },
727
+ });
728
+ const orchestrator = createAutoOrchestrator(deps);
729
+
730
+ for (let round = 0; round < STUCK_WINDOW_SIZE; round++) {
731
+ const result = await orchestrator.advance();
732
+ assert.equal(result.kind, "advanced", `round ${round} should advance, got ${result.kind}`);
733
+ }
734
+ });
735
+
736
+ test("stuck-loop: ring saturated with same unit blocks with action 'stop' and stuck-loop reason", async () => {
737
+ // Dispatch picks the same unit every time. The first advance succeeds.
738
+ // Calls 2..STUCK_WINDOW_SIZE-1 are idempotency-blocked while the ring fills.
739
+ // The STUCK_WINDOW_SIZE'th call sees a saturated ring and returns stuck-loop.
740
+ const { deps } = makeDeps();
741
+ const orchestrator = createAutoOrchestrator(deps);
742
+
743
+ const results: Awaited<ReturnType<typeof orchestrator.advance>>[] = [];
744
+ for (let i = 0; i < STUCK_WINDOW_SIZE; i++) {
745
+ results.push(await orchestrator.advance());
746
+ }
747
+
748
+ // First call advances.
749
+ assert.equal(results[0].kind, "advanced");
750
+
751
+ // Intermediate calls are blocked by idempotency (not stuck-loop yet).
752
+ for (let i = 1; i < STUCK_WINDOW_SIZE - 1; i++) {
753
+ const r = results[i];
754
+ assert.equal(r.kind, "blocked", `round ${i} should be blocked`);
755
+ if (r.kind !== "blocked") return;
756
+ assert.equal(r.reason, "idempotent advance: unit already active");
757
+ assert.equal(r.action, "pause");
758
+ }
759
+
760
+ // The final call (ring now holds STUCK_WINDOW_SIZE copies) returns stuck-loop.
761
+ const last = results[STUCK_WINDOW_SIZE - 1];
762
+ assert.equal(last.kind, "blocked");
763
+ if (last.kind !== "blocked") return;
764
+ assert.equal(last.action, "stop");
765
+ assert.equal(last.reason, `stuck-loop: execute-task:T01 picked ${STUCK_WINDOW_SIZE} times`);
766
+ });
767
+
768
+ test("stuck-loop: idempotency block continues to fire with its own reason before saturation", async () => {
769
+ // Two identical calls should produce idempotent (not stuck-loop). Ensures the
770
+ // existing idempotency block is not absorbed by the new check.
771
+ const { deps } = makeDeps();
772
+ const orchestrator = createAutoOrchestrator(deps);
773
+
774
+ const first = await orchestrator.advance();
775
+ const second = await orchestrator.advance();
776
+
777
+ assert.equal(first.kind, "advanced");
778
+ assert.equal(second.kind, "blocked");
779
+ assert.equal(second.reason, "idempotent advance: unit already active");
780
+ assert.equal(second.action, "pause");
781
+ });
782
+
783
+ test("stuck-loop: start() resets the ring so a fresh saturation cycle is required", async () => {
784
+ // Fill the ring to one short of saturation, then start() — the ring should
785
+ // be cleared, and the next advance must succeed instead of going stuck.
786
+ const { deps } = makeDeps();
787
+ const orchestrator = createAutoOrchestrator(deps);
788
+
789
+ for (let i = 0; i < STUCK_WINDOW_SIZE - 1; i++) {
790
+ await orchestrator.advance();
791
+ }
792
+
793
+ const restarted = await orchestrator.start({ basePath: "/tmp/project", trigger: "manual" });
794
+ assert.equal(restarted.kind, "started");
795
+
796
+ // Immediately after start(), the next advance should succeed because start()
797
+ // no longer pre-dispatches and the ring was reset.
798
+ const next = await orchestrator.advance();
799
+ assert.equal(next.kind, "advanced");
800
+ });
801
+
802
+ test("stuck-loop: resume() resets the ring", async () => {
803
+ const { deps } = makeDeps();
804
+ const orchestrator = createAutoOrchestrator(deps);
805
+
806
+ for (let i = 0; i < STUCK_WINDOW_SIZE - 1; i++) {
807
+ await orchestrator.advance();
808
+ }
809
+
810
+ const resumed = await orchestrator.resume();
811
+ assert.equal(resumed.kind, "resumed");
812
+
813
+ const next = await orchestrator.advance();
814
+ assert.equal(next.kind, "advanced");
815
+ });
816
+
817
+ test("stuck-loop: stop() resets the ring", async () => {
818
+ const { deps } = makeDeps();
819
+ const orchestrator = createAutoOrchestrator(deps);
820
+
821
+ for (let i = 0; i < STUCK_WINDOW_SIZE - 1; i++) {
822
+ await orchestrator.advance();
823
+ }
824
+
825
+ const stopped = await orchestrator.stop("user-request");
826
+ assert.equal(stopped.kind, "stopped");
827
+
828
+ // Ring is cleared by stop(). A subsequent advance is a fresh first-touch.
829
+ const next = await orchestrator.advance();
830
+ assert.equal(next.kind, "advanced");
831
+ });
832
+
833
+ test("stuck-loop: journal records the stuck-loop reason on advance-blocked", async () => {
834
+ const { deps, calls } = makeDeps();
835
+ const orchestrator = createAutoOrchestrator(deps);
836
+
837
+ for (let i = 0; i < STUCK_WINDOW_SIZE; i++) {
838
+ await orchestrator.advance();
839
+ }
840
+
841
+ assert.ok(calls.includes("journal:advance-blocked"));
842
+ });
843
+
844
+ // ─── #5789 parity: wired dispatch adapter mirrors runDispatch's resolveDispatch call ───
845
+
846
+ test("wired DispatchAdapter forwards session-derived dispatch inputs identically to runDispatch", async () => {
847
+ const stateSnapshot = makeState();
848
+
849
+ // Install a capturing registry so we observe the DispatchContext both code paths
850
+ // build, and force a deterministic dispatch action so the parity assertion is
851
+ // about *inputs*, not rule evaluation.
852
+ const captured: DispatchContext[] = [];
853
+ const captureRule: UnifiedRule = {
854
+ name: "test-capture",
855
+ when: "dispatch",
856
+ evaluation: "first-match",
857
+ where: async (ctx: DispatchContext) => {
858
+ captured.push(ctx);
859
+ return {
860
+ action: "dispatch" as const,
861
+ unitType: "execute-task",
862
+ unitId: "T01",
863
+ prompt: "parity-fixture",
864
+ };
865
+ },
866
+ then: (r: unknown) => r,
867
+ };
868
+ setRegistry(new RuleRegistry([captureRule]));
869
+
870
+ try {
871
+ // Mock ExtensionContext + ExtensionAPI with the surface the wired adapter touches.
872
+ const fakeModelRegistry = {
873
+ getAll: () => [],
874
+ getProviderAuthMode: (_provider: string) => "apiKey" as const,
875
+ };
876
+ const ctx = {
877
+ model: {
878
+ provider: "anthropic",
879
+ baseUrl: "https://api.anthropic.com",
880
+ contextWindow: 200_000,
881
+ },
882
+ modelRegistry: fakeModelRegistry,
883
+ } as any;
884
+ const pi = {
885
+ getActiveTools: () => ["read_file", "write_file"],
886
+ } as any;
887
+ const basePath = "/tmp/parity-fixture";
888
+
889
+ // Path A — wired adapter (what createWiredAutoOrchestrationModule uses).
890
+ const adapter = createWiredDispatchAdapter(ctx, pi, basePath);
891
+ const adapterResult = await adapter.decideNextUnit({ stateSnapshot });
892
+
893
+ // Path B — direct resolveDispatch call mirroring phases.ts:runDispatch.
894
+ // Inline the same derivations runDispatch uses so any drift here is a parity break.
895
+ const prefs = undefined; // loadEffectiveGSDPreferences returns null for /tmp/parity-fixture.
896
+ const provider = ctx.model?.provider;
897
+ const authMode = provider && typeof ctx.modelRegistry?.getProviderAuthMode === "function"
898
+ ? ctx.modelRegistry.getProviderAuthMode(provider)
899
+ : undefined;
900
+ const activeTools = typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [];
901
+ const structuredQuestionsAvailable: "true" | "false" =
902
+ prefs !== undefined && (prefs as { planning_depth?: string }).planning_depth === "deep"
903
+ ? "false"
904
+ : supportsStructuredQuestions(activeTools, {
905
+ authMode,
906
+ baseUrl: ctx.model?.baseUrl,
907
+ })
908
+ ? "true"
909
+ : "false";
910
+
911
+ const builtDirectCtx: DispatchContext = {
912
+ basePath,
913
+ mid: stateSnapshot.activeMilestone!.id,
914
+ midTitle: stateSnapshot.activeMilestone!.title,
915
+ state: stateSnapshot,
916
+ prefs,
917
+ structuredQuestionsAvailable,
918
+ sessionContextWindow: ctx.model?.contextWindow,
919
+ sessionProvider: ctx.model?.provider,
920
+ modelRegistry: ctx.modelRegistry,
921
+ };
922
+ const directAction = await resolveDispatch(builtDirectCtx);
923
+
924
+ // Two contexts captured: one per resolveDispatch call.
925
+ assert.equal(captured.length, 2, "expected two captured dispatch contexts");
926
+ const [adapterCtx, directCtx] = captured;
927
+
928
+ // Parity assertion: session-derived fields are identical.
929
+ assert.equal(adapterCtx.structuredQuestionsAvailable, directCtx.structuredQuestionsAvailable);
930
+ assert.equal(adapterCtx.sessionContextWindow, directCtx.sessionContextWindow);
931
+ assert.equal(adapterCtx.sessionProvider, directCtx.sessionProvider);
932
+ assert.equal(adapterCtx.modelRegistry, directCtx.modelRegistry);
933
+ assert.equal(adapterCtx.basePath, directCtx.basePath);
934
+ assert.equal(adapterCtx.mid, directCtx.mid);
935
+ assert.equal(adapterCtx.midTitle, directCtx.midTitle);
936
+
937
+ // Dispatch action equality: both flows reach the same dispatch decision.
938
+ if (!adapterResult || !("unitType" in adapterResult)) {
939
+ assert.fail("expected adapter result to be a dispatch decision");
940
+ }
941
+ assert.equal(adapterResult.unitType, "execute-task");
942
+ assert.equal(adapterResult.unitId, "T01");
943
+ assert.equal(adapterResult.reason, "test-capture");
944
+ assert.equal(directAction.action, "dispatch");
945
+ if (directAction.action === "dispatch") {
946
+ assert.equal(directAction.unitType, adapterResult.unitType);
947
+ assert.equal(directAction.unitId, adapterResult.unitId);
948
+ assert.equal(directAction.matchedRule, adapterResult.reason);
949
+ }
950
+ } finally {
951
+ resetRegistry();
952
+ }
953
+ });
954
+
955
+ test("wired DispatchAdapter prefers caller-supplied dispatch inputs over ctx-derived values", async () => {
956
+ const stateSnapshot = makeState();
957
+ const captured: DispatchContext[] = [];
958
+ const captureRule: UnifiedRule = {
959
+ name: "test-capture-overrides",
960
+ when: "dispatch",
961
+ evaluation: "first-match",
962
+ where: async (ctx: DispatchContext) => {
963
+ captured.push(ctx);
964
+ return {
965
+ action: "dispatch" as const,
966
+ unitType: "execute-task",
967
+ unitId: "T01",
968
+ prompt: "override-fixture",
969
+ };
970
+ },
971
+ then: (r: unknown) => r,
972
+ };
973
+ setRegistry(new RuleRegistry([captureRule]));
974
+
975
+ try {
976
+ const ctxModelRegistry = {
977
+ getAll: () => [],
978
+ getProviderAuthMode: (_provider: string) => "apiKey" as const,
979
+ };
980
+ const overrideModelRegistry = {
981
+ getAll: () => [],
982
+ getProviderAuthMode: (_provider: string) => "oauth" as const,
983
+ };
984
+ const ctx = {
985
+ model: {
986
+ provider: "anthropic",
987
+ baseUrl: "https://api.anthropic.com",
988
+ contextWindow: 200_000,
989
+ },
990
+ modelRegistry: ctxModelRegistry,
991
+ } as any;
992
+ const pi = {
993
+ getActiveTools: () => [],
994
+ } as any;
995
+ const adapter = createWiredDispatchAdapter(ctx, pi, "/tmp/parity-fixture");
996
+ const session = { basePath: "/tmp/session-fixture" } as any;
997
+
998
+ const result = await adapter.decideNextUnit({
999
+ stateSnapshot,
1000
+ session,
1001
+ structuredQuestionsAvailable: "true",
1002
+ sessionContextWindow: 500_000,
1003
+ sessionProvider: "openai",
1004
+ modelRegistry: overrideModelRegistry,
1005
+ });
1006
+
1007
+ assert.ok(result);
1008
+ assert.equal(captured.length, 1, "expected one captured dispatch context");
1009
+ assert.equal(captured[0].structuredQuestionsAvailable, "true");
1010
+ assert.equal(captured[0].sessionContextWindow, 500_000);
1011
+ assert.equal(captured[0].sessionProvider, "openai");
1012
+ assert.equal(captured[0].modelRegistry, overrideModelRegistry);
1013
+ assert.equal(captured[0].session, session);
1014
+ } finally {
1015
+ resetRegistry();
1016
+ }
1017
+ });
1018
+
1019
+ test("wired DispatchAdapter forwards constructor session when advance input omits session", async () => {
1020
+ const stateSnapshot = makeState();
1021
+ const captured: DispatchContext[] = [];
1022
+ const captureRule: UnifiedRule = {
1023
+ name: "test-session-fallback",
1024
+ when: "dispatch",
1025
+ evaluation: "first-match",
1026
+ where: async (ctx: DispatchContext) => {
1027
+ captured.push(ctx);
1028
+ return {
1029
+ action: "dispatch" as const,
1030
+ unitType: "execute-task",
1031
+ unitId: "T01",
1032
+ prompt: "session-fallback-fixture",
1033
+ };
1034
+ },
1035
+ then: (r: unknown) => r,
1036
+ };
1037
+ setRegistry(new RuleRegistry([captureRule]));
1038
+
1039
+ try {
1040
+ const ctx = { model: {}, modelRegistry: { getAll: () => [] } } as any;
1041
+ const pi = { getActiveTools: () => [] } as any;
1042
+ const session = {
1043
+ basePath: "/tmp/worktree-fixture",
1044
+ originalBasePath: "/tmp/project-fixture",
1045
+ currentMilestoneId: "M001",
1046
+ } as any;
1047
+ const adapter = createWiredDispatchAdapter(ctx, pi, "/tmp/project-fixture", session);
1048
+
1049
+ const result = await adapter.decideNextUnit({ stateSnapshot });
1050
+
1051
+ assert.ok(result);
1052
+ assert.equal(captured.length, 1, "expected one captured dispatch context");
1053
+ assert.equal(captured[0].session, session);
1054
+ } finally {
1055
+ resetRegistry();
1056
+ }
1057
+ });
1058
+
1059
+ test("wired DispatchAdapter preserves stop reason as a blocked decision", async () => {
1060
+ const stateSnapshot = makeState();
1061
+ const stopRule: UnifiedRule = {
1062
+ name: "test-stop",
1063
+ when: "dispatch",
1064
+ evaluation: "first-match",
1065
+ where: async () => ({
1066
+ action: "stop" as const,
1067
+ reason: "remediation blocker",
1068
+ level: "warning" as const,
1069
+ }),
1070
+ then: (r: unknown) => r,
1071
+ };
1072
+ setRegistry(new RuleRegistry([stopRule]));
1073
+
1074
+ try {
1075
+ const ctx = { model: {}, modelRegistry: { getAll: () => [] } } as any;
1076
+ const pi = { getActiveTools: () => [] } as any;
1077
+ const adapter = createWiredDispatchAdapter(ctx, pi, "/tmp/parity-fixture");
1078
+
1079
+ const result = await adapter.decideNextUnit({ stateSnapshot });
1080
+
1081
+ assert.deepEqual(result, {
1082
+ kind: "blocked",
1083
+ reason: "remediation blocker",
1084
+ action: "pause",
1085
+ });
1086
+ } finally {
1087
+ resetRegistry();
1088
+ }
1089
+ });