@opengsd/gsd-pi 1.1.1-dev.a5a2de8 → 1.1.1-dev.b2556262

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 (325) hide show
  1. package/dist/headless-recover.js +56 -1
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +18 -2
  4. package/dist/resources/extensions/browser-tools/engine/selection.js +1 -1
  5. package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
  6. package/dist/resources/extensions/browser-tools/index.js +68 -24
  7. package/dist/resources/extensions/browser-tools/state.js +12 -0
  8. package/dist/resources/extensions/browser-tools/tools/session.js +3 -2
  9. package/dist/resources/extensions/browser-tools/utils.js +3 -3
  10. package/dist/resources/extensions/browser-tools/web-app-detect.js +52 -0
  11. package/dist/resources/extensions/gsd/auto/loop.js +4 -2
  12. package/dist/resources/extensions/gsd/auto/phases.js +87 -12
  13. package/dist/resources/extensions/gsd/auto/session.js +22 -1
  14. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +1 -0
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +81 -13
  16. package/dist/resources/extensions/gsd/auto-model-selection.js +154 -9
  17. package/dist/resources/extensions/gsd/auto-post-unit.js +19 -2
  18. package/dist/resources/extensions/gsd/auto-prompts.js +26 -21
  19. package/dist/resources/extensions/gsd/auto-recovery.js +4 -2
  20. package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
  21. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  22. package/dist/resources/extensions/gsd/auto-timers.js +24 -10
  23. package/dist/resources/extensions/gsd/auto.js +40 -15
  24. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +192 -77
  26. package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
  27. package/dist/resources/extensions/gsd/closeout-wizard.js +32 -9
  28. package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -0
  29. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -9
  30. package/dist/resources/extensions/gsd/commands-maintenance.js +93 -15
  31. package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -1
  32. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +2 -2
  33. package/dist/resources/extensions/gsd/config-overlay.js +1 -0
  34. package/dist/resources/extensions/gsd/context-masker.js +129 -5
  35. package/dist/resources/extensions/gsd/db-writer.js +35 -0
  36. package/dist/resources/extensions/gsd/docs/preferences-reference.md +50 -1
  37. package/dist/resources/extensions/gsd/gsd-db.js +480 -172
  38. package/dist/resources/extensions/gsd/guided-flow.js +4 -1
  39. package/dist/resources/extensions/gsd/markdown-renderer.js +37 -53
  40. package/dist/resources/extensions/gsd/md-importer.js +38 -3
  41. package/dist/resources/extensions/gsd/migration-auto-check.js +126 -31
  42. package/dist/resources/extensions/gsd/parsers-legacy.js +23 -0
  43. package/dist/resources/extensions/gsd/planner-handoff.js +98 -0
  44. package/dist/resources/extensions/gsd/planning-path-scope.js +22 -4
  45. package/dist/resources/extensions/gsd/pre-execution-checks.js +10 -2
  46. package/dist/resources/extensions/gsd/preferences-models.js +111 -43
  47. package/dist/resources/extensions/gsd/preferences-types.js +13 -0
  48. package/dist/resources/extensions/gsd/preferences-validation.js +68 -3
  49. package/dist/resources/extensions/gsd/preferences.js +4 -1
  50. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
  51. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  52. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  53. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  54. package/dist/resources/extensions/gsd/prompts/run-uat.md +2 -2
  55. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  56. package/dist/resources/extensions/gsd/roadmap-slices.js +5 -1
  57. package/dist/resources/extensions/gsd/safety/content-validator.js +6 -4
  58. package/dist/resources/extensions/gsd/skill-manifest.js +12 -0
  59. package/dist/resources/extensions/gsd/source-observations.js +306 -0
  60. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +15 -8
  61. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +33 -5
  62. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +34 -13
  63. package/dist/resources/extensions/gsd/state-reconciliation/index.js +39 -14
  64. package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +4 -4
  65. package/dist/resources/extensions/gsd/state.js +7 -3
  66. package/dist/resources/extensions/gsd/tool-contract.js +15 -1
  67. package/dist/resources/extensions/gsd/tool-presentation-plan.js +24 -2
  68. package/dist/resources/extensions/gsd/tools/complete-slice.js +28 -0
  69. package/dist/resources/extensions/gsd/tools/plan-slice.js +42 -11
  70. package/dist/resources/extensions/gsd/tools/plan-task.js +7 -1
  71. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +62 -406
  72. package/dist/resources/extensions/gsd/uat-policy.js +130 -0
  73. package/dist/resources/extensions/gsd/uat-run.js +414 -0
  74. package/dist/resources/extensions/gsd/unit-context-manifest.js +3 -4
  75. package/dist/resources/extensions/gsd/unit-tool-contracts.js +38 -14
  76. package/dist/resources/extensions/gsd/verdict-parser.js +3 -8
  77. package/dist/resources/extensions/gsd/workflow-manifest.js +132 -5
  78. package/dist/resources/extensions/gsd/workflow-mcp.js +2 -3
  79. package/dist/resources/extensions/gsd/workflow-projections.js +8 -0
  80. package/dist/resources/extensions/gsd/worktree-manager.js +26 -0
  81. package/dist/resources/extensions/gsd/worktree-reentry.js +96 -0
  82. package/dist/resources/extensions/gsd/worktree-state-projection.js +18 -17
  83. package/dist/resources/extensions/shared/gsd-browser-cli.js +6 -0
  84. package/dist/resources/extensions/subagent/agents.js +1 -0
  85. package/dist/resources/extensions/subagent/index.js +27 -12
  86. package/dist/resources/extensions/subagent/launch.js +7 -2
  87. package/dist/web/standalone/.next/BUILD_ID +1 -1
  88. package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
  89. package/dist/web/standalone/.next/build-manifest.json +2 -2
  90. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  91. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/index.html +1 -1
  108. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
  115. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  116. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  118. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  119. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  120. package/dist/web/standalone/node_modules/@gsd/native/dist/native.js +22 -0
  121. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  122. package/package.json +4 -4
  123. package/packages/cloud-mcp-gateway/package.json +2 -2
  124. package/packages/contracts/package.json +1 -1
  125. package/packages/daemon/package.json +4 -4
  126. package/packages/gsd-agent-core/package.json +5 -5
  127. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  128. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js +21 -23
  129. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js.map +1 -1
  130. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +3 -0
  131. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  132. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -0
  133. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  134. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +1 -0
  135. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  136. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +66 -12
  137. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  138. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  139. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +18 -11
  140. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  141. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  142. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +16 -0
  143. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  144. package/packages/gsd-agent-modes/package.json +7 -7
  145. package/packages/mcp-server/dist/workflow-tools.js +1 -1
  146. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  147. package/packages/mcp-server/package.json +3 -3
  148. package/packages/native/dist/native.js +22 -0
  149. package/packages/native/package.json +1 -1
  150. package/packages/pi-agent-core/package.json +1 -1
  151. package/packages/pi-ai/dist/image-models.generated.d.ts +30 -0
  152. package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  153. package/packages/pi-ai/dist/image-models.generated.js +30 -0
  154. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  155. package/packages/pi-ai/dist/models.generated.d.ts +174 -29
  156. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  157. package/packages/pi-ai/dist/models.generated.js +178 -54
  158. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  159. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  160. package/packages/pi-ai/dist/providers/transform-messages.js +8 -1
  161. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  162. package/packages/pi-ai/package.json +1 -1
  163. package/packages/pi-coding-agent/dist/core/settings-manager.js +1 -1
  164. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  165. package/packages/pi-coding-agent/dist/theme/themes.js +1 -1
  166. package/packages/pi-coding-agent/dist/theme/themes.js.map +1 -1
  167. package/packages/pi-coding-agent/package.json +7 -7
  168. package/packages/pi-tui/dist/utils.d.ts +11 -0
  169. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  170. package/packages/pi-tui/dist/utils.js +119 -6
  171. package/packages/pi-tui/dist/utils.js.map +1 -1
  172. package/packages/pi-tui/package.json +2 -1
  173. package/packages/rpc-client/package.json +2 -2
  174. package/pkg/dist/theme/themes.js +1 -1
  175. package/pkg/dist/theme/themes.js.map +1 -1
  176. package/pkg/package.json +1 -1
  177. package/scripts/install/handoff.js +16 -3
  178. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +21 -2
  179. package/src/resources/extensions/browser-tools/engine/selection.ts +1 -1
  180. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  181. package/src/resources/extensions/browser-tools/index.ts +75 -27
  182. package/src/resources/extensions/browser-tools/state.ts +13 -0
  183. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +2 -2
  184. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +57 -0
  185. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +37 -0
  186. package/src/resources/extensions/browser-tools/tests/web-app-detect.test.mjs +68 -0
  187. package/src/resources/extensions/browser-tools/tools/session.ts +4 -2
  188. package/src/resources/extensions/browser-tools/utils.ts +3 -3
  189. package/src/resources/extensions/browser-tools/web-app-detect.ts +63 -0
  190. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  191. package/src/resources/extensions/gsd/auto/loop.ts +4 -2
  192. package/src/resources/extensions/gsd/auto/phases.ts +89 -15
  193. package/src/resources/extensions/gsd/auto/session.ts +24 -1
  194. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +1 -0
  195. package/src/resources/extensions/gsd/auto-dispatch.ts +117 -12
  196. package/src/resources/extensions/gsd/auto-model-selection.ts +190 -12
  197. package/src/resources/extensions/gsd/auto-post-unit.ts +20 -2
  198. package/src/resources/extensions/gsd/auto-prompts.ts +25 -22
  199. package/src/resources/extensions/gsd/auto-recovery.ts +22 -3
  200. package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
  201. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  202. package/src/resources/extensions/gsd/auto-timers.ts +25 -9
  203. package/src/resources/extensions/gsd/auto.ts +41 -14
  204. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
  205. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +250 -78
  206. package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
  207. package/src/resources/extensions/gsd/closeout-wizard.ts +47 -13
  208. package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -0
  209. package/src/resources/extensions/gsd/commands/handlers/ops.ts +2 -17
  210. package/src/resources/extensions/gsd/commands-maintenance.ts +124 -13
  211. package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -1
  212. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +2 -2
  213. package/src/resources/extensions/gsd/config-overlay.ts +1 -0
  214. package/src/resources/extensions/gsd/context-masker.ts +152 -5
  215. package/src/resources/extensions/gsd/db-writer.ts +38 -0
  216. package/src/resources/extensions/gsd/docs/preferences-reference.md +50 -1
  217. package/src/resources/extensions/gsd/gsd-db.ts +564 -186
  218. package/src/resources/extensions/gsd/guided-flow.ts +4 -1
  219. package/src/resources/extensions/gsd/markdown-renderer.ts +44 -66
  220. package/src/resources/extensions/gsd/md-importer.ts +49 -2
  221. package/src/resources/extensions/gsd/migration-auto-check.ts +154 -34
  222. package/src/resources/extensions/gsd/parsers-legacy.ts +20 -0
  223. package/src/resources/extensions/gsd/planner-handoff.ts +149 -0
  224. package/src/resources/extensions/gsd/planning-path-scope.ts +22 -4
  225. package/src/resources/extensions/gsd/pre-execution-checks.ts +9 -2
  226. package/src/resources/extensions/gsd/preferences-models.ts +113 -43
  227. package/src/resources/extensions/gsd/preferences-types.ts +47 -0
  228. package/src/resources/extensions/gsd/preferences-validation.ts +76 -2
  229. package/src/resources/extensions/gsd/preferences.ts +5 -0
  230. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
  231. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  232. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  233. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  234. package/src/resources/extensions/gsd/prompts/run-uat.md +2 -2
  235. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  236. package/src/resources/extensions/gsd/roadmap-slices.ts +6 -1
  237. package/src/resources/extensions/gsd/safety/content-validator.ts +8 -5
  238. package/src/resources/extensions/gsd/skill-manifest.ts +12 -0
  239. package/src/resources/extensions/gsd/source-observations.ts +402 -0
  240. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +20 -8
  241. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +44 -5
  242. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +39 -11
  243. package/src/resources/extensions/gsd/state-reconciliation/index.ts +45 -15
  244. package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +4 -4
  245. package/src/resources/extensions/gsd/state.ts +7 -4
  246. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +114 -0
  247. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +66 -4
  248. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +299 -1
  249. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +32 -0
  250. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +75 -3
  251. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +22 -1
  252. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -0
  253. package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +145 -0
  254. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +9 -0
  255. package/src/resources/extensions/gsd/tests/closeout-wizard.test.ts +44 -0
  256. package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +26 -1
  257. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +118 -0
  258. package/src/resources/extensions/gsd/tests/content-validator.test.ts +74 -0
  259. package/src/resources/extensions/gsd/tests/context-masker.test.ts +56 -1
  260. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +17 -2
  261. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +24 -0
  262. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +1 -11
  263. package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +64 -0
  264. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +15 -0
  265. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +62 -1
  266. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +4 -1
  267. package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +27 -0
  268. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -0
  269. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +42 -0
  270. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +7 -1
  271. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +1 -1
  272. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +99 -0
  273. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +99 -2
  274. package/src/resources/extensions/gsd/tests/plan-task.test.ts +19 -0
  275. package/src/resources/extensions/gsd/tests/planner-handoff.test.ts +100 -0
  276. package/src/resources/extensions/gsd/tests/preferences.test.ts +14 -0
  277. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +1 -0
  278. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +133 -0
  279. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +55 -0
  280. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +101 -1
  281. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +2 -2
  282. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +28 -0
  283. package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +5 -3
  284. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +162 -18
  285. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +4 -3
  286. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +8 -0
  287. package/src/resources/extensions/gsd/tests/source-observations.test.ts +275 -0
  288. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +43 -0
  289. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +76 -21
  290. package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +203 -0
  291. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +170 -0
  292. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +7 -1
  293. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  294. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +306 -1
  295. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +77 -10
  296. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +260 -5
  297. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +511 -1
  298. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +102 -0
  299. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +44 -0
  300. package/src/resources/extensions/gsd/tool-contract.ts +29 -1
  301. package/src/resources/extensions/gsd/tool-presentation-plan.ts +41 -6
  302. package/src/resources/extensions/gsd/tools/complete-slice.ts +29 -0
  303. package/src/resources/extensions/gsd/tools/plan-slice.ts +54 -12
  304. package/src/resources/extensions/gsd/tools/plan-task.ts +8 -1
  305. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +71 -489
  306. package/src/resources/extensions/gsd/types.ts +1 -0
  307. package/src/resources/extensions/gsd/uat-policy.ts +191 -0
  308. package/src/resources/extensions/gsd/uat-run.ts +550 -0
  309. package/src/resources/extensions/gsd/unit-context-manifest.ts +3 -4
  310. package/src/resources/extensions/gsd/unit-tool-contracts.ts +38 -14
  311. package/src/resources/extensions/gsd/verdict-parser.ts +3 -10
  312. package/src/resources/extensions/gsd/workflow-manifest.ts +193 -7
  313. package/src/resources/extensions/gsd/workflow-mcp.ts +2 -3
  314. package/src/resources/extensions/gsd/workflow-projections.ts +9 -0
  315. package/src/resources/extensions/gsd/worktree-manager.ts +32 -0
  316. package/src/resources/extensions/gsd/worktree-reentry.ts +103 -0
  317. package/src/resources/extensions/gsd/worktree-state-projection.ts +22 -22
  318. package/src/resources/extensions/shared/gsd-browser-cli.ts +6 -0
  319. package/src/resources/extensions/shared/tests/format-utils.test.ts +8 -3
  320. package/src/resources/extensions/subagent/agents.ts +4 -0
  321. package/src/resources/extensions/subagent/index.ts +28 -3
  322. package/src/resources/extensions/subagent/launch.ts +8 -0
  323. package/src/resources/extensions/subagent/tests/model-override.test.ts +31 -0
  324. /package/dist/web/standalone/.next/static/{9y3LeeR2uGr2yRj9RjY3D → tJOKQbQRO-9MiFDO8DIDS}/_buildManifest.js +0 -0
  325. /package/dist/web/standalone/.next/static/{9y3LeeR2uGr2yRj9RjY3D → tJOKQbQRO-9MiFDO8DIDS}/_ssgManifest.js +0 -0
