@opengsd/gsd-pi 1.8.1 → 1.9.0-dev.97ef11e3

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 (613) hide show
  1. package/README.md +10 -8
  2. package/dist/cli.js +5 -1
  3. package/dist/headless-events.d.ts +2 -1
  4. package/dist/headless-events.js +11 -3
  5. package/dist/headless-milestone-readiness.d.ts +29 -0
  6. package/dist/headless-milestone-readiness.js +161 -0
  7. package/dist/headless.js +27 -3
  8. package/dist/print-mode-exit.d.ts +12 -0
  9. package/dist/print-mode-exit.js +14 -0
  10. package/dist/resources/.managed-resources-content-hash +1 -1
  11. package/dist/resources/GSD-WORKFLOW.md +18 -49
  12. package/dist/resources/extensions/browser-tools/capture.js +2 -77
  13. package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
  14. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
  15. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
  16. package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
  17. package/dist/resources/extensions/gsd/auto/loop.js +24 -4
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +19 -1
  19. package/dist/resources/extensions/gsd/auto/unit-phase.js +37 -5
  20. package/dist/resources/extensions/gsd/auto-artifact-paths.js +16 -10
  21. package/dist/resources/extensions/gsd/auto-dispatch.js +76 -19
  22. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
  23. package/dist/resources/extensions/gsd/auto-prompts.js +137 -22
  24. package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
  25. package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -5
  26. package/dist/resources/extensions/gsd/auto-start.js +29 -9
  27. package/dist/resources/extensions/gsd/auto-tool-tracking.js +40 -0
  28. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-sync.js +7 -3
  30. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
  31. package/dist/resources/extensions/gsd/auto.js +20 -6
  32. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -4
  33. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -7
  34. package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
  35. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +88 -50
  36. package/dist/resources/extensions/gsd/command-feedback.js +16 -12
  37. package/dist/resources/extensions/gsd/commands-verdict.js +10 -9
  38. package/dist/resources/extensions/gsd/compat/compat-marker.js +98 -6
  39. package/dist/resources/extensions/gsd/constants.js +12 -13
  40. package/dist/resources/extensions/gsd/context-masker.js +97 -21
  41. package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
  42. package/dist/resources/extensions/gsd/db/engine.js +56 -18
  43. package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
  44. package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
  45. package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
  46. package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
  47. package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
  48. package/dist/resources/extensions/gsd/docs/preferences-reference.md +26 -4
  49. package/dist/resources/extensions/gsd/doctor-engine-checks.js +24 -8
  50. package/dist/resources/extensions/gsd/error-classifier.js +12 -2
  51. package/dist/resources/extensions/gsd/exec-sandbox.js +1 -0
  52. package/dist/resources/extensions/gsd/flat-phase-migration.js +168 -21
  53. package/dist/resources/extensions/gsd/git-service.js +19 -7
  54. package/dist/resources/extensions/gsd/gsd-db.js +262 -76
  55. package/dist/resources/extensions/gsd/guided-flow.js +40 -15
  56. package/dist/resources/extensions/gsd/markdown-renderer.js +20 -22
  57. package/dist/resources/extensions/gsd/md-importer.js +107 -20
  58. package/dist/resources/extensions/gsd/migrate/command.js +19 -162
  59. package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
  60. package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
  61. package/dist/resources/extensions/gsd/migrate/planning-writer.js +12 -17
  62. package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
  63. package/dist/resources/extensions/gsd/model-cost-table.js +2 -0
  64. package/dist/resources/extensions/gsd/model-router.js +11 -0
  65. package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
  66. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
  67. package/dist/resources/extensions/gsd/paths.js +70 -16
  68. package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
  69. package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
  70. package/dist/resources/extensions/gsd/planning-subagent-registry.js +25 -0
  71. package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
  72. package/dist/resources/extensions/gsd/preferences-types.js +5 -0
  73. package/dist/resources/extensions/gsd/preferences-validation.js +48 -1
  74. package/dist/resources/extensions/gsd/preferences.js +17 -0
  75. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  76. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
  77. package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
  78. package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
  79. package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
  80. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
  81. package/dist/resources/extensions/gsd/skill-activation.js +17 -3
  82. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +125 -15
  83. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +17 -4
  84. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +5 -2
  85. package/dist/resources/extensions/gsd/stop-notice.js +24 -1
  86. package/dist/resources/extensions/gsd/sync-lock.js +13 -7
  87. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
  88. package/dist/resources/extensions/gsd/tools/complete-task.js +94 -6
  89. package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
  90. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
  91. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
  92. package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
  93. package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
  94. package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
  95. package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
  96. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
  97. package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
  98. package/dist/resources/extensions/gsd/unit-registry.js +4 -0
  99. package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
  100. package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
  101. package/dist/resources/extensions/gsd/workspace.js +2 -1
  102. package/dist/resources/extensions/gsd/worktree-state-projection.js +26 -18
  103. package/dist/resources/extensions/mac-tools/index.js +31 -9
  104. package/dist/resources/extensions/shared/interview-ui.js +43 -6
  105. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  106. package/dist/web/standalone/.next/BUILD_ID +1 -1
  107. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  108. package/dist/web/standalone/.next/build-manifest.json +3 -3
  109. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  110. package/dist/web/standalone/.next/required-server-files.json +3 -3
  111. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  112. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  122. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  131. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  150. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  172. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  188. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  204. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  208. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/index.html +1 -1
  218. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  219. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  220. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  221. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  222. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  223. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  224. package/dist/web/standalone/.next/server/app/page.js +2 -2
  225. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  227. package/dist/web/standalone/.next/server/chunks/1991.js +2 -2
  228. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  229. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  230. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  231. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/middleware.js +3 -3
  233. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  234. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  235. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  236. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  237. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  238. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  239. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  240. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  241. package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
  242. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  243. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  244. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  245. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  246. package/dist/web/standalone/package.json +0 -1
  247. package/dist/web/standalone/server.js +1 -1
  248. package/dist/web-mode.js +31 -3
  249. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  250. package/integrations/hermes/pyproject.toml +1 -1
  251. package/package.json +13 -10
  252. package/packages/cloud-mcp-gateway/package.json +2 -2
  253. package/packages/contracts/dist/workflow.d.ts +14 -0
  254. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  255. package/packages/contracts/dist/workflow.js +16 -0
  256. package/packages/contracts/dist/workflow.js.map +1 -1
  257. package/packages/contracts/package.json +1 -1
  258. package/packages/daemon/dist/cloud-config.d.ts +1 -1
  259. package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
  260. package/packages/daemon/dist/cloud-config.js +5 -1
  261. package/packages/daemon/dist/cloud-config.js.map +1 -1
  262. package/packages/daemon/dist/cloud-config.test.js +51 -1
  263. package/packages/daemon/dist/cloud-config.test.js.map +1 -1
  264. package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
  265. package/packages/daemon/dist/local-tool-executor.js +2 -0
  266. package/packages/daemon/dist/local-tool-executor.js.map +1 -1
  267. package/packages/daemon/package.json +6 -6
  268. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  269. package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
  270. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  271. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  272. package/packages/gsd-agent-core/dist/sdk.js +1 -0
  273. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  274. package/packages/gsd-agent-core/package.json +5 -5
  275. package/packages/gsd-agent-modes/package.json +7 -7
  276. package/packages/gsd-cloud/README.md +9 -3
  277. package/packages/gsd-cloud/dist/background-cli.test.d.ts +2 -0
  278. package/packages/gsd-cloud/dist/background-cli.test.d.ts.map +1 -0
  279. package/packages/gsd-cloud/dist/background-cli.test.js +248 -0
  280. package/packages/gsd-cloud/dist/background-cli.test.js.map +1 -0
  281. package/packages/gsd-cloud/dist/cli.d.ts +5 -0
  282. package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
  283. package/packages/gsd-cloud/dist/cli.js +266 -0
  284. package/packages/gsd-cloud/dist/cli.js.map +1 -0
  285. package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
  286. package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
  287. package/packages/gsd-cloud/dist/cloud-config.js +237 -0
  288. package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
  289. package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
  290. package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
  291. package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
  292. package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
  293. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
  294. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
  295. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
  296. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
  297. package/packages/gsd-cloud/dist/cloud-runtime.d.ts +33 -0
  298. package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
  299. package/packages/gsd-cloud/dist/cloud-runtime.js +260 -0
  300. package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
  301. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
  302. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
  303. package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
  304. package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
  305. package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
  306. package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
  307. package/packages/gsd-cloud/dist/cloud-token.js +37 -0
  308. package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
  309. package/packages/gsd-cloud/dist/config.d.ts +17 -0
  310. package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
  311. package/packages/gsd-cloud/dist/config.js +146 -0
  312. package/packages/gsd-cloud/dist/config.js.map +1 -0
  313. package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
  314. package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
  315. package/packages/gsd-cloud/dist/device-flow.js +128 -0
  316. package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
  317. package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
  318. package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
  319. package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
  320. package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
  321. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
  322. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
  323. package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
  324. package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
  325. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
  326. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
  327. package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
  328. package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
  329. package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
  330. package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
  331. package/packages/gsd-cloud/dist/executors/executor.js +11 -0
  332. package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
  333. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
  334. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
  335. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
  336. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
  337. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
  338. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
  339. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
  340. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
  341. package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
  342. package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
  343. package/packages/gsd-cloud/dist/executors/index.js +29 -0
  344. package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
  345. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
  346. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
  347. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
  348. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
  349. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
  350. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
  351. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
  352. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
  353. package/packages/gsd-cloud/dist/index.d.ts +7 -0
  354. package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
  355. package/packages/gsd-cloud/dist/index.js +8 -0
  356. package/packages/gsd-cloud/dist/index.js.map +1 -0
  357. package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
  358. package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
  359. package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
  360. package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
  361. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
  362. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
  363. package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
  364. package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
  365. package/packages/gsd-cloud/dist/logger.d.ts +25 -0
  366. package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
  367. package/packages/gsd-cloud/dist/logger.js +72 -0
  368. package/packages/gsd-cloud/dist/logger.js.map +1 -0
  369. package/packages/gsd-cloud/dist/runtime-process.d.ts +27 -0
  370. package/packages/gsd-cloud/dist/runtime-process.d.ts.map +1 -0
  371. package/packages/gsd-cloud/dist/runtime-process.js +272 -0
  372. package/packages/gsd-cloud/dist/runtime-process.js.map +1 -0
  373. package/packages/gsd-cloud/dist/runtime-process.test.d.ts +2 -0
  374. package/packages/gsd-cloud/dist/runtime-process.test.d.ts.map +1 -0
  375. package/packages/gsd-cloud/dist/runtime-process.test.js +97 -0
  376. package/packages/gsd-cloud/dist/runtime-process.test.js.map +1 -0
  377. package/packages/gsd-cloud/dist/types.d.ts +51 -0
  378. package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
  379. package/packages/gsd-cloud/dist/types.js +9 -0
  380. package/packages/gsd-cloud/dist/types.js.map +1 -0
  381. package/packages/gsd-cloud/package.json +3 -3
  382. package/packages/mcp-server/README.md +15 -2
  383. package/packages/mcp-server/dist/cli-runner.d.ts +3 -0
  384. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
  385. package/packages/mcp-server/dist/cli-runner.js +119 -33
  386. package/packages/mcp-server/dist/cli-runner.js.map +1 -1
  387. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  388. package/packages/mcp-server/dist/server.js +5 -5
  389. package/packages/mcp-server/dist/server.js.map +1 -1
  390. package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
  391. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  392. package/packages/mcp-server/dist/workflow-tools.js +64 -2
  393. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  394. package/packages/mcp-server/package.json +4 -4
  395. package/packages/native/package.json +1 -1
  396. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  397. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  398. package/packages/pi-agent-core/dist/agent.js +2 -0
  399. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  400. package/packages/pi-agent-core/package.json +1 -1
  401. package/packages/pi-ai/dist/models.generated.d.ts +136 -0
  402. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  403. package/packages/pi-ai/dist/models.generated.js +124 -0
  404. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  405. package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
  406. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  407. package/packages/pi-ai/dist/providers/anthropic.js +25 -1
  408. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  409. package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
  410. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  411. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  412. package/packages/pi-ai/dist/providers/openai-completions.js +103 -0
  413. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  414. package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
  415. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  416. package/packages/pi-ai/package.json +1 -1
  417. package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
  418. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  419. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -1
  420. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  421. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +11 -1
  422. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  423. package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
  424. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  425. package/packages/pi-coding-agent/package.json +7 -7
  426. package/packages/pi-tui/package.json +2 -2
  427. package/packages/rpc-client/package.json +2 -2
  428. package/pkg/package.json +1 -1
  429. package/src/resources/GSD-WORKFLOW.md +18 -49
  430. package/src/resources/extensions/browser-tools/capture.ts +2 -86
  431. package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
  432. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
  433. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
  434. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
  435. package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
  436. package/src/resources/extensions/gsd/auto/loop.ts +48 -4
  437. package/src/resources/extensions/gsd/auto/run-unit.ts +20 -1
  438. package/src/resources/extensions/gsd/auto/unit-phase.ts +41 -5
  439. package/src/resources/extensions/gsd/auto-artifact-paths.ts +16 -9
  440. package/src/resources/extensions/gsd/auto-dispatch.ts +87 -19
  441. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
  442. package/src/resources/extensions/gsd/auto-prompts.ts +156 -20
  443. package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
  444. package/src/resources/extensions/gsd/auto-runtime-state.ts +12 -7
  445. package/src/resources/extensions/gsd/auto-start.ts +31 -8
  446. package/src/resources/extensions/gsd/auto-tool-tracking.ts +56 -0
  447. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
  448. package/src/resources/extensions/gsd/auto-worktree-sync.ts +10 -3
  449. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
  450. package/src/resources/extensions/gsd/auto.ts +25 -8
  451. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +92 -4
  452. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -12
  453. package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
  454. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +87 -53
  455. package/src/resources/extensions/gsd/command-feedback.ts +19 -12
  456. package/src/resources/extensions/gsd/commands-verdict.ts +16 -9
  457. package/src/resources/extensions/gsd/compat/compat-marker.ts +119 -8
  458. package/src/resources/extensions/gsd/constants.ts +14 -13
  459. package/src/resources/extensions/gsd/context-masker.ts +98 -2
  460. package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
  461. package/src/resources/extensions/gsd/db/engine.ts +58 -19
  462. package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
  463. package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
  464. package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
  465. package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
  466. package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
  467. package/src/resources/extensions/gsd/docs/preferences-reference.md +26 -4
  468. package/src/resources/extensions/gsd/doctor-engine-checks.ts +30 -7
  469. package/src/resources/extensions/gsd/error-classifier.ts +13 -2
  470. package/src/resources/extensions/gsd/exec-sandbox.ts +1 -0
  471. package/src/resources/extensions/gsd/flat-phase-migration.ts +174 -19
  472. package/src/resources/extensions/gsd/git-service.ts +19 -6
  473. package/src/resources/extensions/gsd/gsd-db.ts +340 -85
  474. package/src/resources/extensions/gsd/guided-flow.ts +50 -14
  475. package/src/resources/extensions/gsd/markdown-renderer.ts +28 -30
  476. package/src/resources/extensions/gsd/md-importer.ts +114 -16
  477. package/src/resources/extensions/gsd/migrate/command.ts +21 -227
  478. package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
  479. package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
  480. package/src/resources/extensions/gsd/migrate/planning-writer.ts +12 -20
  481. package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
  482. package/src/resources/extensions/gsd/model-cost-table.ts +2 -0
  483. package/src/resources/extensions/gsd/model-router.ts +12 -0
  484. package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
  485. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
  486. package/src/resources/extensions/gsd/paths.ts +77 -16
  487. package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
  488. package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
  489. package/src/resources/extensions/gsd/planning-subagent-registry.ts +31 -0
  490. package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
  491. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  492. package/src/resources/extensions/gsd/preferences-validation.ts +62 -0
  493. package/src/resources/extensions/gsd/preferences.ts +25 -0
  494. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  495. package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
  496. package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
  497. package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
  498. package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
  499. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
  500. package/src/resources/extensions/gsd/skill-activation.ts +17 -3
  501. package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +162 -15
  502. package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +20 -4
  503. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +4 -2
  504. package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
  505. package/src/resources/extensions/gsd/stop-notice.ts +29 -1
  506. package/src/resources/extensions/gsd/sync-lock.ts +14 -6
  507. package/src/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
  508. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
  509. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +264 -0
  510. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
  511. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +21 -1
  512. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +74 -1
  513. package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
  514. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
  515. package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
  516. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +10 -0
  517. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +129 -0
  518. package/src/resources/extensions/gsd/tests/complete-task.test.ts +362 -1
  519. package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
  520. package/src/resources/extensions/gsd/tests/db-engine-cjs-compat.test.ts +12 -0
  521. package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
  522. package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
  523. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
  524. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
  525. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
  526. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
  527. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
  528. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
  529. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +83 -0
  530. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
  531. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
  532. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +33 -1
  533. package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
  534. package/src/resources/extensions/gsd/tests/external-markdown-edit.test.ts +38 -1
  535. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +201 -0
  536. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +20 -1
  537. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
  538. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +57 -0
  539. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +22 -0
  540. package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
  541. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +13 -0
  542. package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
  543. package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
  544. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
  545. package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
  546. package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
  547. package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
  548. package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
  549. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  550. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  551. package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
  552. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
  553. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
  554. package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
  555. package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
  556. package/src/resources/extensions/gsd/tests/planning-writer.test.ts +29 -0
  557. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
  558. package/src/resources/extensions/gsd/tests/preferences.test.ts +84 -0
  559. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +4 -0
  560. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +87 -0
  561. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +121 -1
  562. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
  563. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
  564. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +105 -0
  565. package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
  566. package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
  567. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  568. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
  569. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
  570. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
  571. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +52 -0
  572. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +38 -1
  573. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
  574. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
  575. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +14 -0
  576. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  577. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
  578. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +73 -0
  579. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
  580. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +7 -0
  581. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
  582. package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
  583. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
  584. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
  585. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +60 -0
  586. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +34 -0
  587. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
  588. package/src/resources/extensions/gsd/tools/complete-task.ts +140 -5
  589. package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
  590. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
  591. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
  592. package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
  593. package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
  594. package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
  595. package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
  596. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
  597. package/src/resources/extensions/gsd/types.ts +11 -0
  598. package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
  599. package/src/resources/extensions/gsd/unit-registry.ts +4 -0
  600. package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
  601. package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
  602. package/src/resources/extensions/gsd/workspace.ts +2 -1
  603. package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -24
  604. package/src/resources/extensions/mac-tools/index.ts +52 -9
  605. package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
  606. package/src/resources/extensions/shared/interview-ui.ts +47 -8
  607. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +29 -0
  608. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  609. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  610. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  611. package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
  612. /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → DXD9fZPnqtjZSlT5xdC3v}/_buildManifest.js +0 -0
  613. /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → DXD9fZPnqtjZSlT5xdC3v}/_ssgManifest.js +0 -0
