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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (575) hide show
  1. package/dist/cli-style.d.ts +17 -0
  2. package/dist/cli-style.js +28 -0
  3. package/dist/cli.js +1 -1
  4. package/dist/headless-events.d.ts +4 -2
  5. package/dist/headless-events.js +14 -34
  6. package/dist/mcp-server.js +2 -1
  7. package/dist/models-resolver.d.ts +3 -13
  8. package/dist/models-resolver.js +3 -22
  9. package/dist/resource-loader.d.ts +10 -5
  10. package/dist/resource-loader.js +123 -20
  11. package/dist/resources/.managed-resources-content-hash +1 -1
  12. package/dist/resources/GSD-WORKFLOW.md +5 -4
  13. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  14. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  15. package/dist/resources/extensions/async-jobs/index.js +65 -0
  16. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  17. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  18. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  19. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  20. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  21. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  22. package/dist/resources/extensions/bg-shell/utilities.js +3 -0
  23. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  24. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  25. package/dist/resources/extensions/browser-tools/index.js +69 -12
  26. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +30 -4
  27. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  28. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  29. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  30. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  31. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  32. package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
  33. package/dist/resources/extensions/gsd/auto/phases.js +49 -6
  34. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  35. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  36. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  37. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  38. package/dist/resources/extensions/gsd/auto-post-unit.js +35 -8
  39. package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
  40. package/dist/resources/extensions/gsd/auto-start.js +41 -18
  41. package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
  42. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  43. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
  44. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  45. package/dist/resources/extensions/gsd/auto-worktree.js +44 -91
  46. package/dist/resources/extensions/gsd/auto.js +41 -14
  47. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  48. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
  49. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
  50. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  51. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  52. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +212 -48
  53. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +303 -77
  54. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  55. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  56. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  57. package/dist/resources/extensions/gsd/captures.js +4 -6
  58. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  59. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  60. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  61. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  62. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  63. package/dist/resources/extensions/gsd/constants.js +0 -2
  64. package/dist/resources/extensions/gsd/crash-recovery.js +12 -15
  65. package/dist/resources/extensions/gsd/db/queries.js +26 -0
  66. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  67. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  68. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  69. package/dist/resources/extensions/gsd/doctor-environment.js +2 -6
  70. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  71. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  72. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -15
  73. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  74. package/dist/resources/extensions/gsd/error-classifier.js +9 -0
  75. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  76. package/dist/resources/extensions/gsd/files.js +33 -19
  77. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  78. package/dist/resources/extensions/gsd/gsd-db.js +2 -1
  79. package/dist/resources/extensions/gsd/guidance.js +158 -0
  80. package/dist/resources/extensions/gsd/guided-flow.js +23 -5
  81. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  82. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  83. package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
  84. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  85. package/dist/resources/extensions/gsd/migrate/safety.js +4 -1
  86. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  87. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  88. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  89. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  90. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -4
  91. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  92. package/dist/resources/extensions/gsd/paths.js +27 -0
  93. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  94. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  95. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  96. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  97. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  98. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  99. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  100. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  101. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  102. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  103. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  104. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  105. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  106. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  107. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
  108. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  109. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  110. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  111. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  112. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  113. package/dist/resources/extensions/gsd/publication.js +87 -0
  114. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  115. package/dist/resources/extensions/gsd/recovery-classification.js +37 -94
  116. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  117. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  118. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  119. package/dist/resources/extensions/gsd/state.js +6 -20
  120. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  121. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  122. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  123. package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
  124. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  125. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  126. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
  127. package/dist/resources/extensions/gsd/tools/exec-tool.js +9 -7
  128. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
  129. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  130. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  131. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  132. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  133. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  134. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  135. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  136. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  137. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  138. package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
  139. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  140. package/dist/resources/extensions/gsd/unit-registry.js +337 -0
  141. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
  142. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  143. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  144. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  145. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  146. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  147. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  148. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  149. package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
  150. package/dist/resources/extensions/gsd/worktree-git-recovery.js +15 -9
  151. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  152. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  153. package/dist/resources/extensions/gsd/worktree-root.js +11 -0
  154. package/dist/resources/extensions/gsd/worktree-session-state.js +4 -5
  155. package/dist/resources/extensions/gsd/worktree.js +8 -1
  156. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  157. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  158. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  159. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  160. package/dist/resources/shared/package-manager-detection.js +1 -1
  161. package/dist/resources/shared/package.json +3 -0
  162. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  163. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  164. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  165. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  166. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  167. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  168. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  169. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  170. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  171. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  172. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  173. package/dist/update-check.d.ts +2 -0
  174. package/dist/update-check.js +24 -1
  175. package/dist/update-cmd.js +20 -3
  176. package/dist/web/standalone/.next/BUILD_ID +1 -1
  177. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  178. package/dist/web/standalone/.next/build-manifest.json +3 -3
  179. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  180. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  181. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  182. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  183. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  184. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  190. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  191. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  192. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  193. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  194. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  195. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  196. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  197. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/index.html +1 -1
  200. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  205. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  207. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  208. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  209. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  212. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  213. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  214. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  215. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  216. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  217. package/dist/web/standalone/package.json +1 -1
  218. package/dist/worktree-cli.js +3 -6
  219. package/dist/worktree-status-banner.js +7 -15
  220. package/package.json +2 -2
  221. package/packages/cloud-mcp-gateway/package.json +2 -2
  222. package/packages/contracts/dist/rpc.d.ts +1 -0
  223. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  224. package/packages/contracts/dist/rpc.js.map +1 -1
  225. package/packages/contracts/dist/workflow.d.ts +4 -0
  226. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  227. package/packages/contracts/dist/workflow.js.map +1 -1
  228. package/packages/contracts/package.json +1 -1
  229. package/packages/daemon/package.json +4 -4
  230. package/packages/gsd-agent-core/package.json +5 -5
  231. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  232. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  233. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  234. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  235. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  236. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  237. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  238. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  239. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  240. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  241. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  242. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  243. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  244. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  245. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  246. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  247. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  248. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  249. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  250. package/packages/gsd-agent-modes/package.json +7 -7
  251. package/packages/mcp-server/dist/cli.js +9 -1
  252. package/packages/mcp-server/dist/cli.js.map +1 -1
  253. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  254. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  255. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  256. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  257. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  258. package/packages/mcp-server/dist/server.js +4 -0
  259. package/packages/mcp-server/dist/server.js.map +1 -1
  260. package/packages/mcp-server/dist/workflow-tools.d.ts +26 -18
  261. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  262. package/packages/mcp-server/dist/workflow-tools.js +116 -39
  263. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  264. package/packages/mcp-server/package.json +5 -4
  265. package/packages/native/package.json +1 -1
  266. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  267. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  268. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  269. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  270. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  271. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  272. package/packages/pi-agent-core/dist/index.js +3 -0
  273. package/packages/pi-agent-core/dist/index.js.map +1 -1
  274. package/packages/pi-agent-core/package.json +1 -1
  275. package/packages/pi-ai/README.md +1 -0
  276. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  277. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  278. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  279. package/packages/pi-ai/dist/index.d.ts +2 -0
  280. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  281. package/packages/pi-ai/dist/index.js +2 -0
  282. package/packages/pi-ai/dist/index.js.map +1 -1
  283. package/packages/pi-ai/dist/models.generated.d.ts +35 -125
  284. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  285. package/packages/pi-ai/dist/models.generated.js +46 -120
  286. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  287. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  288. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  289. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  290. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  291. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  292. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  293. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  294. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  295. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  296. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  297. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  298. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  299. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  300. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  301. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  302. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  303. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  304. package/packages/pi-ai/package.json +3 -2
  305. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  306. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  307. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  308. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  311. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  313. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  315. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  317. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/index.js +1 -1
  319. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  321. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  323. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  324. package/packages/pi-coding-agent/package.json +7 -7
  325. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  326. package/packages/pi-tui/dist/tui.js +9 -0
  327. package/packages/pi-tui/dist/tui.js.map +1 -1
  328. package/packages/pi-tui/package.json +2 -2
  329. package/packages/rpc-client/package.json +2 -2
  330. package/pkg/package.json +1 -1
  331. package/src/resources/GSD-WORKFLOW.md +5 -4
  332. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  333. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  334. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  335. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  336. package/src/resources/extensions/async-jobs/index.ts +79 -0
  337. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  338. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  339. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  340. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  341. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  342. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  343. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  344. package/src/resources/extensions/bg-shell/utilities.ts +3 -0
  345. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  346. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  347. package/src/resources/extensions/browser-tools/index.ts +71 -13
  348. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  349. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  350. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  351. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +34 -4
  352. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  353. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  354. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  355. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  356. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  357. package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
  358. package/src/resources/extensions/gsd/auto/phases.ts +65 -26
  359. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  360. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  361. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  362. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  363. package/src/resources/extensions/gsd/auto-post-unit.ts +40 -8
  364. package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
  365. package/src/resources/extensions/gsd/auto-start.ts +42 -21
  366. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  367. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  368. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
  369. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  370. package/src/resources/extensions/gsd/auto-worktree.ts +44 -94
  371. package/src/resources/extensions/gsd/auto.ts +52 -16
  372. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  373. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
  374. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
  375. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  376. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  377. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +251 -47
  378. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +352 -84
  379. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  380. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  381. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  382. package/src/resources/extensions/gsd/captures.ts +4 -6
  383. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  384. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  385. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  386. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  387. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  388. package/src/resources/extensions/gsd/constants.ts +0 -3
  389. package/src/resources/extensions/gsd/crash-recovery.ts +13 -11
  390. package/src/resources/extensions/gsd/db/queries.ts +37 -0
  391. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  392. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  393. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  394. package/src/resources/extensions/gsd/doctor-environment.ts +2 -7
  395. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  396. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  397. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +13 -15
  398. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  399. package/src/resources/extensions/gsd/error-classifier.ts +11 -0
  400. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  401. package/src/resources/extensions/gsd/files.ts +33 -12
  402. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  403. package/src/resources/extensions/gsd/gsd-db.ts +4 -3
  404. package/src/resources/extensions/gsd/guidance.ts +217 -0
  405. package/src/resources/extensions/gsd/guided-flow.ts +37 -28
  406. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  407. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  408. package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
  409. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  410. package/src/resources/extensions/gsd/migrate/safety.ts +4 -1
  411. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  412. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  413. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  414. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  415. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -4
  416. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  417. package/src/resources/extensions/gsd/paths.ts +33 -0
  418. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  419. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  420. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  421. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  422. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  423. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  424. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  425. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  426. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  427. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  428. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  429. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  430. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  431. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  432. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
  433. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  434. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  435. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  436. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  437. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  438. package/src/resources/extensions/gsd/publication.ts +122 -0
  439. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  440. package/src/resources/extensions/gsd/recovery-classification.ts +42 -96
  441. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  442. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  443. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  444. package/src/resources/extensions/gsd/state.ts +9 -21
  445. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  446. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  447. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
  448. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  449. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  450. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  451. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  452. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  453. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  454. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  455. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
  456. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
  457. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  458. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  459. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  460. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  461. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  462. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  463. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  464. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  465. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  466. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  467. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  468. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  469. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  470. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  471. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  472. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  473. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  474. package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
  475. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
  476. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +53 -11
  477. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +73 -58
  478. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  479. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  480. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  481. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  482. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  483. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  484. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  485. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  486. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
  487. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  488. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  489. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  490. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  491. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  492. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  493. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +157 -0
  494. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  495. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -1
  496. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  497. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  498. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  499. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  500. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
  501. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  502. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  503. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  504. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  505. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
  506. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  507. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  508. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  509. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  510. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  511. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  512. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  513. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
  514. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  515. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  516. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  517. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  518. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  519. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  520. package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
  521. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  522. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  523. package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
  524. package/src/resources/extensions/gsd/tools/exec-tool.ts +8 -7
  525. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
  526. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  527. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  528. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  529. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  530. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  531. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  532. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  533. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  534. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  535. package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
  536. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  537. package/src/resources/extensions/gsd/unit-registry.ts +412 -0
  538. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
  539. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  540. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  541. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  542. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  543. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  544. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  545. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  546. package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
  547. package/src/resources/extensions/gsd/worktree-git-recovery.ts +15 -9
  548. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  549. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  550. package/src/resources/extensions/gsd/worktree-root.ts +12 -0
  551. package/src/resources/extensions/gsd/worktree-session-state.ts +3 -5
  552. package/src/resources/extensions/gsd/worktree.ts +7 -1
  553. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  554. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  555. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  556. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  557. package/src/resources/shared/package-manager-detection.ts +1 -1
  558. package/src/resources/shared/package.json +3 -0
  559. package/src/resources/skills/create-skill/SKILL.md +3 -0
  560. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  561. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  562. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  563. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  564. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  565. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  566. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  567. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  568. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  569. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  570. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  571. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  572. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  573. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  574. /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_buildManifest.js +0 -0
  575. /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_ssgManifest.js +0 -0