@@ -9,9 +9,17 @@ import * as os from 'node:os';
9
9
  import {
10
10
  openDatabase,
11
11
  closeDatabase,
12
+ insertRequirement,
13
+ insertArtifact,
12
14
  insertMilestone,
13
15
  insertSlice,
14
16
  insertTask,
17
+ insertMemoryRow,
18
+ insertAssessment,
19
+ insertGateRow,
20
+ insertReplanHistory,
21
+ recordMilestoneCommitAttribution,
22
+ saveGateResult,
15
23
  _getAdapter,
16
24
  } from '../gsd-db.ts';
17
25
  import {
@@ -20,6 +28,7 @@ import {
20
28
  snapshotState,
21
29
  bootstrapFromManifest,
22
30
  } from '../workflow-manifest.ts';
31
+ import { getAllDecisionsFromMemories } from '../context-store.ts';
23
32
 
24
33
  function tempDir(): string {
25
34
  return fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-manifest-'));
@@ -33,6 +42,33 @@ function cleanupDir(dirPath: string): void {
33
42
  try { fs.rmSync(dirPath, { recursive: true, force: true }); } catch { /* best effort */ }
34
43
  }
35
44
 
45
+ function insertMemoryBackedDecision(id: string): void {
46
+ const now = '2026-01-01T00:00:00.000Z';
47
+ insertMemoryRow({
48
+ id: `MEM-${id}`,
49
+ category: 'architecture',
50
+ content: `Decision ${id} content`,
51
+ confidence: 0.85,
52
+ sourceUnitType: null,
53
+ sourceUnitId: null,
54
+ createdAt: now,
55
+ updatedAt: now,
56
+ scope: 'project',
57
+ tags: [],
58
+ structuredFields: {
59
+ sourceDecisionId: id,
60
+ when_context: 'M001',
61
+ scope: 'architecture',
62
+ decision: `Decision ${id}`,
63
+ choice: `Choice ${id}`,
64
+ rationale: `Rationale ${id}`,
65
+ made_by: 'agent',
66
+ revisable: 'Yes',
67
+ superseded_by: null,
68
+ },
69
+ });
70
+ }
71
+
36
72
  // ─── readManifest: no file ────────────────────────────────────────────────
37
73
 
38
74
  test('workflow-manifest: readManifest returns null when file does not exist', () => {
@@ -75,6 +111,12 @@ test('workflow-manifest: readManifest parses manifest written by writeManifest',
75
111
  assert.ok(Array.isArray(manifest!.slices));
76
112
  assert.ok(Array.isArray(manifest!.tasks));
77
113
  assert.ok(Array.isArray(manifest!.decisions));
114
+ assert.ok(Array.isArray(manifest!.requirements));
115
+ assert.ok(Array.isArray(manifest!.artifacts));
116
+ assert.ok(Array.isArray(manifest!.replan_history));
117
+ assert.ok(Array.isArray(manifest!.assessments));
118
+ assert.ok(Array.isArray(manifest!.quality_gates));
119
+ assert.ok(Array.isArray(manifest!.milestone_commit_attributions));
78
120
  assert.ok(Array.isArray(manifest!.verification_evidence));
79
121
  } finally {
80
122
  closeDatabase();
@@ -120,6 +162,136 @@ test('workflow-manifest: snapshotState captures tasks', () => {
120
162
  }
121
163
  });
122
164
 
165
+ test('workflow-manifest: snapshotState captures memory-backed decisions', () => {
166
+ const base = tempDir();
167
+ openDatabase(tempDbPath(base));
168
+ try {
169
+ insertMemoryBackedDecision('D900');
170
+
171
+ const snap = snapshotState();
172
+ const decision = snap.decisions.find((r) => r.id === 'D900');
173
+
174
+ assert.ok(decision !== undefined, 'D900 should appear in manifest decisions');
175
+ assert.strictEqual(decision!.decision, 'Decision D900');
176
+ assert.strictEqual(decision!.choice, 'Choice D900');
177
+ assert.strictEqual(decision!.rationale, 'Rationale D900');
178
+ } finally {
179
+ closeDatabase();
180
+ cleanupDir(base);
181
+ }
182
+ });
183
+
184
+ test('workflow-manifest: bootstrapFromManifest restores extended correctness rows', () => {
185
+ const base = tempDir();
186
+ openDatabase(tempDbPath(base));
187
+ try {
188
+ insertRequirement({
189
+ id: 'R100',
190
+ class: 'functional',
191
+ status: 'active',
192
+ description: 'Persist requirements',
193
+ why: 'Recovery needs requirements',
194
+ source: 'test',
195
+ primary_owner: 'S01',
196
+ supporting_slices: 'S00',
197
+ validation: 'manifest round-trip',
198
+ notes: 'important',
199
+ full_content: 'Full requirement content',
200
+ superseded_by: null,
201
+ });
202
+ insertArtifact({
203
+ path: '.gsd/milestones/M001/M001-VALIDATION.md',
204
+ artifact_type: 'VALIDATION',
205
+ milestone_id: 'M001',
206
+ slice_id: null,
207
+ task_id: null,
208
+ full_content: '# Validation\n\nPASS',
209
+ });
210
+ insertArtifact({
211
+ path: 'milestones/M001/slices/S01/S01-ASSESSMENT.md',
212
+ artifact_type: 'ASSESSMENT',
213
+ milestone_id: 'M001',
214
+ slice_id: 'S01',
215
+ task_id: null,
216
+ full_content: '# Assessment\n\nPASS',
217
+ });
218
+ insertMilestone({ id: 'M001', title: 'Tracked Milestone' });
219
+ insertSlice({ id: 'S00', milestoneId: 'M001', title: 'Dependency Slice' });
220
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Dependent Slice', depends: ['S00'] });
221
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', title: 'Tracked Task' });
222
+ insertAssessment({
223
+ path: '.gsd/milestones/M001/slices/S01/S01-ASSESSMENT.md',
224
+ milestoneId: 'M001',
225
+ sliceId: 'S01',
226
+ taskId: null,
227
+ status: 'pass',
228
+ scope: 'run-uat',
229
+ fullContent: '# UAT\n\nPASS',
230
+ });
231
+ insertReplanHistory({
232
+ milestoneId: 'M001',
233
+ sliceId: 'S01',
234
+ taskId: 'T01',
235
+ summary: 'Replan preserved',
236
+ previousArtifactPath: 'old.md',
237
+ replacementArtifactPath: 'new.md',
238
+ });
239
+ insertGateRow({ milestoneId: 'M001', sliceId: 'S01', gateId: 'Q3', scope: 'slice' });
240
+ saveGateResult({
241
+ milestoneId: 'M001',
242
+ sliceId: 'S01',
243
+ gateId: 'Q3',
244
+ verdict: 'pass',
245
+ rationale: 'Gate passed',
246
+ findings: 'No findings',
247
+ });
248
+ recordMilestoneCommitAttribution({
249
+ commitSha: 'abc123',
250
+ milestoneId: 'M001',
251
+ sliceId: 'S01',
252
+ taskId: 'T01',
253
+ source: 'recorded',
254
+ confidence: 0.95,
255
+ files: ['src/example.ts'],
256
+ createdAt: '2026-06-05T00:00:00.000Z',
257
+ });
258
+
259
+ writeManifest(base);
260
+ closeDatabase();
261
+
262
+ const newDbPath = path.join(base, 'new.db');
263
+ openDatabase(newDbPath);
264
+ const restored = bootstrapFromManifest(base);
265
+ assert.strictEqual(restored, true);
266
+
267
+ const snap = snapshotState();
268
+ assert.strictEqual(snap.requirements?.find((r) => r.id === 'R100')?.full_content, 'Full requirement content');
269
+ const artifact = snap.artifacts?.find((r) => r.path === '.gsd/milestones/M001/M001-VALIDATION.md');
270
+ assert.strictEqual(artifact?.full_content, '# Validation\n\nPASS');
271
+ assert.ok(artifact?.content_hash, 'artifact content_hash should round-trip through manifest restore');
272
+ assert.strictEqual(
273
+ fs.readFileSync(path.join(base, '.gsd', 'milestones', 'M001', 'M001-VALIDATION.md'), 'utf-8'),
274
+ '# Validation\n\nPASS',
275
+ );
276
+ assert.strictEqual(
277
+ fs.readFileSync(path.join(base, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'S01-ASSESSMENT.md'), 'utf-8'),
278
+ '# Assessment\n\nPASS',
279
+ );
280
+ assert.strictEqual(snap.assessments?.find((r) => r.scope === 'run-uat')?.status, 'pass');
281
+ assert.strictEqual(snap.replan_history?.find((r) => r.summary === 'Replan preserved')?.replacement_artifact_path, 'new.md');
282
+ assert.strictEqual(snap.quality_gates?.find((r) => r.gate_id === 'Q3')?.rationale, 'Gate passed');
283
+ assert.strictEqual(snap.milestone_commit_attributions?.find((r) => r.commit_sha === 'abc123')?.files_json, '["src/example.ts"]');
284
+
285
+ const dep = _getAdapter()!.prepare(
286
+ 'SELECT depends_on_slice_id FROM slice_dependencies WHERE milestone_id = ? AND slice_id = ?',
287
+ ).get('M001', 'S01') as Record<string, unknown> | undefined;
288
+ assert.strictEqual(dep?.['depends_on_slice_id'], 'S00');
289
+ } finally {
290
+ closeDatabase();
291
+ cleanupDir(base);
292
+ }
293
+ });
294
+
123
295
  // ─── bootstrapFromManifest ────────────────────────────────────────────────
124
296
 
125
297
  test('workflow-manifest: bootstrapFromManifest returns false when no manifest file', () => {
@@ -152,7 +324,7 @@ test('workflow-manifest: bootstrapFromManifest restores DB from manifest (round-
152
324
  milestoneId: 'M001',
153
325
  title: 'Restored Task',
154
326
  status: 'complete',
155
- planning: { targetRepositories: ['project'] },
327
+ planning: { fullPlanMd: '# Full Task Plan\n\nKeep this body.', targetRepositories: ['project'] },
156
328
  });
157
329
  writeManifest(base);
158
330
  closeDatabase();
@@ -176,6 +348,7 @@ test('workflow-manifest: bootstrapFromManifest restores DB from manifest (round-
176
348
  const t = snap.tasks.find((r) => r.id === 'T01');
177
349
  assert.ok(t !== undefined, 'T01 should be restored');
178
350
  assert.strictEqual(t!.status, 'complete');
351
+ assert.strictEqual(t!.full_plan_md, '# Full Task Plan\n\nKeep this body.');
179
352
  assert.deepEqual(t!.target_repositories, ['project']);
180
353
  } finally {
181
354
  closeDatabase();
@@ -207,6 +380,138 @@ test('workflow-manifest: bootstrapFromManifest preserves target_repositories', (
207
380
  }
208
381
  });
209
382
 
383
+ test('workflow-manifest: bootstrapFromManifest preserves optional rows from old manifests', () => {
384
+ const base = tempDir();
385
+ openDatabase(tempDbPath(base));
386
+ try {
387
+ insertMilestone({ id: 'M001', title: 'Old Manifest Milestone' });
388
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Old Manifest Slice' });
389
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', title: 'Old Manifest Task' });
390
+ writeManifest(base);
391
+
392
+ const manifestPath = path.join(base, '.gsd', 'state-manifest.json');
393
+ const oldManifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as Record<string, unknown>;
394
+ delete oldManifest['replan_history'];
395
+ delete oldManifest['assessments'];
396
+ delete oldManifest['quality_gates'];
397
+ delete oldManifest['milestone_commit_attributions'];
398
+ fs.writeFileSync(manifestPath, JSON.stringify(oldManifest, null, 2));
399
+ closeDatabase();
400
+
401
+ const newDbPath = path.join(base, 'new.db');
402
+ openDatabase(newDbPath);
403
+ insertMilestone({ id: 'M001', title: 'Existing Milestone' });
404
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Existing Slice' });
405
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', title: 'Existing Task' });
406
+ insertAssessment({
407
+ path: '.gsd/milestones/M001/M001-VALIDATION.md',
408
+ milestoneId: 'M001',
409
+ status: 'pass',
410
+ scope: 'validate-milestone',
411
+ fullContent: '# Existing Validation',
412
+ });
413
+ insertReplanHistory({
414
+ milestoneId: 'M001',
415
+ sliceId: 'S01',
416
+ taskId: 'T01',
417
+ summary: 'Existing replan row',
418
+ previousArtifactPath: 'before.md',
419
+ replacementArtifactPath: 'after.md',
420
+ });
421
+ insertGateRow({ milestoneId: 'M001', sliceId: 'S01', gateId: 'Q3', scope: 'slice' });
422
+ saveGateResult({
423
+ milestoneId: 'M001',
424
+ sliceId: 'S01',
425
+ gateId: 'Q3',
426
+ verdict: 'pass',
427
+ rationale: 'Existing gate',
428
+ findings: 'No findings',
429
+ });
430
+ recordMilestoneCommitAttribution({
431
+ commitSha: 'def456',
432
+ milestoneId: 'M001',
433
+ source: 'recorded',
434
+ confidence: 0.8,
435
+ files: ['src/kept.ts'],
436
+ createdAt: '2026-06-05T00:00:00.000Z',
437
+ });
438
+
439
+ const restored = bootstrapFromManifest(base);
440
+ assert.strictEqual(restored, true);
441
+
442
+ const snap = snapshotState();
443
+ assert.strictEqual(snap.assessments?.find((r) => r.path.endsWith('VALIDATION.md'))?.full_content, '# Existing Validation');
444
+ assert.strictEqual(snap.replan_history?.find((r) => r.summary === 'Existing replan row')?.replacement_artifact_path, 'after.md');
445
+ assert.strictEqual(snap.quality_gates?.find((r) => r.gate_id === 'Q3')?.rationale, 'Existing gate');
446
+ assert.strictEqual(snap.milestone_commit_attributions?.find((r) => r.commit_sha === 'def456')?.files_json, '["src/kept.ts"]');
447
+ } finally {
448
+ closeDatabase();
449
+ cleanupDir(base);
450
+ }
451
+ });
452
+
453
+ test('workflow-manifest: bootstrapFromManifest restores memory-backed decisions', () => {
454
+ const base = tempDir();
455
+ openDatabase(tempDbPath(base));
456
+ try {
457
+ insertMemoryBackedDecision('D901');
458
+ writeManifest(base);
459
+ closeDatabase();
460
+
461
+ const newDbPath = path.join(base, 'new.db');
462
+ openDatabase(newDbPath);
463
+ const restored = bootstrapFromManifest(base);
464
+ assert.strictEqual(restored, true);
465
+
466
+ const decision = getAllDecisionsFromMemories().find((r) => r.id === 'D901');
467
+ assert.ok(decision !== undefined, 'D901 should be restored into the memory-backed decision surface');
468
+ assert.strictEqual(decision!.decision, 'Decision D901');
469
+ } finally {
470
+ closeDatabase();
471
+ cleanupDir(base);
472
+ }
473
+ });
474
+
475
+ test('workflow-manifest: bootstrapFromManifest replaces stale memory-backed decisions', () => {
476
+ const base = tempDir();
477
+ openDatabase(tempDbPath(base));
478
+ try {
479
+ insertMemoryBackedDecision('D902');
480
+ writeManifest(base);
481
+ closeDatabase();
482
+
483
+ const newDbPath = path.join(base, 'new.db');
484
+ openDatabase(newDbPath);
485
+ insertMemoryBackedDecision('D-STALE');
486
+ insertMemoryRow({
487
+ id: 'MEM-NOTE',
488
+ category: 'note',
489
+ content: 'Keep this non-decision memory',
490
+ confidence: 0.9,
491
+ sourceUnitType: null,
492
+ sourceUnitId: null,
493
+ createdAt: '2026-01-01T00:00:00.000Z',
494
+ updatedAt: '2026-01-01T00:00:00.000Z',
495
+ scope: 'project',
496
+ tags: ['keep'],
497
+ structuredFields: { kind: 'ordinary-note' },
498
+ });
499
+
500
+ const restored = bootstrapFromManifest(base);
501
+ assert.strictEqual(restored, true);
502
+
503
+ const decisions = getAllDecisionsFromMemories();
504
+ assert.ok(decisions.some((r) => r.id === 'D902'), 'manifest decision should be restored into memories');
505
+ assert.equal(decisions.some((r) => r.id === 'D-STALE'), false, 'stale memory-backed decision should be removed');
506
+
507
+ const note = _getAdapter()!.prepare('SELECT id FROM memories WHERE id = ?').get('MEM-NOTE') as Record<string, unknown> | undefined;
508
+ assert.strictEqual(note?.['id'], 'MEM-NOTE');
509
+ } finally {
510
+ closeDatabase();
511
+ cleanupDir(base);
512
+ }
513
+ });
514
+
210
515
  test('workflow-manifest: insertTask can clear target_repositories with explicit empty array', () => {
211
516
  const base = tempDir();
212
517
  openDatabase(tempDbPath(base));
@@ -48,12 +48,52 @@ test("auto execute-task requires canonical task completion tool", () => {
48
48
  assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("execute-task"), ["gsd_task_complete"]);
49
49
  });
50
50
 
51
+ test("plan-slice requires planning and roadmap reassessment tools", () => {
52
+ const expected = ["gsd_plan_slice", "gsd_reassess_roadmap"];
53
+ assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("plan-slice"), expected);
54
+ assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("plan-slice"), expected);
55
+ });
56
+
57
+ test("plan-milestone requires status, roadmap, and single-slice planning tools", () => {
58
+ const expected = ["gsd_milestone_status", "gsd_plan_milestone", "gsd_plan_slice"];
59
+ assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("plan-milestone"), expected);
60
+ assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("plan-milestone"), expected);
61
+ });
62
+
63
+ test("refine-slice requires canonical slice planning tool", () => {
64
+ assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("refine-slice"), ["gsd_plan_slice"]);
65
+ assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("refine-slice"), ["gsd_plan_slice"]);
66
+ });
67
+
51
68
  test("complete-slice requires closeout and execution handoff tools", () => {
52
- const expected = ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice"];
69
+ const expected = [
70
+ "gsd_slice_complete",
71
+ "gsd_task_reopen",
72
+ "gsd_replan_slice",
73
+ "gsd_requirement_update",
74
+ "gsd_summary_save",
75
+ ];
53
76
  assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("complete-slice"), expected);
54
77
  assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("complete-slice"), expected);