@@ -19,7 +19,8 @@ import { createHash } from "node:crypto";
19
19
  import { GSDError, GSD_STALE_STATE } from "./errors.js";
20
20
  import { getGateIdsForTurn } from "./gate-registry.js";
21
21
  import { logWarning } from "./workflow-logger.js";
22
- import { isClosedStatus } from "./status-guards.js";
22
+ import { rowToArtifact } from "./db-milestone-artifact-rows.js";
23
+ import { isClosedStatus, toStatus } from "./status-guards.js";
23
24
  // Connection ownership, lifecycle, schema/migrations and transaction
24
25
  // primitives now live in the engine; re-export the full public surface so
25
26
  // existing `from "./gsd-db.js"` imports keep working.
@@ -37,6 +38,7 @@ export * from "./db/queries.js";
37
38
  export * from "./db/writers/cascades.js";
38
39
  import { TERMINAL_STATUS_SQL } from "./db/sql-constants.js";
39
40
  import { applyStatusTransition } from "./db/writers/status.js";
41
+ import { LAYOUT_SEGMENTS, derivePhaseSlug, milestoneIdToPhaseNum, milestoneIdUniqueSuffix, phaseDirName, } from "./layout-policy.js";
40
42
  export function insertDecision(d) {
41
43
  if (!getDbOrNull())
42
44
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
@@ -168,6 +170,44 @@ export function insertArtifact(a) {
168
170
  ":content_hash": contentHash,
169
171
  });