@@ -26,12 +26,11 @@ import { gsdProjectionRoot, clearPathCache, resolveMilestoneFile } from "../path
26
26
  import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
27
27
  import { checkOwnership, sliceUnitKey } from "../unit-ownership.js";
28
28
  import { saveFile, clearParseCache } from "../files.js";
29
- import { getDeclaredUatType, shouldEscalateArtifactUatToBrowser } from "../uat-policy.js";
29
+ import { classifyUatContent, escalatesArtifactUatToBrowser } from "../uat-policy.js";
30
30
  import { invalidateStateCache } from "../state.js";
31
- import { renderRoadmapFromDb } from "../markdown-renderer.js";
32
- import { parseRoadmap } from "../parsers-legacy.js";
31
+ import { renderRoadmapFromDb, roadmapRenderMarksSliceDone } from "../markdown-renderer.js";
33
32
  import { isStaleWrite } from "../auto/turn-epoch.js";
34
- import { renderAllProjections } from "../workflow-projections.js";
33
+ import { flushWorkflowProjections } from "../projection-flush.js";
35
34
  import { writeManifest } from "../workflow-manifest.js";
36
35
  import { appendEvent } from "../workflow-events.js";
37
36
  import { logWarning, logError } from "../workflow-logger.js";
@@ -91,9 +90,11 @@ function hasCompleteSliceArtifactContract(basePath: string, milestoneId: string,
91
90
  join(gsdProjectionRoot(basePath), "milestones", milestoneId, `${milestoneId}-ROADMAP.md`);
92
91
  if (!existsSync(roadmapPath)) return false;
93
92
 
93
+ // Projection-completeness check (ADR-017): the DB has already recorded the
94
+ // duplicate completion; this only verifies the rendered markdown artifacts
95
+ // exist and reflect it, deciding whether re-rendering is needed.
94
96
  try {
95
- const roadmap = parseRoadmap(readFileSync(roadmapPath, "utf-8"));
96
- return roadmap.slices.some((slice) => slice.id === sliceId && slice.done);
97
+ return roadmapRenderMarksSliceDone(readFileSync(roadmapPath, "utf-8"), sliceId);
97
98
  } catch {
98
99
  return false;
99
100
  }
@@ -355,10 +356,18 @@ export async function handleCompleteSlice(
355
356
  // `npx playwright test` via gsd_uat_exec, and live-runtime/mixed/
356
357
  // browser-executable receive browser tools (UAT_MODE_POLICIES).
357
358
  const uatContent = params.uatContent || "";
358
- const declaredUatMode = getDeclaredUatType(uatContent);
359
- if (shouldEscalateArtifactUatToBrowser(uatContent)) {
359
+ const uatPolicy = classifyUatContent(uatContent);
360
+ if (escalatesArtifactUatToBrowser(uatPolicy)) {
361
+ // Distinguish an explicit artifact-driven declaration from a missing or
362
+ // unparseable one that merely *defaulted* to artifact-driven — telling an
363
+ // agent it "declared artifact-driven" when its declaration simply failed
364
+ // to parse sends it into a rewrite loop with the same unparseable format.
365
+ const staticOnlyClause = `which only runs static/file checks and would defer the browser work to a human`;
366
+ const modeClause = uatPolicy.modeDeclared
367
+ ? `declares "UAT mode: artifact-driven", ${staticOnlyClause}`
368
+ : `has no parseable UAT mode declaration in its "## UAT Type" section (the declaration must be a bullet exactly like "- UAT mode: browser-executable"), so it defaults to "artifact-driven", ${staticOnlyClause}`;
360
369
  return {
361
- error: `UAT requires browser verification (opening a page in a browser, navigating to a page or localhost, screenshots) but declares "UAT mode: artifact-driven", which only runs static/file checks and would defer the browser work to a human. Use a mode that actually verifies the UI: "browser-executable" (interactive browser tools), "runtime-executable" (a browser test command such as playwright), or a browser-inclusive "mixed"/"live-runtime". Re-author the UAT Type section and complete the slice again.`,
370
+ error: `UAT requires browser verification (opening a page in a browser, navigating to a page or localhost, screenshots) but ${modeClause}. Use a mode that actually verifies the UI: "browser-executable" (interactive browser tools), "runtime-executable" (a browser test command such as playwright), or a browser-inclusive "mixed"/"live-runtime". Re-author the UAT Type section and complete the slice again.`,
362
371
  };
363
372
  }
364
373
 
@@ -470,8 +479,9 @@ export async function handleCompleteSlice(
470
479
 
471
480
  const roadmap = await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
472
481
  clearParseCache();
473
- const roadmapSlice = parseRoadmap(roadmap.content).slices.find((slice) => slice.id === params.sliceId);
474
- if (!roadmapSlice?.done) {
482
+ // Render verification (ADR-017): confirms the just-written projection
483
+ // reflects the DB completion; the DB row is already committed.
484
+ if (!roadmapRenderMarksSliceDone(roadmap.content, params.sliceId)) {
475
485
  throw new Error(`roadmap render did not mark ${params.milestoneId}/${params.sliceId} complete`);
476
486
  }
477
487
  } catch (renderErr) {
@@ -527,7 +537,7 @@ export async function handleCompleteSlice(
527
537
  // Separate try/catch per step so a projection failure doesn't prevent
528
538
  // the event log entry (critical for worktree reconciliation).
529
539
  try {
530
- await renderAllProjections(artifactBasePath, params.milestoneId);
540
+ await flushWorkflowProjections(artifactBasePath, { milestoneId: params.milestoneId });
531
541
  } catch (projErr) {
532
542
  logWarning("tool", `complete-slice projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
533
543
  }
@@ -35,7 +35,8 @@ import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
35
35
  import { saveFile, clearParseCache } from "../files.js";
36
36
  import { invalidateStateCache } from "../state.js";
37
37
  import { renderPlanCheckboxes } from "../markdown-renderer.js";
38
- import { renderAllProjections, renderSummaryContent } from "../workflow-projections.js";
38
+ import { renderSummaryContent } from "../workflow-projections.js";
39
+ import { flushWorkflowProjections } from "../projection-flush.js";
39
40
  import { writeManifest } from "../workflow-manifest.js";
40
41
  import { appendEvent } from "../workflow-events.js";
41
42
  import { logWarning, logError } from "../workflow-logger.js";
@@ -467,7 +468,7 @@ export async function handleCompleteTask(
467
468
  // Separate try/catch per step so a projection failure doesn't prevent
468
469
  // the event log entry (critical for worktree reconciliation).
469
470
  try {
470
- await renderAllProjections(artifactBasePath, params.milestoneId);
471
+ await flushWorkflowProjections(artifactBasePath, { milestoneId: params.milestoneId });
471
472
  } catch (projErr) {
472
473
  logWarning("tool", `complete-task projection warning: ${(projErr as Error).message}`);
473
474
  }
@@ -11,7 +11,7 @@ import {
11
11
  import { realpathSync } from "node:fs";
12
12
  import path from "node:path";
13
13
  import { isContextModeEnabled, type ContextModeConfig } from "../preferences-types.js";
14
- import { findWorktreeSegment } from "../worktree-root.js";
14
+ import { projectRootFromWorktreePath } from "../worktree-root.js";
15
15
  import { contextModeDisabledResult, type ToolExecutionResult } from "./context-mode-tool-result.js";
16
16
 
17
17
  export interface ExecToolParams {
@@ -202,12 +202,9 @@ function normalizeScanPath(value: string): string {
202
202
 
203
203
  function parseWorktreeBase(baseDir: string): { originalRoot: string; worktreeRoot: string } | null {
204
204
  const normalizedBase = normalizeScanPath(baseDir);
205
- const segment = findWorktreeSegment(normalizedBase);
206
- if (!segment || segment.gsdIdx <= 0) return null;
207
- return {
208
- originalRoot: normalizedBase.slice(0, segment.gsdIdx),
209
- worktreeRoot: normalizedBase,
210
- };
205
+ const originalRoot = projectRootFromWorktreePath(normalizedBase);
206
+ if (!originalRoot) return null;
207
+ return { originalRoot, worktreeRoot: normalizedBase };
211
208
  }
212
209
 
213
210
  function pathInside(parent: string, target: string): boolean {
@@ -427,6 +424,7 @@ function formatResult(result: ExecSandboxResult): ToolExecutionResult {
427
424
  exit_code: result.exit_code,
428
425
  signal: result.signal,
429
426
  timed_out: result.timed_out,
427
+ force_resolved: result.force_resolved,
430
428
  duration_ms: result.duration_ms,
431
429
  stdout_bytes: result.stdout_bytes,
432
430
  stderr_bytes: result.stderr_bytes,
@@ -441,6 +439,9 @@ function formatResult(result: ExecSandboxResult): ToolExecutionResult {
441
439
  }
442
440
 
443
441
  function formatExit(result: ExecSandboxResult): string {
442
+ // force_resolved means a non-closing (D-state) child was force-resolved past its
443
+ // hard deadline rather than observed exiting; distinguish it from a clean timeout.
444
+ if (result.force_resolved) return "timeout(force-killed)";
444
445
  if (result.timed_out) return "timeout";
445
446
  if (result.signal) return `signal:${result.signal}`;
446
447
  if (result.exit_code === null) return "null";
@@ -21,13 +21,14 @@ import {
21
21
  import type { GateEvaluationConfig, GateId } from "../types.js";
22
22
  import { invalidateStateCache } from "../state.js";
23
23
  import { renderPlanFromDb } from "../markdown-renderer.js";
24
- import { renderAllProjections } from "../workflow-projections.js";
24
+ import { flushWorkflowProjections } from "../projection-flush.js";
25
25
  import { writeManifest } from "../workflow-manifest.js";
26
26
  import { appendEvent } from "../workflow-events.js";
27
27
  import { logWarning } from "../workflow-logger.js";
28
28
  import { validatePathOnlyPlanningFields, validatePlanningPathScope } from "../planning-path-scope.js";
29
- import { checkFilePathConsistency, checkTaskOrdering } from "../pre-execution-checks.js";
29
+ import { runTaskPathChecks } from "../pre-execution-checks.js";
30
30
  import type { TaskRow } from "../db-task-slice-rows.js";
31
+ import { resolveWorktreeProjectRoot } from "../worktree-root.js";
31
32
  import { buildTaskFileName, gsdProjectionRoot } from "../paths.js";
32
33
  import { loadEffectiveGSDPreferences } from "../preferences.js";
33
34
  import { createRepositoryRegistryFromPreferences, defaultRepositoryTargets, type RepositoryRegistry } from "../repository-registry.js";
@@ -268,11 +269,16 @@ function validateTaskPathsBeforePersist(
268
269
  const additionalRoots = allowedRoots
269
270
  .map((root) => resolve(root))
270
271
  .filter((root) => root !== baseRoot);
271
- const context = additionalRoots.length > 0 ? { additionalRoots } : undefined;
272
- const checks = [
273
- ...checkFilePathConsistency(taskRows, basePath, context),
274
- ...checkTaskOrdering(taskRows, basePath, context),
275
- ];
272
+ const resolvedCanonicalRoot = resolve(resolveWorktreeProjectRoot(basePath));
273
+ const canonicalProjectRoot = resolvedCanonicalRoot !== baseRoot ? resolvedCanonicalRoot : undefined;
274
+ const hasContext = additionalRoots.length > 0 || canonicalProjectRoot !== undefined;
275
+ const context = hasContext
276
+ ? {
277
+ ...(additionalRoots.length > 0 ? { additionalRoots } : {}),
278
+ ...(canonicalProjectRoot !== undefined ? { canonicalProjectRoot } : {}),
279
+ }
280
+ : undefined;
281
+ const checks = runTaskPathChecks(taskRows, basePath, context);
276
282
  const blocking = checks.filter((check) => !check.passed && check.blocking);
277
283
 
278
284
  if (blocking.length === 0) return null;
@@ -462,7 +468,7 @@ export async function handlePlanSlice(
462
468
 
463
469
  // ── Post-mutation hook: projections, manifest, event log ─────────────
464
470
  try {
465
- await renderAllProjections(basePath, params.milestoneId);
471
+ await flushWorkflowProjections(basePath, { milestoneId: params.milestoneId });
466
472
  writeManifest(basePath);
467
473
  appendEvent(basePath, {
468
474
  cmd: "plan-slice",
@@ -4,7 +4,7 @@ import { isNonEmptyString, validateStringArray } from "../validation.js";
4
4
  import { transaction, getSlice, getTask, insertTask, upsertTaskPlanning } from "../gsd-db.js";
5
5
  import { invalidateStateCache } from "../state.js";
6
6
  import { renderTaskPlanFromDb } from "../markdown-renderer.js";
7
- import { renderAllProjections } from "../workflow-projections.js";
7
+ import { flushWorkflowProjections } from "../projection-flush.js";
8
8
  import { writeManifest } from "../workflow-manifest.js";
9
9
  import { appendEvent } from "../workflow-events.js";
10
10
  import { logWarning } from "../workflow-logger.js";
@@ -142,7 +142,7 @@ export async function handlePlanTask(
142
142
 
143
143
  // ── Post-mutation hook: projections, manifest, event log ─────────────
144
144
  try {
145
- await renderAllProjections(basePath, params.milestoneId);
145
+ await flushWorkflowProjections(basePath, { milestoneId: params.milestoneId });
146
146
  writeManifest(basePath);
147
147
  appendEvent(basePath, {
148
148
  cmd: "plan-task",
@@ -16,7 +16,7 @@ import {
16
16
  } from "../gsd-db.js";
17
17
  import { invalidateStateCache } from "../state.js";
18
18
  import { renderRoadmapFromDb, renderAssessmentFromDb } from "../markdown-renderer.js";
19
- import { renderAllProjections } from "../workflow-projections.js";
19
+ import { flushWorkflowProjections } from "../projection-flush.js";
20
20
  import { writeManifest } from "../workflow-manifest.js";
21
21
  import { appendEvent } from "../workflow-events.js";
22
22
  import { logWarning } from "../workflow-logger.js";
@@ -306,7 +306,7 @@ export async function handleReassessRoadmap(
306
306
 
307
307
  // ── Post-mutation hook: projections, manifest, event log ─────
308
308
  try {
309
- await renderAllProjections(basePath, params.milestoneId);
309
+ await flushWorkflowProjections(basePath, { milestoneId: params.milestoneId });
310
310
  writeManifest(basePath);
311
311
  appendEvent(basePath, {
312
312
  cmd: "reassess-roadmap",
@@ -15,7 +15,7 @@ import {
15
15
  reopenMilestoneCascade,
16
16
  } from "../gsd-db.js";
17
17
  import { invalidateStateCache } from "../state.js";
18
- import { renderAllProjections } from "../workflow-projections.js";
18
+ import { flushWorkflowProjections } from "../projection-flush.js";
19
19
  import { writeManifest } from "../workflow-manifest.js";
20
20
  import { appendEvent } from "../workflow-events.js";
21
21
  import { logWarning } from "../workflow-logger.js";
@@ -98,7 +98,7 @@ export async function handleReopenMilestone(
98
98
 
99
99
  // ── Post-mutation hook ───────────────────────────────────────────────────
100
100
  try {
101
- await renderAllProjections(basePath, params.milestoneId);
101
+ await flushWorkflowProjections(basePath, { milestoneId: params.milestoneId });
102
102
  writeManifest(basePath);
103
103
  appendEvent(basePath, {
104
104
  cmd: "reopen-milestone",
@@ -16,7 +16,7 @@ import {
16
16
  reopenSliceCascade,
17
17
  } from "../gsd-db.js";
18
18
  import { invalidateStateCache } from "../state.js";
19
- import { renderAllProjections } from "../workflow-projections.js";
19
+ import { flushWorkflowProjections } from "../projection-flush.js";
20
20
  import { writeManifest } from "../workflow-manifest.js";
21
21
  import { appendEvent } from "../workflow-events.js";
22
22
  import { logWarning } from "../workflow-logger.js";
@@ -97,7 +97,7 @@ export async function handleReopenSlice(
97
97
 
98
98
  // ── Post-mutation hook ───────────────────────────────────────────────────
99
99
  try {
100
- await renderAllProjections(basePath, params.milestoneId);
100
+ await flushWorkflowProjections(basePath, { milestoneId: params.milestoneId });
101
101
  writeManifest(basePath);
102
102
  appendEvent(basePath, {
103
103
  cmd: "reopen-slice",
@@ -19,7 +19,7 @@ import {
19
19
  } from "../gsd-db.js";
20
20
  import { invalidateStateCache } from "../state.js";
21
21
  import { isClosedStatus } from "../status-guards.js";
22
- import { renderAllProjections } from "../workflow-projections.js";
22
+ import { flushWorkflowProjections } from "../projection-flush.js";
23
23
  import { writeManifest } from "../workflow-manifest.js";
24
24
  import { appendEvent } from "../workflow-events.js";
25
25
  import { logWarning } from "../workflow-logger.js";
@@ -119,7 +119,7 @@ export async function handleReopenTask(
119
119
 
120
120
  // ── Post-mutation hook ───────────────────────────────────────────────────
121
121
  try {
122
- await renderAllProjections(basePath, params.milestoneId);
122
+ await flushWorkflowProjections(basePath, { milestoneId: params.milestoneId });
123
123
  writeManifest(basePath);
124
124
  appendEvent(basePath, {
125
125
  cmd: "reopen-task",
@@ -13,7 +13,7 @@ import { invalidateStateCache } from "../state.js";
13
13
  import { isClosedStatus } from "../status-guards.js";
14
14
  import { isNonEmptyString } from "../validation.js";
15
15
  import { renderPlanFromDb, renderReplanFromDb } from "../markdown-renderer.js";
16
- import { renderAllProjections } from "../workflow-projections.js";
16
+ import { flushWorkflowProjections } from "../projection-flush.js";
17
17
  import { writeManifest } from "../workflow-manifest.js";
18
18
  import { appendEvent } from "../workflow-events.js";
19
19
  import { logWarning } from "../workflow-logger.js";
@@ -216,7 +216,7 @@ export async function handleReplanSlice(
216
216
 
217
217
  // ── Post-mutation hook: projections, manifest, event log ─────
218
218
  try {
219
- await renderAllProjections(basePath, params.milestoneId);
219
+ await flushWorkflowProjections(basePath, { milestoneId: params.milestoneId });
220
220
  writeManifest(basePath);
221
221
  appendEvent(basePath, {
222
222
  cmd: "replan-slice",
@@ -19,9 +19,10 @@ import {
19
19
  } from "../gsd-db.js";
20
20
  import { GATE_REGISTRY } from "../gate-registry.js";
21
21
  import { generateRequirementsMd, saveArtifactToDb } from "../db-writer.js";
22
- import { clearPathCache, relSliceFile, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "../paths.js";
22
+ import { clearPathCache, normalizeRealPath, relSliceFile, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "../paths.js";
23
23
  import { saveFile, clearParseCache } from "../files.js";
24
24
  import { unlinkSync } from "node:fs";
25
+ import { hostname } from "node:os";
25
26
  import { join } from "node:path";
26
27
  import type { CompleteMilestoneParams } from "./complete-milestone.js";
27
28
  import { handleCompleteMilestone } from "./complete-milestone.js";
@@ -48,13 +49,21 @@ import { logError, logWarning } from "../workflow-logger.js";
48
49
  import { invalidateStateCache } from "../state.js";
49
50
  import { loadEffectiveGSDPreferences } from "../preferences.js";
50
51
  import { parseProject } from "../schemas/parsers.js";
51
- import { getAutoRuntimeSnapshot } from "../auto-runtime-state.js";
52
+ import { autoSession, getAutoRuntimeSnapshot, isAutoActive } from "../auto-runtime-state.js";
52
53
  import { renderPlanFromDb } from "../markdown-renderer.js";
53
54
  import {
54
55
  prepareUatRun,
55
56
  saveUatAttemptArtifact,
56
57
  type UatResultSaveParams,
57
58
  } from "../uat-run.js";
59
+ import { registerAutoWorker, markWorkerStopping, getAutoWorker } from "../db/auto-workers.js";
60
+ import {
61
+ claimMilestoneLease,
62
+ releaseMilestoneLease,
63
+ getMilestoneLease,
64
+ refreshMilestoneLease,
65
+ milestoneLeaseTtlSeconds,
66
+ } from "../db/milestone-leases.js";
58
67
  export type {
59
68
  UatCheckResultInput,
60
69
  UatEvidenceRef,
@@ -105,6 +114,24 @@ function blockIfWrongAutoUnit(requiredUnitType: string, operation: string): Tool
105
114
  };
106
115
  }
107
116
 
117
+ function milestoneLeaseConflictResult(
118
+ milestoneId: string,
119
+ byWorker: string,
120
+ expiresAt: string,
121
+ ): ToolExecutionResult {
122
+ return {
123
+ content: [{ type: "text", text: `Milestone ${milestoneId} is currently leased by ${byWorker}. Retry after ${expiresAt}.` }],
124
+ details: {
125
+ operation: "plan_milestone",
126
+ error: "milestone_lease_conflict",
127
+ milestoneId,
128
+ byWorker,
129
+ expiresAt,
130
+ },
131
+ isError: true,
132
+ };
133
+ }
134
+
108
135
  export interface SummarySaveParams {
109
136
  milestone_id?: string;
110
137
  slice_id?: string;
@@ -1244,7 +1271,48 @@ export async function executePlanMilestone(
1244
1271
  isError: true,
1245
1272
  };
1246
1273
  }
1274
+ let workerId: string | null = null;
1275
+ let acquiredToken: number | null = null;
1276
+ let leaseRefreshTimer: ReturnType<typeof setInterval> | undefined;
1247
1277
  try {
1278
+ // Re-read at the gate so a peer-created milestone is not treated as fresh.
1279
+ const milestoneExists = getMilestone(params.milestoneId) !== null;
1280
+ if (milestoneExists) {
1281
+ const heldLease = getMilestoneLease(params.milestoneId);
1282
+ if (heldLease?.status === "held" && Date.parse(heldLease.expires_at) > Date.now()) {
1283
+ const holder = getAutoWorker(heldLease.worker_id);
1284
+ // Let the one-shot claim path recover stale same-process worker rows.
1285
+ const projectRoot = normalizeRealPath(basePath);
1286
+ const isOurAutoLease = isAutoActive() && heldLease.worker_id === autoSession.workerId;
1287
+ const holderIsOneShotReentrantPeer = !isAutoActive()
1288
+ && !!holder
1289
+ && holder.host === hostname()
1290
+ && holder.pid === process.pid
1291
+ && holder.project_root_realpath === projectRoot;
1292
+ if (holder?.status === "active" && !isOurAutoLease && !holderIsOneShotReentrantPeer) {
1293
+ return milestoneLeaseConflictResult(params.milestoneId, heldLease.worker_id, heldLease.expires_at);
1294
+ }
1295
+ }
1296
+ }
1297
+
1298
+ // Fresh creation cannot claim a lease because the FK row does not exist.
1299
+ // In-process auto already owns its lease; re-claiming would bump its token.
1300
+ if (!isAutoActive() && milestoneExists) {
1301
+ workerId = registerAutoWorker({ projectRootRealpath: normalizeRealPath(basePath) });
1302
+ const lease = claimMilestoneLease(workerId, params.milestoneId);
1303
+ if (!lease.ok) {
1304
+ return milestoneLeaseConflictResult(params.milestoneId, lease.byWorker, lease.expiresAt);
1305
+ }
1306
+ acquiredToken = lease.token;
1307
+
1308
+ const leaseRefreshMs = (milestoneLeaseTtlSeconds() / 2) * 1000;
1309
+ leaseRefreshTimer = setInterval(() => {
1310
+ if (acquiredToken !== null && workerId !== null) {
1311
+ refreshMilestoneLease(workerId, params.milestoneId, acquiredToken);
1312
+ }
1313
+ }, leaseRefreshMs);
1314
+ }
1315
+
1248
1316
  const result = await handlePlanMilestone(params, basePath);
1249
1317
  if ("error" in result) {
1250
1318
  return {
@@ -1270,6 +1338,17 @@ export async function executePlanMilestone(
1270
1338
  isError: true,
1271
1339
  };
1272
1340
  }
1341
+ finally {
1342
+ if (leaseRefreshTimer !== undefined) {
1343
+ clearInterval(leaseRefreshTimer);
1344
+ }
1345
+ if (workerId !== null && acquiredToken !== null) {
1346
+ releaseMilestoneLease(workerId, params.milestoneId, acquiredToken);
1347
+ }
1348
+ if (workerId !== null) {
1349
+ markWorkerStopping(workerId);
1350
+ }
1351
+ }
1273
1352
  }
1274
1353
 
1275
1354
  export async function executePlanSlice(
@@ -1,7 +1,8 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Central UAT mode policy for dispatch, tool presentation, and result validation.
3
3
 
4
- import { extractUatType } from "./files.js";
4
+ import { hasBrowserContractPrefix } from "../shared/browser-contract.js";
5
+ import { extractUatType, UAT_TYPE_KEYWORDS } from "./files.js";
5
6
  import type { UatType } from "./files.js";
6
7
  import { hasBrowserRequiredText } from "./browser-evidence.js";
7
8
  import { parseMcpToolName } from "./mcp-tool-name.js";
@@ -27,19 +28,14 @@ export interface UatModePolicy {
27
28
 
28
29
  export interface UatContentPolicy {
29
30
  declaredType: UatType;
31
+ /** False when no parseable `UAT mode:` declaration exists and declaredType defaulted to artifact-driven. */
32
+ modeDeclared: boolean;
30
33
  effectiveType: UatType;
31
34
  browserRequired: boolean;
32
35
  shouldDispatchByDefault: boolean;
33
36
  }
34
37
 
35
- export const UAT_TYPES: readonly UatType[] = [
36
- "artifact-driven",
37
- "browser-executable",
38
- "runtime-executable",
39
- "live-runtime",
40
- "mixed",
41
- "human-experience",
42
- ] as const;
38
+ export const UAT_TYPES: readonly UatType[] = UAT_TYPE_KEYWORDS;
43
39
 
44
40
  export const UAT_MODE_POLICIES: Readonly<Record<UatType, UatModePolicy>> = {
45
41
  "artifact-driven": {
@@ -88,26 +84,76 @@ export function getDeclaredUatType(content: string): UatType {
88
84
  return extractUatType(content) ?? "artifact-driven";
89
85
  }
90
86
 
91
- export function classifyUatContent(content: string): UatContentPolicy {
92
- const declaredType = getDeclaredUatType(content);
93
- const browserRequired = hasBrowserRequiredText(content);
94
- const effectiveType = declaredType === "artifact-driven" && browserRequired
87
+ /** Self-contained browser UAT harnesses that manage server lifecycle internally. */
88
+ const SELF_CONTAINED_RUNTIME_UAT_COMMAND_RE =
89
+ /\b(?:npm run test:uat|node\s+(?:--check\s+\S+\s+&&\s+)*tests\/browser\/search-uat\.mjs|npx playwright test(?:\s+\S+)?)\b/i;
90
+
91
+ export function hasSelfContainedRuntimeUatCommand(content: string): boolean {
92
+ return SELF_CONTAINED_RUNTIME_UAT_COMMAND_RE.test(content);
93
+ }
94
+
95
+ function resolveEffectiveUatTypeFromPolicy(
96
+ declaredType: UatType,
97
+ browserRequired: boolean,
98
+ content: string,
99
+ ): UatType {
100
+ let effectiveType = declaredType === "artifact-driven" && browserRequired
95
101
  ? "browser-executable"
96
102
  : declaredType;
97
103
 
104
+ // M006/S01 regression: specs often declare browser-executable with localhost
105
+ // preconditions while the Evidence section names a runtime harness such as
106
+ // `npm run test:uat`. Interactive browser_* checks then race a fixed port
107
+ // against the script's own ephemeral server — run the harness instead.
108
+ if (
109
+ effectiveType === "browser-executable" &&
110
+ hasSelfContainedRuntimeUatCommand(content)
111
+ ) {
112
+ effectiveType = "runtime-executable";
113
+ }
114
+
115
+ return effectiveType;
116
+ }
117
+
118
+ export function classifyUatContent(content: string): UatContentPolicy {
119
+ return classifyUatContentForRun(content);
120
+ }
121
+
122
+ /**
123
+ * Classify UAT mode for run-uat dispatch. Supplemental context (slice summary,
124
+ * verification excerpts) can name a self-contained harness even when the UAT
125
+ * file only documents a separate server command such as `npm run test:server`.
126
+ */
127
+ export function classifyUatContentForRun(content: string, supplementalContext = ""): UatContentPolicy {
128
+ const parsedType = extractUatType(content);
129
+ const declaredType = parsedType ?? "artifact-driven";
130
+ const browserRequired = hasBrowserRequiredText(content);
131
+ const combinedForHarness = supplementalContext.trim()
132
+ ? `${content}\n\n${supplementalContext}`
133
+ : content;
134
+ const effectiveType = resolveEffectiveUatTypeFromPolicy(
135
+ declaredType,
136
+ browserRequired,
137
+ combinedForHarness,
138
+ );
139
+
98
140
  return {
99
141
  declaredType,
142
+ modeDeclared: parsedType !== undefined,
100
143
  effectiveType,
101
144
  browserRequired,
102
145
  shouldDispatchByDefault: effectiveType !== "artifact-driven" || browserRequired,
103
146
  };
104
147
  }
105
148
 
106
- export function shouldEscalateArtifactUatToBrowser(content: string): boolean {
107
- const policy = classifyUatContent(content);
149
+ export function escalatesArtifactUatToBrowser(policy: UatContentPolicy): boolean {
108
150
  return policy.declaredType === "artifact-driven" && policy.browserRequired;
109
151
  }
110
152
 
153
+ export function shouldEscalateArtifactUatToBrowser(content: string): boolean {
154
+ return escalatesArtifactUatToBrowser(classifyUatContent(content));
155
+ }
156
+
111
157
  export function resolveEffectiveUatType(content: string): UatType {
112
158
  return classifyUatContent(content).effectiveType;
113
159
  }
@@ -126,7 +172,7 @@ export function uatTypeIncludesBrowser(uatType: string | undefined): boolean {
126
172
  export function isUatBrowserToolName(toolName: string): boolean {
127
173
  const parsed = parseMcpToolName(toolName);
128
174
  const canonicalName = parsed?.toolName ?? toolName;
129
- if (canonicalName.startsWith("browser_")) return true;
175
+ if (hasBrowserContractPrefix(canonicalName)) return true;
130
176
  return parsed?.toolName === "*" && parsed.serverName.toLowerCase().includes("browser");
131
177
  }
132
178