55
78
  });
56
79
 
80
+ test("complete-milestone requires status, requirement, project refresh, and closeout tools", () => {
81
+ const expected = [
82
+ "gsd_milestone_status",
83
+ "gsd_requirement_update",
84
+ "gsd_summary_save",
85
+ "gsd_complete_milestone",
86
+ ];
87
+ assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("complete-milestone"), expected);
88
+ assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("complete-milestone"), expected);
89
+ });
90
+
91
+ test("reactive-execute requires task completion and failed-task summary tools", () => {
92
+ const expected = ["gsd_task_complete", "gsd_summary_save"];
93
+ assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("reactive-execute"), expected);
94
+ assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("reactive-execute"), expected);
95
+ });
96
+
57
97
  test("workflow MCP capability surface includes native legacy gsd aliases", () => {
58
98
  const err = getWorkflowTransportSupportError(
59
99
  "claude-code",
@@ -679,7 +719,7 @@ test("transport compatibility ignores API-backed providers", () => {
679
719
  test("transport compatibility now allows plan-slice over workflow MCP surface", () => {
680
720
  const error = getWorkflowTransportSupportError(
681
721
  "claude-code",
682
- ["gsd_plan_slice"],
722
+ getRequiredWorkflowToolsForAutoUnit("plan-slice"),
683
723
  {
684
724
  projectRoot: "/tmp/project",
685
725
  env: { GSD_WORKFLOW_MCP_COMMAND: "node" },
@@ -696,7 +736,7 @@ test("transport compatibility now allows plan-slice over workflow MCP surface",
696
736
  test("transport compatibility now allows complete-slice over workflow MCP surface", () => {
697
737
  const error = getWorkflowTransportSupportError(
698
738
  "claude-code",
699
- ["gsd_complete_slice"],
739
+ getRequiredWorkflowToolsForAutoUnit("complete-slice"),
700
740
  {
701
741
  projectRoot: "/tmp/project",
702
742
  env: { GSD_WORKFLOW_MCP_COMMAND: "node" },
@@ -747,7 +787,7 @@ test("transport compatibility now allows gate-evaluate over workflow MCP surface
747
787
  test("transport compatibility now allows validate-milestone over workflow MCP surface", () => {
748
788
  const error = getWorkflowTransportSupportError(
749
789
  "claude-code",
750
- ["gsd_milestone_status", "gsd_validate_milestone"],
790
+ getRequiredWorkflowToolsForAutoUnit("validate-milestone"),
751
791
  {
752
792
  projectRoot: "/tmp/project",
753
793
  env: { GSD_WORKFLOW_MCP_COMMAND: "node" },
@@ -764,7 +804,7 @@ test("transport compatibility now allows validate-milestone over workflow MCP su
764
804
  test("transport compatibility now allows complete-milestone over workflow MCP surface", () => {
765
805
  const error = getWorkflowTransportSupportError(
766
806
  "claude-code",
767
- ["gsd_milestone_status", "gsd_complete_milestone"],
807
+ getRequiredWorkflowToolsForAutoUnit("complete-milestone"),
768
808
  {
769
809
  projectRoot: "/tmp/project",
770
810
  env: { GSD_WORKFLOW_MCP_COMMAND: "node" },
@@ -795,7 +835,7 @@ test("transport compatibility now allows replan-slice over workflow MCP surface"
795
835
  assert.equal(error, null);
796
836
  });
797
837
 
798
- test("transport compatibility accepts workflow MCP tools absent from parent active tool surface", () => {
838
+ test("transport compatibility rejects MCP tools not connected in active tool surface", () => {
799
839
  const error = getWorkflowTransportSupportError(
800
840
  "claude-code",
801
841
  ["gsd_summary_save"],
@@ -810,10 +850,10 @@ test("transport compatibility accepts workflow MCP tools absent from parent acti
810
850
  },
811
851
  );
812
852
 
813
- assert.equal(error, null);
853
+ assert.match(error ?? "", /requires gsd_summary_save/);
814
854
  });
815
855
 
816
- test("transport compatibility still checks non-MCP tools against parent active tool surface", () => {
856
+ test("transport compatibility checks all required tools against active tool surface", () => {
817
857
  const error = getWorkflowTransportSupportError(
818
858
  "claude-code",
819
859
  ["gsd_summary_save", "secure_env_collect"],
@@ -828,8 +868,9 @@ test("transport compatibility still checks non-MCP tools against parent active t
828
868
  },
829
869
  );
830
870
 
831
- assert.match(error ?? "", /requires secure_env_collect/);
832
- assert.doesNotMatch(error ?? "", /gsd_summary_save/);
871
+ assert.match(error ?? "", /requires.*(?:gsd_summary_save|secure_env_collect)/);
872
+ assert.match(error ?? "", /gsd_summary_save/);
873
+ assert.match(error ?? "", /secure_env_collect/);
833
874
  });
834
875
 
835
876
  test("transport compatibility still blocks units whose MCP tools are not exposed", () => {
@@ -850,6 +891,32 @@ test("transport compatibility still blocks units whose MCP tools are not exposed
850
891
  assert.match(error ?? "", /currently exposes only/);
851
892
  });
852
893
 
894
+ test("discuss-milestone guided flow does not abort when all required tools are on MCP surface (regression #469)", () => {
895
+ // Guided flow starts the workflow MCP server as part of dispatch, so the
896
+ // parent session active-tool list is not authoritative for MCP tools.
897
+ const discussMilestoneTools = [
898
+ "gsd_summary_save",
899
+ "gsd_requirement_save",
900
+ "gsd_requirement_update",
901
+ "gsd_plan_milestone",
902
+ "gsd_milestone_generate_id",
903
+ ];
904
+ const error = getWorkflowTransportSupportError(
905
+ "claude-code",
906
+ discussMilestoneTools,
907
+ {
908
+ projectRoot: "/tmp/project",
909
+ env: { GSD_WORKFLOW_MCP_COMMAND: "node" },
910
+ surface: "guided flow",
911
+ unitType: "discuss-milestone",
912
+ authMode: "externalCli",
913
+ baseUrl: "local://claude-code",
914
+ },
915
+ );
916
+
917
+ assert.equal(error, null);
918
+ });
919
+
853
920
  test("transport compatibility accepts MCP-namespaced runtime tools", () => {
854
921
  const error = getWorkflowTransportSupportError(
855
922
  "claude-code",