170
172
  }
173
+ function canonicalPhaseDirNameForDb(milestoneId, title) {
174
+ const phaseNum = milestoneIdToPhaseNum(milestoneId);
175
+ const slug = derivePhaseSlug(title || milestoneId);
176
+ const suffix = milestoneIdUniqueSuffix(milestoneId);
177
+ return phaseDirName(phaseNum, suffix ? `${suffix}-${slug}` : slug);
178
+ }
179
+ function reconcileMilestonePhaseArtifactPaths(milestoneId, title) {
180
+ const db = getDbOrNull();
181
+ const phaseNumPrefix = String(milestoneIdToPhaseNum(milestoneId)).padStart(2, "0");
182
+ const canonicalDir = canonicalPhaseDirNameForDb(milestoneId, title);
183
+ const staleRows = db.prepare(`SELECT path
184
+ FROM artifacts
185
+ WHERE milestone_id = :milestone_id
186
+ AND path LIKE :phase_prefix`).all({
187
+ ":milestone_id": milestoneId,
188
+ ":phase_prefix": `${LAYOUT_SEGMENTS.level1}/${phaseNumPrefix}-%/%`,
189
+ });
190
+ const updatePath = db.prepare("UPDATE artifacts SET path = :new_path WHERE path = :old_path");
191
+ const deletePath = db.prepare("DELETE FROM artifacts WHERE path = :path");
192
+ const existingPath = db.prepare("SELECT 1 AS present FROM artifacts WHERE path = :path");
193
+ for (const row of staleRows) {
194
+ const parts = row.path.split("/");
195
+ if (parts.length < 3)
196
+ continue;
197
+ if (parts[0] !== LAYOUT_SEGMENTS.level1)
198
+ continue;
199
+ if (parts[1] === canonicalDir)
200
+ continue;
201
+ if (!parts[1]?.startsWith(`${phaseNumPrefix}-`))
202
+ continue;
203
+ const newPath = [LAYOUT_SEGMENTS.level1, canonicalDir, ...parts.slice(2)].join("/");
204
+ if (existingPath.get({ ":path": newPath })) {
205
+ deletePath.run({ ":path": row.path });
206
+ continue;
207
+ }
208
+ updatePath.run({ ":new_path": newPath, ":old_path": row.path });
209
+ }
210
+ }
171
211
  export function insertMilestone(m) {
172
212
  if (!getDbOrNull())
173
213
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
@@ -206,37 +246,42 @@ export function insertMilestone(m) {
206
246
  export function upsertMilestonePlanning(milestoneId, planning) {
207
247
  if (!getDbOrNull())
208
248
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
209
- getDbOrNull().prepare(`UPDATE milestones SET
210
- title = COALESCE(NULLIF(:title, ''), title),
211
- status = COALESCE(NULLIF(:status, ''), status),
212
- depends_on = COALESCE(:depends_on, depends_on),
213
- vision = COALESCE(:vision, vision),
214
- success_criteria = COALESCE(:success_criteria, success_criteria),
215
- key_risks = COALESCE(:key_risks, key_risks),
216
- proof_strategy = COALESCE(:proof_strategy, proof_strategy),
217
- verification_contract = COALESCE(:verification_contract, verification_contract),
218
- verification_integration = COALESCE(:verification_integration, verification_integration),
219
- verification_operational = COALESCE(:verification_operational, verification_operational),
220
- verification_uat = COALESCE(:verification_uat, verification_uat),
221
- definition_of_done = COALESCE(:definition_of_done, definition_of_done),
222
- requirement_coverage = COALESCE(:requirement_coverage, requirement_coverage),
223
- boundary_map_markdown = COALESCE(:boundary_map_markdown, boundary_map_markdown)
224
- WHERE id = :id`).run({
225
- ":id": milestoneId,
226
- ":title": planning.title ?? "",
227
- ":status": planning.status ?? "",
228
- ":depends_on": planning.depends_on ? JSON.stringify(planning.depends_on) : null,
229
- ":vision": planning.vision ?? null,
230
- ":success_criteria": planning.successCriteria ? JSON.stringify(planning.successCriteria) : null,
231
- ":key_risks": planning.keyRisks ? JSON.stringify(planning.keyRisks) : null,
232
- ":proof_strategy": planning.proofStrategy ? JSON.stringify(planning.proofStrategy) : null,
233
- ":verification_contract": planning.verificationContract ?? null,
234
- ":verification_integration": planning.verificationIntegration ?? null,
235
- ":verification_operational": planning.verificationOperational ?? null,
236
- ":verification_uat": planning.verificationUat ?? null,
237
- ":definition_of_done": planning.definitionOfDone ? JSON.stringify(planning.definitionOfDone) : null,
238
- ":requirement_coverage": planning.requirementCoverage ?? null,
239
- ":boundary_map_markdown": planning.boundaryMapMarkdown ?? null,
249
+ transaction(() => {
250
+ getDbOrNull().prepare(`UPDATE milestones SET
251
+ title = COALESCE(NULLIF(:title, ''), title),
252
+ status = COALESCE(NULLIF(:status, ''), status),
253
+ depends_on = COALESCE(:depends_on, depends_on),
254
+ vision = COALESCE(:vision, vision),
255
+ success_criteria = COALESCE(:success_criteria, success_criteria),
256
+ key_risks = COALESCE(:key_risks, key_risks),
257
+ proof_strategy = COALESCE(:proof_strategy, proof_strategy),
258
+ verification_contract = COALESCE(:verification_contract, verification_contract),
259
+ verification_integration = COALESCE(:verification_integration, verification_integration),
260
+ verification_operational = COALESCE(:verification_operational, verification_operational),
261
+ verification_uat = COALESCE(:verification_uat, verification_uat),
262
+ definition_of_done = COALESCE(:definition_of_done, definition_of_done),
263
+ requirement_coverage = COALESCE(:requirement_coverage, requirement_coverage),
264
+ boundary_map_markdown = COALESCE(:boundary_map_markdown, boundary_map_markdown)
265
+ WHERE id = :id`).run({
266
+ ":id": milestoneId,
267
+ ":title": planning.title ?? "",
268
+ ":status": planning.status ?? "",
269
+ ":depends_on": planning.depends_on ? JSON.stringify(planning.depends_on) : null,
270
+ ":vision": planning.vision ?? null,
271
+ ":success_criteria": planning.successCriteria ? JSON.stringify(planning.successCriteria) : null,
272
+ ":key_risks": planning.keyRisks ? JSON.stringify(planning.keyRisks) : null,
273
+ ":proof_strategy": planning.proofStrategy ? JSON.stringify(planning.proofStrategy) : null,
274
+ ":verification_contract": planning.verificationContract ?? null,
275
+ ":verification_integration": planning.verificationIntegration ?? null,
276
+ ":verification_operational": planning.verificationOperational ?? null,
277
+ ":verification_uat": planning.verificationUat ?? null,
278
+ ":definition_of_done": planning.definitionOfDone ? JSON.stringify(planning.definitionOfDone) : null,
279
+ ":requirement_coverage": planning.requirementCoverage ?? null,
280
+ ":boundary_map_markdown": planning.boundaryMapMarkdown ?? null,
281
+ });
282
+ const finalTitle = planning.title?.trim();
283
+ if (finalTitle)
284
+ reconcileMilestonePhaseArtifactPaths(milestoneId, finalTitle);
240
285
  });
241
286
  }
242
287
  export function insertSlice(s) {
@@ -336,6 +381,11 @@ export function upsertSlicePlanning(milestoneId, sliceId, planning) {
336
381
  export function insertTask(t) {
337
382
  if (!getDbOrNull())
338
383
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
384
+ // Stamp completed_at for every terminal-complete alias (complete/done/closed),
385
+ // not just two literals — a task imported as "closed" is completed and must
386
+ // carry a timestamp. NOT for "skipped": a skipped task was never completed
387
+ // (cascade writers set its completed_at = NULL).
388
+ const isCompleteAlias = t.status != null && toStatus(t.status) === "complete";
339
389
  getDbOrNull().prepare(`INSERT INTO tasks (
340
390
  milestone_id, slice_id, id, title, status, one_liner, narrative,
341
391
  verification_result, duration, completed_at, blocker_discovered,
@@ -385,7 +435,7 @@ export function insertTask(t) {
385
435
  ":narrative": t.narrative ?? "",
386
436
  ":verification_result": t.verificationResult ?? "",
387
437
  ":duration": t.duration ?? "",
388
- ":completed_at": t.status === "done" || t.status === "complete" ? new Date().toISOString() : null,
438
+ ":completed_at": isCompleteAlias ? new Date().toISOString() : null,
389
439
  ":blocker_discovered": t.blockerDiscovered ? 1 : 0,
390
440
  ":deviations": t.deviations ?? "",
391
441
  ":known_issues": t.knownIssues ?? "",
@@ -401,7 +451,7 @@ export function insertTask(t) {
401
451
  ":observability_impact": t.planning?.observabilityImpact ?? "",
402
452
  ":full_plan_md": t.planning?.fullPlanMd ?? "",
403
453
  ":sequence": t.sequence ?? 0,
404
- ":preserve_completion": t.preserveCompletionMetadata && (t.status === "complete" || t.status === "done") ? 1 : 0,
454
+ ":preserve_completion": t.preserveCompletionMetadata && isCompleteAlias ? 1 : 0,
405
455
  ":target_repositories": JSON.stringify(t.planning?.targetRepositories ?? []),
406
456
  ":raw_target_repositories": t.planning && "targetRepositories" in t.planning
407
457
  ? JSON.stringify(t.planning.targetRepositories ?? [])
@@ -498,8 +548,8 @@ export function upsertTaskPlanning(milestoneId, sliceId, taskId, planning) {
498
548
  ":target_repositories": planning.targetRepositories ? JSON.stringify(planning.targetRepositories) : null,
499
549
  });
500
550
  }
501
- export function updateSliceStatus(milestoneId, sliceId, status, completedAt) {
502
- applyStatusTransition({ entity: "slice", milestoneId, sliceId, status, completedAt });
551
+ export function updateSliceStatus(milestoneId, sliceId, status, completedAt, preserveCompletion) {
552
+ applyStatusTransition({ entity: "slice", milestoneId, sliceId, status, completedAt, preserveCompletion });
503
553
  }
504
554
  export function setTaskSummaryMd(milestoneId, sliceId, taskId, md) {
505
555
  if (!getDbOrNull())
@@ -611,8 +661,8 @@ function writeMilestoneStatus(milestoneId, status, completedAt) {
611
661
  * advance planned milestones. They may not reopen a closed milestone; callers
612
662
  * must use reopenMilestoneStatus(), which is reserved for gsd_milestone_reopen.
613
663
  */
614
- export function updateMilestoneStatus(milestoneId, status, completedAt) {
615
- applyStatusTransition({ entity: "milestone", milestoneId, status, completedAt });
664
+ export function updateMilestoneStatus(milestoneId, status, completedAt, preserveCompletion) {
665
+ applyStatusTransition({ entity: "milestone", milestoneId, status, completedAt, preserveCompletion });
616
666
  }
617
667
  /**
618
668
  * Explicit closed -> active transition for gsd_milestone_reopen only.
@@ -657,6 +707,128 @@ export function insertReplanHistory(entry) {
657
707
  ":created_at": new Date().toISOString(),
658
708
  });
659
709
  }
710
+ function reworkBriefIdFromTask(milestoneId, sliceId, taskId) {
711
+ return `RB-${milestoneId}-${sliceId}-${taskId}`;
712
+ }
713
+ function normalizeReworkStatus(status) {
714
+ const normalized = String(status ?? "pending");
715
+ if (normalized === "resolved" || normalized === "deferred-with-override") {
716
+ return normalized;
717
+ }
718
+ return "pending";
719
+ }
720
+ function rowToReworkFinding(row) {
721
+ let verificationCommands = [];
722
+ try {
723
+ const parsed = JSON.parse(String(row["verification_commands"] ?? "[]"));
724
+ verificationCommands = Array.isArray(parsed) ? parsed.map(String) : [];
725
+ }
726
+ catch {
727
+ verificationCommands = [];
728
+ }
729
+ return {
730
+ brief_id: String(row["brief_id"] ?? ""),
731
+ finding_id: String(row["finding_id"] ?? ""),
732
+ severity: String(row["severity"] ?? "blocking") === "advisory" ? "advisory" : "blocking",
733
+ description: String(row["description"] ?? ""),
734
+ required_fix: String(row["required_fix"] ?? ""),
735
+ verification_commands: verificationCommands,
736
+ status: normalizeReworkStatus(row["status"]),
737
+ evidence: String(row["evidence"] ?? ""),
738
+ decision_ref: String(row["decision_ref"] ?? ""),
739
+ };
740
+ }
741
+ export function saveReworkBrief(entry) {
742
+ if (!getDbOrNull())
743
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
744
+ const briefId = entry.briefId?.trim() || reworkBriefIdFromTask(entry.milestoneId, entry.sliceId, entry.taskId);
745
+ const now = new Date().toISOString();
746
+ transaction(() => {
747
+ getDbOrNull().prepare(`INSERT INTO rework_briefs (id, milestone_id, slice_id, task_id, created_at, updated_at)
748
+ VALUES (:id, :mid, :sid, :tid, :created_at, :updated_at)
749
+ ON CONFLICT(id) DO UPDATE SET
750
+ milestone_id = :mid,
751
+ slice_id = :sid,
752
+ task_id = :tid,
753
+ updated_at = :updated_at`).run({
754
+ ":id": briefId,
755
+ ":mid": entry.milestoneId,
756
+ ":sid": entry.sliceId,
757
+ ":tid": entry.taskId,
758
+ ":created_at": now,
759
+ ":updated_at": now,
760
+ });
761
+ getDbOrNull().prepare("DELETE FROM rework_brief_findings WHERE brief_id = :id").run({ ":id": briefId });
762
+ const stmt = getDbOrNull().prepare(`INSERT INTO rework_brief_findings (
763
+ brief_id, finding_id, severity, description, required_fix, verification_commands,
764
+ status, evidence, decision_ref, updated_at
765
+ ) VALUES (
766
+ :brief_id, :finding_id, :severity, :description, :required_fix, :verification_commands,
767
+ :status, :evidence, :decision_ref, :updated_at
768
+ )`);
769
+ for (const finding of entry.findings) {
770
+ stmt.run({
771
+ ":brief_id": briefId,
772
+ ":finding_id": finding.findingId,
773
+ ":severity": finding.severity,
774
+ ":description": finding.description,
775
+ ":required_fix": finding.requiredFix,
776
+ ":verification_commands": JSON.stringify(finding.verificationCommands),
777
+ ":status": finding.status ?? "pending",
778
+ ":evidence": finding.evidence ?? "",
779
+ ":decision_ref": finding.decisionRef ?? "",
780
+ ":updated_at": now,
781
+ });
782
+ }
783
+ });
784
+ return { briefId };
785
+ }
786
+ export function getBlockingReworkFindingsForTask(milestoneId, sliceId, taskId) {
787
+ if (!getDbOrNull())
788
+ return [];
789
+ const rows = getDbOrNull().prepare(`SELECT f.*
790
+ FROM rework_brief_findings f
791
+ JOIN rework_briefs b ON b.id = f.brief_id
792
+ WHERE b.milestone_id = :mid
793
+ AND b.slice_id = :sid
794
+ AND b.task_id = :tid
795
+ AND f.severity = 'blocking'
796
+ ORDER BY b.created_at, f.finding_id`).all({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
797
+ return rows.map(rowToReworkFinding);
798
+ }
799
+ export function getUnresolvedBlockingReworkFindingsForTask(milestoneId, sliceId, taskId) {
800
+ return getBlockingReworkFindingsForTask(milestoneId, sliceId, taskId)
801
+ .filter((finding) => finding.status === "pending");
802
+ }
803
+ export function applyReworkResolutions(resolutions) {
804
+ if (!getDbOrNull())
805
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
806
+ const now = new Date().toISOString();
807
+ const stmt = getDbOrNull().prepare(`UPDATE rework_brief_findings
808
+ SET status = :status,
809
+ evidence = :evidence,
810
+ decision_ref = :decision_ref,
811
+ updated_at = :updated_at
812
+ WHERE finding_id = :finding_id
813
+ AND brief_id IN (
814
+ SELECT id FROM rework_briefs
815
+ WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid
816
+ )`);
817
+ transaction(() => {
818
+ for (const resolution of resolutions) {
819
+ stmt.run({
820
+ ":status": resolution.status,
821
+ ":evidence": resolution.evidence,
822
+ ":decision_ref": resolution.decisionRef ?? "",
823
+ ":updated_at": now,
824
+ ":finding_id": resolution.findingId,
825
+ ":mid": resolution.milestoneId,
826
+ ":sid": resolution.sliceId,
827
+ ":tid": resolution.taskId,
828
+ });
829
+ }
830
+ });
831
+ }
660
832
  export function insertAssessment(entry) {
661
833
  if (!getDbOrNull())
662
834
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
@@ -767,44 +939,51 @@ export function saveGateResult(g) {
767
939
  if (!getDbOrNull())
768
940
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
769
941
  const evaluatedAt = new Date().toISOString();
770
- const result = getDbOrNull().prepare(`UPDATE quality_gates
771
- SET status = 'complete', verdict = :verdict, rationale = :rationale,
772
- findings = :findings, evaluated_at = :evaluated_at
773
- WHERE milestone_id = :mid AND slice_id = :sid AND gate_id = :gid
774
- AND (task_id = :tid OR (:tid = '' AND task_id IS NULL))`).run({
775
- ":mid": g.milestoneId,
776
- ":sid": g.sliceId,
777
- ":gid": g.gateId,
778
- ":tid": g.taskId ?? "",
779
- ":verdict": g.verdict,
780
- ":rationale": g.rationale,
781
- ":findings": g.findings,
782
- ":evaluated_at": evaluatedAt,
783
- });
784
- if ((result.changes ?? 0) === 0) {
785
- throw new GSDError(GSD_STALE_STATE, `quality gate row not found for ${g.milestoneId}/${g.sliceId}/${g.gateId}${g.taskId ? `/${g.taskId}` : ""}`);
786
- }
787
- const outcome = g.verdict === "pass"
788
- ? "pass"
789
- : g.verdict === "omitted"
790
- ? "manual-attention"
791
- : "fail";
792
- insertGateRun({
793
- traceId: `quality-gate:${g.milestoneId}:${g.sliceId}`,
794
- turnId: `gate:${g.gateId}:${g.taskId ?? "slice"}`,
795
- gateId: g.gateId,
796
- gateType: "quality-gate",
797
- milestoneId: g.milestoneId,
798
- sliceId: g.sliceId,
799
- taskId: g.taskId ?? undefined,
800
- outcome,
801
- failureClass: outcome === "fail" ? "verification" : outcome === "manual-attention" ? "manual-attention" : "none",
802
- rationale: g.rationale,
803
- findings: g.findings,
804
- attempt: 1,
805
- maxAttempts: 1,
806
- retryable: false,
807
- evaluatedAt,
942
+ // Atomic: the gate verdict UPDATE and the gate_runs ledger INSERT must commit
943
+ // together. As two autocommits, a crash between them records a completed gate
944
+ // with no ledger row (the row Recovery Classification reads). transaction()
945
+ // is re-entrant, so callers already inside a transaction are safe. The
946
+ // throw-on-zero-changes stays inside so a missing gate row rolls back cleanly.
947
+ transaction(() => {
948
+ const result = getDbOrNull().prepare(`UPDATE quality_gates
949
+ SET status = 'complete', verdict = :verdict, rationale = :rationale,
950
+ findings = :findings, evaluated_at = :evaluated_at
951
+ WHERE milestone_id = :mid AND slice_id = :sid AND gate_id = :gid
952
+ AND (task_id = :tid OR (:tid = '' AND task_id IS NULL))`).run({
953
+ ":mid": g.milestoneId,
954
+ ":sid": g.sliceId,
955
+ ":gid": g.gateId,
956
+ ":tid": g.taskId ?? "",
957
+ ":verdict": g.verdict,
958
+ ":rationale": g.rationale,
959
+ ":findings": g.findings,
960
+ ":evaluated_at": evaluatedAt,
961
+ });
962
+ if ((result.changes ?? 0) === 0) {
963
+ throw new GSDError(GSD_STALE_STATE, `quality gate row not found for ${g.milestoneId}/${g.sliceId}/${g.gateId}${g.taskId ? `/${g.taskId}` : ""}`);
964
+ }
965
+ const outcome = g.verdict === "pass"
966
+ ? "pass"
967
+ : g.verdict === "omitted"
968
+ ? "manual-attention"
969
+ : "fail";
970
+ insertGateRun({
971
+ traceId: `quality-gate:${g.milestoneId}:${g.sliceId}`,
972
+ turnId: `gate:${g.gateId}:${g.taskId ?? "slice"}`,
973
+ gateId: g.gateId,
974
+ gateType: "quality-gate",
975
+ milestoneId: g.milestoneId,
976
+ sliceId: g.sliceId,
977
+ taskId: g.taskId ?? undefined,
978
+ outcome,
979
+ failureClass: outcome === "fail" ? "verification" : outcome === "manual-attention" ? "manual-attention" : "none",
980
+ rationale: g.rationale,
981
+ findings: g.findings,
982
+ attempt: 1,
983
+ maxAttempts: 1,
984
+ retryable: false,
985
+ evaluatedAt,
986
+ });
808
987
  });
809
988
  }
810
989
  export function markAllGatesOmitted(milestoneId, sliceId) {
@@ -1012,6 +1191,13 @@ export function deleteArtifactsByPathPrefix(prefix) {
1012
1191
  return Number(countRow?.["count"] ?? 0);
1013
1192
  });
1014
1193
  }
1194
+ /** List artifact rows whose paths share a DB-relative prefix. */
1195
+ export function getArtifactsByPathPrefix(prefix) {
1196
+ if (!getDbOrNull())
1197
+ return [];
1198
+ const rows = getDbOrNull().prepare("SELECT * FROM artifacts WHERE path LIKE :prefix ORDER BY path").all({ ":prefix": `${prefix}%` });
1199
+ return rows.map(rowToArtifact);
1200
+ }
1015
1201
  /**
1016
1202
  * Drop hierarchy rows in dependency order inside a transaction. Used by
1017
1203
  * `gsd recover --confirm` to rebuild engine state from markdown.
@@ -11,7 +11,7 @@ import { loadFile, saveFile } from "./files.js";
11
11
  import { isDbAvailable, getMilestone, getMilestoneSlices } from "./gsd-db.js";
12
12
  import { parseRoadmapSlices } from "./roadmap-slices.js";
13
13
  import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
14
- import { buildCompleteSlicePrompt, buildDiscussMilestonePrompt, buildExecuteTaskPrompt, buildPlanMilestonePrompt, buildPlanSlicePrompt, buildSkillActivationBlock, } from "./auto-prompts.js";
14
+ import { buildCompleteSlicePrompt, buildDiscussMilestonePrompt, buildExecuteTaskPrompt, buildPlanMilestonePrompt, buildPlanSlicePrompt, buildSkillActivationBlock, capPreamble, } from "./auto-prompts.js";
15
15
  import { deriveState, isGhostMilestone } from "./state.js";
16
16
  import { invalidateAllCaches } from "./cache.js";
17
17
  import { startAutoDetached } from "./auto.js";
@@ -603,6 +603,9 @@ export const _dispatchWorkflowForTest = dispatchWorkflow;
603
603
  export function getDiscussableFutureMilestones(registry, activeMilestoneId) {
604
604
  return registry.filter((m) => m.id !== activeMilestoneId && m.status !== "complete" && m.status !== "parked");
605
605
  }
606
+ function findDiscussTargetMilestone(registry, milestoneId) {
607
+ return registry.find((m) => m.id === milestoneId || m.id.startsWith(`${milestoneId}-`));
608
+ }
606
609
  function getStructuredQuestionsAvailability(pi, ctx) {
607
610
  if (!ctx)
608
611
  return "false";
@@ -852,7 +855,9 @@ function resolveDiscussSliceBasePath(basePath, milestoneId) {
852
855
  * slice summaries so the agent can ask grounded UX/behaviour questions
853
856
  * without wasting a turn reading files.
854
857
  */
855
- async function buildDiscussSlicePrompt(mid, sid, sTitle, base, options) {
858
+ // Exported for tests (`prompt-budget-enforcement.test.ts`) verifies the
859
+ // inlined-context cap. Not part of the public flow surface otherwise.
860
+ export async function buildDiscussSlicePrompt(mid, sid, sTitle, base, options) {
856
861
  const inlined = [];
857
862
  // Roadmap — always included so the agent sees surrounding slices
858
863
  const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
@@ -903,8 +908,12 @@ async function buildDiscussSlicePrompt(mid, sid, sTitle, base, options) {
903
908
  }
904
909
  }
905
910
  }
911
+ // Cap the inlined block: it grows unbounded with each completed slice's full
912
+ // SUMMARY. `capPreamble` truncates at `### ` section boundaries — roadmap and
913
+ // milestone context come first (survive), completed-slice summaries come last
914
+ // (dropped first) when the executor's window can't hold everything.
906
915
  const inlinedContext = inlined.length > 0
907
- ? `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`
916
+ ? capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`)
908
917
  : `## Inlined Context\n\n_(no context files found yet — go in blind and ask broad questions)_`;
909
918
  const sliceDirPath = `.gsd/milestones/${mid}/slices/${sid}`;
910
919
  const sliceContextPath = `${sliceDirPath}/${sid}-CONTEXT.md`;
@@ -913,7 +922,7 @@ async function buildDiscussSlicePrompt(mid, sid, sTitle, base, options) {
913
922
  ? `\n\n## Re-discuss Mode\n\nThis slice already has an existing context file (\`${sliceContextPath}\`) from a prior discussion. The user has chosen to re-discuss it. Read the existing context file, interview for any updates, changes, or new decisions, and rewrite the file with merged findings. Do NOT skip the interview — the user explicitly asked to revisit this slice.\n`
914
923
  : "";
915
924
  const inlinedTemplates = inlineTemplate("slice-context", "Slice Context");
916
- return loadPrompt("guided-discuss-slice", {
925
+ return prependLanguageDirective(base, loadPrompt("guided-discuss-slice", {
917
926
  milestoneId: mid,
918
927
  sliceId: sid,
919
928
  sliceTitle: sTitle,
@@ -924,7 +933,7 @@ async function buildDiscussSlicePrompt(mid, sid, sTitle, base, options) {
924
933
  inlinedTemplates,
925
934
  structuredQuestionsAvailable: options?.structuredQuestionsAvailable ?? "false",
926
935
  commitInstruction: buildDocsCommitInstruction(`docs(${mid}/${sid}): slice context from discuss`),
927
- });
936
+ }));
928
937
  }
929
938
  /**
930
939
  * /gsd discuss — show a picker of non-done slices and run a slice interview.
@@ -964,12 +973,20 @@ export async function showDiscuss(ctx, pi, basePath, options) {
964
973
  if (slash > 0) {
965
974
  const mid = target.slice(0, slash);
966
975
  const sid = target.slice(slash + 1);
967
- const targetMilestone = state.registry.find((m) => m.id === mid);
968
- if (!targetMilestone || targetMilestone.status === "complete" || targetMilestone.status === "parked") {
969
- ctx.ui.notify(`Milestone ${mid} is not discussable.`, "warning");
976
+ const targetMilestone = findDiscussTargetMilestone(state.registry, mid);
977
+ if (!targetMilestone) {
978
+ ctx.ui.notify(`Milestone ${mid} was not found in the roadmap. Use /gsd new-milestone to add it, or /gsd status to see available milestones.`, "warning");
970
979
  return;
971
980
  }
972
- const slices = await loadDiscussNormSlices(basePath, mid);
981
+ if (targetMilestone.status === "complete") {
982
+ ctx.ui.notify(`Milestone ${targetMilestone.id} is already complete.`, "info");
983
+ return;
984
+ }
985
+ if (targetMilestone.status === "parked") {
986
+ ctx.ui.notify(`Milestone ${targetMilestone.id} is parked. Run /gsd unpark ${targetMilestone.id} to reactivate.`, "warning");
987
+ return;
988
+ }
989
+ const slices = await loadDiscussNormSlices(basePath, targetMilestone.id);
973
990
  const chosen = slices.find((s) => s.id.toUpperCase() === sid.toUpperCase());
974
991
  if (!chosen) {
975
992
  ctx.ui.notify(`Slice ${target} was not found in discussable slices.`, "warning");
@@ -979,19 +996,27 @@ export async function showDiscuss(ctx, pi, basePath, options) {
979
996
  ctx.ui.notify(`Slice ${target} is already complete; nothing to discuss.`, "info");
980
997
  return;
981
998
  }
982
- const discussBasePath = resolveDiscussSliceBasePath(basePath, mid);
983
- const contextFile = resolveSliceFile(discussBasePath, mid, sid, "CONTEXT");
999
+ const discussBasePath = resolveDiscussSliceBasePath(basePath, targetMilestone.id);
1000
+ const contextFile = resolveSliceFile(discussBasePath, targetMilestone.id, sid, "CONTEXT");
984
1001
  const sqAvail = getStructuredQuestionsAvailability(pi, ctx);
985
- const prompt = await buildDiscussSlicePrompt(mid, sid, chosen.title, discussBasePath, {
1002
+ const prompt = await buildDiscussSlicePrompt(targetMilestone.id, sid, chosen.title, discussBasePath, {
986
1003
  rediscuss: !!contextFile,
987
1004
  structuredQuestionsAvailable: sqAvail,
988
1005
  });
989
1006
  await dispatchWorkflow(pi, prompt, "gsd-discuss", ctx, "discuss-slice", { basePath: discussBasePath });
990
1007
  return;
991
1008
  }
992
- const targetMilestone = state.registry.find((m) => m.id === target);
993
- if (!targetMilestone || targetMilestone.status === "complete" || targetMilestone.status === "parked") {
994
- ctx.ui.notify(`Milestone ${target} is not discussable.`, "warning");
1009
+ const targetMilestone = findDiscussTargetMilestone(state.registry, target);
1010
+ if (!targetMilestone) {
1011
+ ctx.ui.notify(`Milestone ${target} was not found in the roadmap. Use /gsd new-milestone to add it, or /gsd status to see available milestones.`, "warning");
1012
+ return;
1013
+ }
1014
+ if (targetMilestone.status === "complete") {
1015
+ ctx.ui.notify(`Milestone ${targetMilestone.id} is already complete.`, "info");
1016
+ return;
1017
+ }
1018
+ if (targetMilestone.status === "parked") {
1019
+ ctx.ui.notify(`Milestone ${targetMilestone.id} is parked. Run /gsd unpark ${targetMilestone.id} to reactivate.`, "warning");
995
1020
  return;
996
1021
  }
997
1022
  await dispatchDiscussForMilestone(ctx, pi, basePath, targetMilestone.id, targetMilestone.title, {});
@@ -11,14 +11,14 @@
11
11
  import { readFileSync, existsSync, mkdirSync, statSync, unlinkSync } from "node:fs";
12
12
  import { logWarning } from "./workflow-logger.js";
13
13
  import { isClosedStatus } from "./status-guards.js";
14
- import { dirname, join, relative } from "node:path";
14
+ import { dirname, join } from "node:path";
15
15
  import { getAllMilestones, getMilestone, getMilestoneScopedArtifacts, getSliceScopedArtifacts, getMilestoneSlices, getSliceTasks, getTasksBySliceIds, getTask, getSlice, insertArtifact, deleteArtifactByPath, getGateResults, isDbAvailable, } from "./gsd-db.js";
16
- import { resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTasksDir, targetMilestoneFile, targetSliceFile, gsdProjectionRoot, gsdRoot, buildTaskFileName, } from "./paths.js";
16
+ import { resolveDir, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTasksDir, targetMilestoneFile, targetSliceFile, targetTaskFile, gsdProjectionRoot, gsdRoot, buildTaskFileName, } from "./paths.js";
17
17
  import { saveFile, clearParseCache, registerCacheClearCallback } from "./files.js";
18
18
  import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
19
19
  import { invalidateStateCache } from "./state.js";
20
20
  import { clearPathCache, milestonesDir, legacyMilestonesDir, isLegacyMilestonesLayout, resolveMilestonePath, relSliceFile, canonicalPhaseDirName } from "./paths.js";
21
- import { readCompatMarker, writeCompatMarker, computeProjectionSha } from "./compat/compat-marker.js";
21
+ import { readCompatMarker, writeCompatMarker, computeProjectionSha, deriveCompatProjectionKey } from "./compat/compat-marker.js";
22
22
  // ─── Compat marker invalidation ───────────────────────────────────────────
23
23
  // Every successful projection write pushes its (basePath, projectionPath,
24
24
  // entities) here; invalidateCaches() drains it and refreshes .gsd/.compat.json
@@ -71,13 +71,7 @@ function flushProjectionWritesToMarker() {
71
71
  */
72
72
  function toArtifactPath(absPath, basePath) {
73
73
  const projectionRoot = gsdProjectionRoot(basePath);
74
- const projectionRel = relative(projectionRoot, absPath);
75
- const root = projectionRel && !projectionRel.startsWith("..") && !projectionRel.startsWith("/")
76
- ? projectionRoot
77
- : gsdRoot(basePath);
78
- const rel = relative(root, absPath);
79
- // Normalize to forward slashes for consistent DB keys
80
- return rel.replace(/\\/g, "/");
74
+ return deriveCompatProjectionKey(absPath, [projectionRoot, gsdRoot(basePath)]);
81
75
  }
82
76
  /**
83
77
  * Invalidate all caches after a disk write.
@@ -612,17 +606,7 @@ export async function renderTaskSummary(basePath, milestoneId, sliceId, taskId)
612
606
  if (!task || !task.full_summary_md) {
613
607
  return false; // No summary to render — skip silently
614
608
  }
615
- // Resolve the tasks directory, creating path if needed
616
- const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
617
- if (!slicePath) {
618
- process.stderr.write(`markdown-renderer: cannot resolve slice path for ${milestoneId}/${sliceId}\n`);
619
- return false;
620
- }
621
- // Use the tasks/ subdir when it exists (legacy layout), otherwise use the
622
- // slice path directly (flat-phase: task summaries live alongside plan files).
623
- const tasksDir = resolveTasksDir(basePath, milestoneId, sliceId) ?? slicePath;
624
- const fileName = buildTaskFileName(taskId, "SUMMARY");
625
- const absPath = join(tasksDir, fileName);
609
+ const absPath = targetTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY", getMilestone(milestoneId)?.title);
626
610
  const artifactPath = toArtifactPath(absPath, basePath);
627
611
  await writeAndStore(absPath, artifactPath, task.full_summary_md, {
628
612
  artifact_type: "SUMMARY",
@@ -975,6 +959,19 @@ function detectStaleRendersImpl(basePath) {
975
959
  export function roadmapRenderMarksSliceDone(roadmapContent, sliceId) {
976
960
  return parseRoadmap(roadmapContent).slices.some((slice) => slice.id === sliceId && slice.done);
977
961
  }
962
+ function existingLegacySliceAssessmentPath(basePath, milestoneId, sliceId) {
963
+ if (!isLegacyMilestonesLayout(basePath))
964
+ return null;
965
+ const legacyBase = legacyMilestonesDir(basePath);
966
+ const milestoneDirName = resolveDir(legacyBase, milestoneId);
967
+ if (!milestoneDirName)
968
+ return null;
969
+ const slicesDir = join(legacyBase, milestoneDirName, "slices");
970
+ const sliceDirName = resolveDir(slicesDir, sliceId);
971
+ if (!sliceDirName)
972
+ return null;
973
+ return join(slicesDir, sliceDirName, `${sliceId}-ASSESSMENT.md`);
974
+ }
978
975
  export async function renderReplanFromDb(basePath, milestoneId, sliceId, replanData) {
979
976
  const absPath = targetSliceFile(basePath, milestoneId, sliceId, "REPLAN", getMilestone(milestoneId)?.title);
980
977
  mkdirSync(dirname(absPath), { recursive: true });
@@ -1004,7 +1001,8 @@ export async function renderReplanFromDb(basePath, milestoneId, sliceId, replanD
1004
1001
  return { replanPath: absPath, content };
1005
1002
  }
1006
1003
  export async function renderAssessmentFromDb(basePath, milestoneId, sliceId, assessmentData) {
1007
- const absPath = targetSliceFile(basePath, milestoneId, sliceId, "ASSESSMENT", getMilestone(milestoneId)?.title);
1004
+ const absPath = existingLegacySliceAssessmentPath(basePath, milestoneId, sliceId)
1005
+ ?? targetSliceFile(basePath, milestoneId, sliceId, "ASSESSMENT", getMilestone(milestoneId)?.title);
1008
1006
  mkdirSync(dirname(absPath), { recursive: true });
1009
1007
  const artifactPath = toArtifactPath(absPath, basePath);
1010
1008
  const lines = [];