gsd-pi 2.48.0 → 2.49.0-dev.9e177e9

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 (369) hide show
  1. package/dist/headless-ui.js +12 -2
  2. package/dist/headless.js +29 -13
  3. package/dist/resources/extensions/gsd/auto/infra-errors.js +1 -0
  4. package/dist/resources/extensions/gsd/auto/phases.js +11 -11
  5. package/dist/resources/extensions/gsd/auto/resolve.js +2 -2
  6. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -2
  7. package/dist/resources/extensions/gsd/auto/session.js +4 -0
  8. package/dist/resources/extensions/gsd/auto-artifact-paths.js +8 -10
  9. package/dist/resources/extensions/gsd/auto-dashboard.js +6 -3
  10. package/dist/resources/extensions/gsd/auto-dispatch.js +34 -7
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +34 -27
  12. package/dist/resources/extensions/gsd/auto-prompts.js +102 -21
  13. package/dist/resources/extensions/gsd/auto-recovery.js +62 -184
  14. package/dist/resources/extensions/gsd/auto-start.js +4 -31
  15. package/dist/resources/extensions/gsd/auto-timers.js +2 -2
  16. package/dist/resources/extensions/gsd/auto-verification.js +4 -7
  17. package/dist/resources/extensions/gsd/auto-worktree.js +262 -115
  18. package/dist/resources/extensions/gsd/auto.js +7 -5
  19. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -0
  20. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +8 -1
  21. package/dist/resources/extensions/gsd/branch-patterns.js +13 -0
  22. package/dist/resources/extensions/gsd/commands/handlers/auto.js +43 -3
  23. package/dist/resources/extensions/gsd/doctor-checks.js +5 -1234
  24. package/dist/resources/extensions/gsd/doctor-engine-checks.js +168 -0
  25. package/dist/resources/extensions/gsd/doctor-environment.js +28 -7
  26. package/dist/resources/extensions/gsd/doctor-git-checks.js +405 -0
  27. package/dist/resources/extensions/gsd/doctor-global-checks.js +74 -0
  28. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +600 -0
  29. package/dist/resources/extensions/gsd/doctor.js +9 -1
  30. package/dist/resources/extensions/gsd/extension-manifest.json +1 -1
  31. package/dist/resources/extensions/gsd/git-service.js +20 -20
  32. package/dist/resources/extensions/gsd/gsd-db.js +124 -1
  33. package/dist/resources/extensions/gsd/guided-flow-queue.js +10 -11
  34. package/dist/resources/extensions/gsd/markdown-renderer.js +33 -5
  35. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  36. package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
  37. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
  38. package/dist/resources/extensions/gsd/prompts/complete-slice.md +9 -8
  39. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +223 -56
  40. package/dist/resources/extensions/gsd/prompts/execute-task.md +16 -13
  41. package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
  42. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
  43. package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  44. package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  45. package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  46. package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  47. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  48. package/dist/resources/extensions/gsd/prompts/plan-slice.md +8 -3
  49. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
  50. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  51. package/dist/resources/extensions/gsd/prompts/run-uat.md +4 -4
  52. package/dist/resources/extensions/gsd/repo-identity.js +29 -0
  53. package/dist/resources/extensions/gsd/roadmap-slices.js +2 -2
  54. package/dist/resources/extensions/gsd/session-forensics.js +6 -11
  55. package/dist/resources/extensions/gsd/session-lock.js +67 -56
  56. package/dist/resources/extensions/gsd/state.js +34 -7
  57. package/dist/resources/extensions/gsd/templates/milestone-summary.md +8 -0
  58. package/dist/resources/extensions/gsd/templates/plan.md +16 -0
  59. package/dist/resources/extensions/gsd/templates/roadmap.md +13 -0
  60. package/dist/resources/extensions/gsd/templates/slice-summary.md +9 -0
  61. package/dist/resources/extensions/gsd/templates/task-plan.md +24 -0
  62. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -1
  63. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -3
  64. package/dist/resources/extensions/gsd/verdict-parser.js +84 -0
  65. package/dist/resources/extensions/gsd/worktree-command.js +1 -1
  66. package/dist/resources/extensions/gsd/worktree-resolver.js +24 -0
  67. package/dist/resources/extensions/gsd/worktree.js +3 -2
  68. package/dist/resources/extensions/remote-questions/config.js +3 -5
  69. package/dist/resources/extensions/search-the-web/native-search.js +8 -3
  70. package/dist/resources/extensions/search-the-web/tool-search.js +19 -2
  71. package/dist/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
  72. package/dist/web/standalone/.next/BUILD_ID +1 -1
  73. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  74. package/dist/web/standalone/.next/build-manifest.json +4 -4
  75. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  76. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  77. package/dist/web/standalone/.next/required-server-files.json +4 -4
  78. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  79. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  81. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  89. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  91. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  93. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  95. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  105. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  143. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  149. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  163. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  165. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  167. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  169. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/index.html +1 -1
  179. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  180. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  181. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  182. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  183. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  184. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/page.js +2 -2
  186. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  188. package/dist/web/standalone/.next/server/chunks/229.js +2 -2
  189. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  190. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/middleware.js +2 -2
  193. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  195. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  196. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  197. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  198. package/dist/web/standalone/.next/static/chunks/4024.7c75ac378de0f2b5.js +9 -0
  199. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  200. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  201. package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
  202. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  203. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  204. package/dist/web/standalone/.next/static/chunks/{webpack-0a4cd455ec4197d2.js → webpack-2473ce2c3879fff4.js} +1 -1
  205. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  206. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  207. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  208. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  209. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  210. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  211. package/dist/web/standalone/server.js +1 -1
  212. package/dist/worktree-cli.js +1 -1
  213. package/package.json +1 -1
  214. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  215. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  216. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  217. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  218. package/packages/pi-ai/dist/providers/openai-codex-responses.js +39 -10
  219. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  220. package/packages/pi-ai/src/providers/openai-codex-responses.ts +39 -8
  221. package/packages/pi-coding-agent/dist/core/blob-store.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/blob-store.js +8 -3
  223. package/packages/pi-coding-agent/dist/core/blob-store.js.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/discovery-cache.d.ts.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/discovery-cache.js +9 -2
  226. package/packages/pi-coding-agent/dist/core/discovery-cache.js.map +1 -1
  227. package/packages/pi-coding-agent/dist/core/retry-handler.js +1 -1
  228. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  229. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -32
  231. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/modes/rpc/jsonl.d.ts.map +1 -1
  233. package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js +5 -0
  234. package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js.map +1 -1
  235. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +0 -1
  237. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  238. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  239. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  240. package/packages/pi-coding-agent/package.json +1 -1
  241. package/packages/pi-coding-agent/src/core/blob-store.ts +6 -3
  242. package/packages/pi-coding-agent/src/core/discovery-cache.ts +9 -2
  243. package/packages/pi-coding-agent/src/core/retry-handler.ts +1 -1
  244. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +7 -32
  245. package/packages/pi-coding-agent/src/modes/rpc/jsonl.ts +6 -0
  246. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +0 -2
  247. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
  248. package/pkg/package.json +1 -1
  249. package/src/resources/extensions/github-sync/tests/commit-linking.test.ts +8 -4
  250. package/src/resources/extensions/gsd/auto/infra-errors.ts +1 -0
  251. package/src/resources/extensions/gsd/auto/phases.ts +10 -11
  252. package/src/resources/extensions/gsd/auto/resolve.ts +3 -3
  253. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -2
  254. package/src/resources/extensions/gsd/auto/session.ts +5 -0
  255. package/src/resources/extensions/gsd/auto/types.ts +13 -0
  256. package/src/resources/extensions/gsd/auto-artifact-paths.ts +19 -21
  257. package/src/resources/extensions/gsd/auto-dashboard.ts +5 -2
  258. package/src/resources/extensions/gsd/auto-dispatch.ts +40 -5
  259. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  260. package/src/resources/extensions/gsd/auto-post-unit.ts +36 -31
  261. package/src/resources/extensions/gsd/auto-prompts.ts +113 -19
  262. package/src/resources/extensions/gsd/auto-recovery.ts +65 -199
  263. package/src/resources/extensions/gsd/auto-start.ts +7 -27
  264. package/src/resources/extensions/gsd/auto-timers.ts +2 -2
  265. package/src/resources/extensions/gsd/auto-verification.ts +4 -7
  266. package/src/resources/extensions/gsd/auto-worktree.ts +309 -110
  267. package/src/resources/extensions/gsd/auto.ts +11 -10
  268. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +93 -0
  269. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +8 -0
  270. package/src/resources/extensions/gsd/branch-patterns.ts +16 -0
  271. package/src/resources/extensions/gsd/commands/handlers/auto.ts +46 -3
  272. package/src/resources/extensions/gsd/doctor-checks.ts +5 -1291
  273. package/src/resources/extensions/gsd/doctor-engine-checks.ts +182 -0
  274. package/src/resources/extensions/gsd/doctor-environment.ts +30 -7
  275. package/src/resources/extensions/gsd/doctor-git-checks.ts +415 -0
  276. package/src/resources/extensions/gsd/doctor-global-checks.ts +84 -0
  277. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +626 -0
  278. package/src/resources/extensions/gsd/doctor.ts +9 -1
  279. package/src/resources/extensions/gsd/extension-manifest.json +1 -1
  280. package/src/resources/extensions/gsd/git-service.ts +19 -26
  281. package/src/resources/extensions/gsd/gsd-db.ts +150 -2
  282. package/src/resources/extensions/gsd/guided-flow-queue.ts +11 -12
  283. package/src/resources/extensions/gsd/markdown-renderer.ts +37 -4
  284. package/src/resources/extensions/gsd/preferences-types.ts +5 -1
  285. package/src/resources/extensions/gsd/preferences-validation.ts +37 -0
  286. package/src/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
  287. package/src/resources/extensions/gsd/prompts/complete-slice.md +9 -8
  288. package/src/resources/extensions/gsd/prompts/discuss-headless.md +223 -56
  289. package/src/resources/extensions/gsd/prompts/execute-task.md +16 -13
  290. package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
  291. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
  292. package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  293. package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  294. package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  295. package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  296. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  297. package/src/resources/extensions/gsd/prompts/plan-slice.md +8 -3
  298. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
  299. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  300. package/src/resources/extensions/gsd/prompts/run-uat.md +4 -4
  301. package/src/resources/extensions/gsd/repo-identity.ts +28 -0
  302. package/src/resources/extensions/gsd/roadmap-slices.ts +2 -2
  303. package/src/resources/extensions/gsd/session-forensics.ts +6 -11
  304. package/src/resources/extensions/gsd/session-lock.ts +92 -64
  305. package/src/resources/extensions/gsd/state.ts +38 -5
  306. package/src/resources/extensions/gsd/templates/milestone-summary.md +8 -0
  307. package/src/resources/extensions/gsd/templates/plan.md +16 -0
  308. package/src/resources/extensions/gsd/templates/roadmap.md +13 -0
  309. package/src/resources/extensions/gsd/templates/slice-summary.md +9 -0
  310. package/src/resources/extensions/gsd/templates/task-plan.md +24 -0
  311. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +2 -2
  312. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +2 -2
  313. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +35 -0
  314. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +1 -81
  315. package/src/resources/extensions/gsd/tests/auto-stash-merge.test.ts +1 -1
  316. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +14 -12
  317. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  318. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  319. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +9 -12
  320. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +115 -1
  321. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +65 -1
  322. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +50 -0
  323. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +1 -1
  324. package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +189 -0
  325. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +156 -0
  326. package/src/resources/extensions/gsd/tests/git-service.test.ts +68 -9
  327. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  328. package/src/resources/extensions/gsd/tests/infra-error.test.ts +12 -2
  329. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +39 -0
  330. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  331. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  332. package/src/resources/extensions/gsd/tests/milestone-transition-worktree.test.ts +2 -2
  333. package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +6 -6
  334. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +347 -0
  335. package/src/resources/extensions/gsd/tests/queue-completed-milestone-perf.test.ts +155 -0
  336. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +2 -1
  337. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +32 -0
  338. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +26 -0
  339. package/src/resources/extensions/gsd/tests/run-uat.test.ts +87 -15
  340. package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +223 -0
  341. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +44 -4
  342. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -1
  343. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +2 -1
  344. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +0 -16
  345. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +67 -0
  346. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +1 -1
  347. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +204 -0
  348. package/src/resources/extensions/gsd/tools/plan-slice.ts +16 -0
  349. package/src/resources/extensions/gsd/tools/validate-milestone.ts +3 -3
  350. package/src/resources/extensions/gsd/types.ts +30 -0
  351. package/src/resources/extensions/gsd/verdict-parser.ts +95 -0
  352. package/src/resources/extensions/gsd/verification-gate.ts +0 -2
  353. package/src/resources/extensions/gsd/worktree-command.ts +1 -1
  354. package/src/resources/extensions/gsd/worktree-resolver.ts +31 -0
  355. package/src/resources/extensions/gsd/worktree.ts +3 -2
  356. package/src/resources/extensions/remote-questions/config.ts +3 -5
  357. package/src/resources/extensions/search-the-web/native-search.ts +8 -3
  358. package/src/resources/extensions/search-the-web/tool-search.ts +22 -2
  359. package/src/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
  360. package/dist/resources/extensions/gsd/auto-worktree-sync.js +0 -191
  361. package/dist/resources/extensions/gsd/resource-version.js +0 -97
  362. package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +0 -9
  363. package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
  364. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  365. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  366. package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -234
  367. package/src/resources/extensions/gsd/resource-version.ts +0 -101
  368. /package/dist/web/standalone/.next/static/{zGWUKFTfjCQerNgsPpAbF → vNN0h0emdEi8l_npi8poE}/_buildManifest.js +0 -0
  369. /package/dist/web/standalone/.next/static/{zGWUKFTfjCQerNgsPpAbF → vNN0h0emdEi8l_npi8poE}/_ssgManifest.js +0 -0
@@ -450,7 +450,15 @@ export async function runGSDDoctor(basePath, options) {
450
450
  }));
451
451
  }
452
452
  else {
453
- slices = parseLegacyRoadmap(roadmapContent).slices;
453
+ const activeMilestoneId = state.activeMilestone?.id;
454
+ const activeSliceId = state.activeSlice?.id;
455
+ slices = parseLegacyRoadmap(roadmapContent).slices.map(s => ({
456
+ ...s,
457
+ // Legacy roadmaps only encode done vs not-done. For doctor's
458
+ // missing-directory checks, treat every undone slice except the
459
+ // current active slice as effectively pending/unstarted.
460
+ pending: !s.done && (milestoneId !== activeMilestoneId || s.id !== activeSliceId),
461
+ }));
454
462
  }
455
463
  // Wrap in Roadmap-compatible shape for detectCircularDependencies
456
464
  const roadmap = { slices };
@@ -12,7 +12,7 @@
12
12
  "gsd_requirement_update", "gsd_milestone_generate_id"
13
13
  ],
14
14
  "commands": ["gsd", "kill", "worktree", "exit"],
15
- "hooks": ["session_start"],
15
+ "hooks": ["session_start", "session_switch"],
16
16
  "shortcuts": ["Ctrl+Alt+G"]
17
17
  }
18
18
  }
@@ -13,28 +13,31 @@ import { join } from "node:path";
13
13
  import { gsdRoot } from "./paths.js";
14
14
  import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
15
15
  import { loadEffectiveGSDPreferences } from "./preferences.js";
16
- import { detectWorktreeName, SLICE_BRANCH_RE, } from "./worktree.js";
16
+ import { detectWorktreeName, } from "./worktree.js";
17
+ import { SLICE_BRANCH_RE, QUICK_BRANCH_RE, WORKFLOW_BRANCH_RE } from "./branch-patterns.js";
17
18
  import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeBranchExists, nativeHasChanges, nativeAddAllWithExclusions, nativeHasStagedChanges, nativeCommit, nativeRmCached, nativeUpdateRef, } from "./native-git-bridge.js";
18
19
  import { GSDError, GSD_MERGE_CONFLICT, GSD_GIT_ERROR } from "./errors.js";
19
20
  import { getErrorMessage } from "./error-utils.js";
20
21
  export const VALID_BRANCH_NAME = /^[a-zA-Z0-9_\-\/.]+$/;
21
22
  /**
22
23
  * Build a meaningful conventional commit message from task execution context.
23
- * Format: `{type}({sliceId}/{taskId}): {description}`
24
+ * Format: `{type}: {description}` (clean conventional commit — no GSD IDs in subject).
25
+ *
26
+ * GSD metadata is placed in a `GSD-Task:` git trailer at the end of the body,
27
+ * following the same convention as `Signed-off-by:` or `Co-Authored-By:`.
24
28
  *
25
29
  * The description is the task summary one-liner if available (it describes
26
30
  * what was actually built), falling back to the task title (what was planned).
27
31
  */
28
32
  export function buildTaskCommitMessage(ctx) {
29
- const scope = ctx.taskId; // e.g. "S01/T02" or just "T02"
30
33
  const description = ctx.oneLiner || ctx.taskTitle;
31
34
  const type = inferCommitType(ctx.taskTitle, ctx.oneLiner);
32
- // Truncate description to ~72 chars for subject line
33
- const maxDescLen = 68 - type.length - scope.length;
35
+ // Truncate description to ~72 chars for subject line (full budget without scope)
36
+ const maxDescLen = 70 - type.length;
34
37
  const truncated = description.length > maxDescLen
35
38
  ? description.slice(0, maxDescLen - 1).trimEnd() + "…"
36
39
  : description;
37
- const subject = `${type}(${scope}): ${truncated}`;
40
+ const subject = `${type}: ${truncated}`;
38
41
  // Build body with key files if available
39
42
  const bodyParts = [];
40
43
  if (ctx.keyFiles && ctx.keyFiles.length > 0) {
@@ -44,13 +47,12 @@ export function buildTaskCommitMessage(ctx) {
44
47
  .join("\n");
45
48
  bodyParts.push(fileLines);
46
49
  }
50
+ // Trailers: GSD-Task first, then Resolves
51
+ bodyParts.push(`GSD-Task: ${ctx.taskId}`);
47
52
  if (ctx.issueNumber) {
48
53
  bodyParts.push(`Resolves #${ctx.issueNumber}`);
49
54
  }
50
- if (bodyParts.length > 0) {
51
- return `${subject}\n\n${bodyParts.join("\n\n")}`;
52
- }
53
- return subject;
55
+ return `${subject}\n\n${bodyParts.join("\n\n")}`;
54
56
  }
55
57
  /**
56
58
  * Thrown when a slice merge hits code conflicts in non-.gsd files.
@@ -132,8 +134,8 @@ export function readIntegrationBranch(basePath, milestoneId) {
132
134
  *
133
135
  * The file is committed immediately so the metadata is persisted in git.
134
136
  */
135
- /** Regex matching GSD quick-task branches: gsd/quick/<num>-<slug> */
136
- export const QUICK_BRANCH_RE = /^gsd\/quick\//;
137
+ /** Re-export for backward compatibility canonical definitions in branch-patterns.ts */
138
+ export { QUICK_BRANCH_RE, WORKFLOW_BRANCH_RE } from "./branch-patterns.js";
137
139
  export function writeIntegrationBranch(basePath, milestoneId, branch) {
138
140
  // Don't record slice branches as the integration target
139
141
  if (SLICE_BRANCH_RE.test(branch))
@@ -143,6 +145,11 @@ export function writeIntegrationBranch(basePath, milestoneId, branch) {
143
145
  // target causes milestone merges to land on the wrong branch (#1293).
144
146
  if (QUICK_BRANCH_RE.test(branch))
145
147
  return;
148
+ // Don't record workflow-template branches (hotfix, bugfix, spike, etc.) —
149
+ // same root cause as quick-task branches (#2498). All templates create
150
+ // gsd/<templateId>/<slug> branches that are ephemeral.
151
+ if (WORKFLOW_BRANCH_RE.test(branch))
152
+ return;
146
153
  // Validate
147
154
  if (!VALID_BRANCH_NAME.test(branch))
148
155
  return;
@@ -298,10 +305,6 @@ export class GitServiceImpl {
298
305
  setMilestoneId(milestoneId) {
299
306
  this._milestoneId = milestoneId;
300
307
  }
301
- /** Convenience wrapper: run git in this repo's basePath. */
302
- git(args, options = {}) {
303
- return runGit(this.basePath, args, options);
304
- }
305
308
  /**
306
309
  * Smart staging: `git add -A` excluding GSD runtime paths via pathspec.
307
310
  * Falls back to plain `git add -A` if the exclusion pathspec fails.
@@ -385,7 +388,7 @@ export class GitServiceImpl {
385
388
  return null;
386
389
  const message = taskContext
387
390
  ? buildTaskCommitMessage(taskContext)
388
- : `chore(${unitId}): auto-commit after ${unitType}`;
391
+ : `chore: auto-commit after ${unitType}\n\nGSD-Unit: ${unitId}`;
389
392
  nativeCommit(this.basePath, message, { allowEmpty: false });
390
393
  return message;
391
394
  }
@@ -441,9 +444,6 @@ export class GitServiceImpl {
441
444
  getCurrentBranch() {
442
445
  return nativeGetCurrentBranch(this.basePath);
443
446
  }
444
- /** True if currently on a GSD slice branch. */
445
- // ─── Branch Lifecycle ──────────────────────────────────────────────────
446
- // ─── S05 Features ─────────────────────────────────────────────────────
447
447
  /**
448
448
  * Create a snapshot ref for the given label (typically a slice branch name).
449
449
  * Gated on prefs.snapshots === true. Ref path: refs/gsd/snapshots/<label>/<timestamp>
@@ -109,7 +109,7 @@ function openRawDb(path) {
109
109
  const Database = providerModule;
110
110
  return new Database(path);
111
111
  }
112
- const SCHEMA_VERSION = 11;
112
+ const SCHEMA_VERSION = 12;
113
113
  function initSchema(db, fileBacked) {
114
114
  if (fileBacked)
115
115
  db.exec("PRAGMA journal_mode=WAL");
@@ -302,6 +302,22 @@ function initSchema(db, fileBacked) {
302
302
  created_at TEXT NOT NULL DEFAULT '',
303
303
  FOREIGN KEY (milestone_id) REFERENCES milestones(id)
304
304
  )
305
+ `);
306
+ db.exec(`
307
+ CREATE TABLE IF NOT EXISTS quality_gates (
308
+ milestone_id TEXT NOT NULL,
309
+ slice_id TEXT NOT NULL,
310
+ gate_id TEXT NOT NULL,
311
+ scope TEXT NOT NULL DEFAULT 'slice',
312
+ task_id TEXT NOT NULL DEFAULT '',
313
+ status TEXT NOT NULL DEFAULT 'pending',
314
+ verdict TEXT NOT NULL DEFAULT '',
315
+ rationale TEXT NOT NULL DEFAULT '',
316
+ findings TEXT NOT NULL DEFAULT '',
317
+ evaluated_at TEXT DEFAULT NULL,
318
+ PRIMARY KEY (milestone_id, slice_id, gate_id, task_id),
319
+ FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id)
320
+ )
305
321
  `);
306
322
  db.exec("CREATE INDEX IF NOT EXISTS idx_memories_active ON memories(superseded_by)");
307
323
  db.exec("CREATE INDEX IF NOT EXISTS idx_replan_history_milestone ON replan_history(milestone_id, created_at)");
@@ -561,6 +577,28 @@ function migrateSchema(db) {
561
577
  ":applied_at": new Date().toISOString(),
562
578
  });
563
579
  }
580
+ if (currentVersion < 12) {
581
+ db.exec(`
582
+ CREATE TABLE IF NOT EXISTS quality_gates (
583
+ milestone_id TEXT NOT NULL,
584
+ slice_id TEXT NOT NULL,
585
+ gate_id TEXT NOT NULL,
586
+ scope TEXT NOT NULL DEFAULT 'slice',
587
+ task_id TEXT DEFAULT NULL,
588
+ status TEXT NOT NULL DEFAULT 'pending',
589
+ verdict TEXT NOT NULL DEFAULT '',
590
+ rationale TEXT NOT NULL DEFAULT '',
591
+ findings TEXT NOT NULL DEFAULT '',
592
+ evaluated_at TEXT DEFAULT NULL,
593
+ PRIMARY KEY (milestone_id, slice_id, gate_id, COALESCE(task_id, '')),
594
+ FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id)
595
+ )
596
+ `);
597
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
598
+ ":version": 12,
599
+ ":applied_at": new Date().toISOString(),
600
+ });
601
+ }
564
602
  db.exec("COMMIT");
565
603
  }
566
604
  catch (err) {
@@ -1396,3 +1434,88 @@ export function getAssessment(path) {
1396
1434
  const row = currentDb.prepare(`SELECT * FROM assessments WHERE path = :path`).get({ ":path": path });
1397
1435
  return row ?? null;
1398
1436
  }
1437
+ // ─── Quality Gates ───────────────────────────────────────────────────────
1438
+ function rowToGate(row) {
1439
+ return {
1440
+ milestone_id: row["milestone_id"],
1441
+ slice_id: row["slice_id"],
1442
+ gate_id: row["gate_id"],
1443
+ scope: row["scope"],
1444
+ task_id: row["task_id"] ?? "",
1445
+ status: row["status"],
1446
+ verdict: row["verdict"] || "",
1447
+ rationale: row["rationale"] || "",
1448
+ findings: row["findings"] || "",
1449
+ evaluated_at: row["evaluated_at"] ?? null,
1450
+ };
1451
+ }
1452
+ export function insertGateRow(g) {
1453
+ if (!currentDb)
1454
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1455
+ currentDb.prepare(`INSERT OR IGNORE INTO quality_gates (milestone_id, slice_id, gate_id, scope, task_id, status)
1456
+ VALUES (:mid, :sid, :gid, :scope, :tid, :status)`).run({
1457
+ ":mid": g.milestoneId,
1458
+ ":sid": g.sliceId,
1459
+ ":gid": g.gateId,
1460
+ ":scope": g.scope,
1461
+ ":tid": g.taskId ?? "",
1462
+ ":status": g.status ?? "pending",
1463
+ });
1464
+ }
1465
+ export function saveGateResult(g) {
1466
+ if (!currentDb)
1467
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1468
+ currentDb.prepare(`UPDATE quality_gates
1469
+ SET status = 'complete', verdict = :verdict, rationale = :rationale,
1470
+ findings = :findings, evaluated_at = :evaluated_at
1471
+ WHERE milestone_id = :mid AND slice_id = :sid AND gate_id = :gid
1472
+ AND task_id = :tid`).run({
1473
+ ":mid": g.milestoneId,
1474
+ ":sid": g.sliceId,
1475
+ ":gid": g.gateId,
1476
+ ":tid": g.taskId ?? "",
1477
+ ":verdict": g.verdict,
1478
+ ":rationale": g.rationale,
1479
+ ":findings": g.findings,
1480
+ ":evaluated_at": new Date().toISOString(),
1481
+ });
1482
+ }
1483
+ export function getPendingGates(milestoneId, sliceId, scope) {
1484
+ if (!currentDb)
1485
+ return [];
1486
+ const sql = scope
1487
+ ? `SELECT * FROM quality_gates WHERE milestone_id = :mid AND slice_id = :sid AND scope = :scope AND status = 'pending'`
1488
+ : `SELECT * FROM quality_gates WHERE milestone_id = :mid AND slice_id = :sid AND status = 'pending'`;
1489
+ const params = { ":mid": milestoneId, ":sid": sliceId };
1490
+ if (scope)
1491
+ params[":scope"] = scope;
1492
+ return currentDb.prepare(sql).all(params).map(rowToGate);
1493
+ }
1494
+ export function getGateResults(milestoneId, sliceId, scope) {
1495
+ if (!currentDb)
1496
+ return [];
1497
+ const sql = scope
1498
+ ? `SELECT * FROM quality_gates WHERE milestone_id = :mid AND slice_id = :sid AND scope = :scope`
1499
+ : `SELECT * FROM quality_gates WHERE milestone_id = :mid AND slice_id = :sid`;
1500
+ const params = { ":mid": milestoneId, ":sid": sliceId };
1501
+ if (scope)
1502
+ params[":scope"] = scope;
1503
+ return currentDb.prepare(sql).all(params).map(rowToGate);
1504
+ }
1505
+ export function markAllGatesOmitted(milestoneId, sliceId) {
1506
+ if (!currentDb)
1507
+ return;
1508
+ currentDb.prepare(`UPDATE quality_gates SET status = 'omitted', verdict = 'omitted', evaluated_at = :now
1509
+ WHERE milestone_id = :mid AND slice_id = :sid AND status = 'pending'`).run({
1510
+ ":mid": milestoneId,
1511
+ ":sid": sliceId,
1512
+ ":now": new Date().toISOString(),
1513
+ });
1514
+ }
1515
+ export function getPendingSliceGateCount(milestoneId, sliceId) {
1516
+ if (!currentDb)
1517
+ return 0;
1518
+ const row = currentDb.prepare(`SELECT COUNT(*) as cnt FROM quality_gates
1519
+ WHERE milestone_id = :mid AND slice_id = :sid AND scope = 'slice' AND status = 'pending'`).get({ ":mid": milestoneId, ":sid": sliceId });
1520
+ return row ? row["cnt"] : 0;
1521
+ }
@@ -186,11 +186,20 @@ export async function buildExistingMilestonesContext(basePath, milestoneIds, sta
186
186
  sections.push(`### Decisions Register\nSource: \`${relGsdRootFile("DECISIONS")}\`\n\n${decisionsContent.trim()}`);
187
187
  }
188
188
  }
189
- // For each milestone, include context and status
189
+ // For each milestone, include context and status.
190
+ // Completed milestones get a compact summary line only — loading their full
191
+ // CONTEXT.md + SUMMARY.md files is expensive and triggers 429 rate limits on
192
+ // projects with many completed milestones (#2379).
190
193
  for (const mid of milestoneIds) {
191
194
  const registryEntry = state.registry.find(m => m.id === mid);
192
195
  const status = registryEntry?.status ?? "unknown";
193
196
  const title = registryEntry?.title ?? mid;
197
+ // Completed milestones: emit a one-liner — the LLM only needs to know
198
+ // they exist for dedup/dependency purposes, not their full content.
199
+ if (status === "complete") {
200
+ sections.push(`### ${mid}: ${title}\n**Status:** complete`);
201
+ continue;
202
+ }
194
203
  const parts = [];
195
204
  parts.push(`### ${mid}: ${title}\n**Status:** ${status}`);
196
205
  // Include context file — this is the primary content for understanding scope
@@ -211,16 +220,6 @@ export async function buildExistingMilestonesContext(basePath, milestoneIds, sta
211
220
  }
212
221
  }
213
222
  }
214
- // For completed milestones, include the summary if it exists
215
- if (status === "complete") {
216
- const summaryFile = resolveMilestoneFile(basePath, mid, "SUMMARY");
217
- if (summaryFile) {
218
- const content = await loadFile(summaryFile);
219
- if (content) {
220
- parts.push(`\n**Summary:**\n${content.trim()}`);
221
- }
222
- }
223
- }
224
223
  // For active/pending/parked milestones, include the roadmap if it exists
225
224
  // (shows what's planned but not yet built)
226
225
  if (status === "active" || status === "pending" || status === "parked") {
@@ -10,7 +10,7 @@
10
10
  import { readFileSync, existsSync, mkdirSync } from "node:fs";
11
11
  import { join, relative } from "node:path";
12
12
  import { createRequire } from "node:module";
13
- import { getAllMilestones, getMilestone, getMilestoneSlices, getSliceTasks, getTask, getSlice, getArtifact, insertArtifact, } from "./gsd-db.js";
13
+ import { getAllMilestones, getMilestone, getMilestoneSlices, getSliceTasks, getTask, getSlice, getArtifact, insertArtifact, getGateResults, } from "./gsd-db.js";
14
14
  import { resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveTasksDir, gsdRoot, buildTaskFileName, buildSliceFileName, } from "./paths.js";
15
15
  import { saveFile, clearParseCache } from "./files.js";
16
16
  import { invalidateStateCache } from "./state.js";
@@ -127,7 +127,7 @@ function renderRoadmapMarkdown(milestone, slices) {
127
127
  }
128
128
  return `${lines.join("\n").trimEnd()}\n`;
129
129
  }
130
- function renderTaskPlanMarkdown(task) {
130
+ function renderTaskPlanMarkdown(task, taskGates = []) {
131
131
  const estimatedSteps = Math.max(1, task.description.trim().split(/\n+/).filter(Boolean).length || 1);
132
132
  const estimatedFiles = task.files.length > 0
133
133
  ? task.files.length
@@ -186,9 +186,20 @@ function renderTaskPlanMarkdown(task) {
186
186
  lines.push(task.observability_impact.trim());
187
187
  lines.push("");
188
188
  }
189
+ // ── Quality Gate Sections (Q5/Q6/Q7) ──────────────────────────────────
190
+ const gateLabels = { Q5: "Failure Modes", Q6: "Load Profile", Q7: "Negative Tests" };
191
+ for (const [gid, label] of Object.entries(gateLabels)) {
192
+ const gate = taskGates.find(g => g.gate_id === gid && g.status === "complete");
193
+ if (gate && gate.verdict !== "omitted") {
194
+ lines.push(`## ${label}`);
195
+ lines.push("");
196
+ lines.push(gate.findings.trim() || `- **Verdict:** ${gate.verdict}\n- **Rationale:** ${gate.rationale}`);
197
+ lines.push("");
198
+ }
199
+ }
189
200
  return `${lines.join("\n").trimEnd()}\n`;
190
201
  }
191
- function renderSlicePlanMarkdown(slice, tasks) {
202
+ function renderSlicePlanMarkdown(slice, tasks, gates = []) {
192
203
  const lines = [];
193
204
  lines.push(`# ${slice.id}: ${slice.title || slice.id}`);
194
205
  lines.push("");
@@ -206,6 +217,21 @@ function renderSlicePlanMarkdown(slice, tasks) {
206
217
  lines.push("- Complete the planned slice outcomes.");
207
218
  }
208
219
  lines.push("");
220
+ // ── Quality Gate Sections (Q3/Q4) ────────────────────────────────────
221
+ const q3 = gates.find(g => g.gate_id === "Q3" && g.status === "complete");
222
+ if (q3 && q3.verdict !== "omitted") {
223
+ lines.push("## Threat Surface");
224
+ lines.push("");
225
+ lines.push(q3.findings.trim() || `- **Verdict:** ${q3.verdict}\n- **Rationale:** ${q3.rationale}`);
226
+ lines.push("");
227
+ }
228
+ const q4 = gates.find(g => g.gate_id === "Q4" && g.status === "complete");
229
+ if (q4 && q4.verdict !== "omitted") {
230
+ lines.push("## Requirement Impact");
231
+ lines.push("");
232
+ lines.push(q4.findings.trim() || `- **Verdict:** ${q4.verdict}\n- **Rationale:** ${q4.rationale}`);
233
+ lines.push("");
234
+ }
209
235
  if (slice.proof_level.trim()) {
210
236
  lines.push("## Proof Level");
211
237
  lines.push("");
@@ -275,7 +301,8 @@ export async function renderPlanFromDb(basePath, milestoneId, sliceId) {
275
301
  const absPath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN")
276
302
  ?? join(slicePath, `${sliceId}-PLAN.md`);
277
303
  const artifactPath = toArtifactPath(absPath, basePath);
278
- const content = renderSlicePlanMarkdown(slice, tasks);
304
+ const sliceGates = getGateResults(milestoneId, sliceId, "slice");
305
+ const content = renderSlicePlanMarkdown(slice, tasks, sliceGates);
279
306
  await writeAndStore(absPath, artifactPath, content, {
280
307
  artifact_type: "PLAN",
281
308
  milestone_id: milestoneId,
@@ -298,7 +325,8 @@ export async function renderTaskPlanFromDb(basePath, milestoneId, sliceId, taskI
298
325
  mkdirSync(tasksDir, { recursive: true });
299
326
  const absPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
300
327
  const artifactPath = toArtifactPath(absPath, basePath);
301
- const content = task.full_plan_md.trim() ? task.full_plan_md : renderTaskPlanMarkdown(task);
328
+ const taskGates = getGateResults(milestoneId, sliceId, "task").filter(g => g.task_id === taskId);
329
+ const content = task.full_plan_md.trim() ? task.full_plan_md : renderTaskPlanMarkdown(task, taskGates);
302
330
  await writeAndStore(absPath, artifactPath, content, {
303
331
  artifact_type: "PLAN",
304
332
  milestone_id: milestoneId,
@@ -65,6 +65,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
65
65
  "context_selection",
66
66
  "widget_mode",
67
67
  "reactive_execution",
68
+ "gate_evaluation",
68
69
  "github",
69
70
  "service_tier",
70
71
  "forensics_dedup",
@@ -73,7 +74,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
73
74
  /** Canonical list of all dispatch unit types. */
74
75
  export const KNOWN_UNIT_TYPES = [
75
76
  "research-milestone", "plan-milestone", "research-slice", "plan-slice",
76
- "execute-task", "reactive-execute", "complete-slice", "replan-slice", "reassess-roadmap",
77
+ "execute-task", "reactive-execute", "gate-evaluate", "complete-slice", "replan-slice", "reassess-roadmap",
77
78
  "run-uat", "complete-milestone",
78
79
  ];
79
80
  export const SKILL_ACTIONS = new Set(["use", "prefer", "avoid"]);
@@ -542,6 +542,45 @@ export function validatePreferences(preferences) {
542
542
  errors.push("reactive_execution must be an object");
543
543
  }
544
544
  }
545
+ // ─── Gate Evaluation ─────────────────────────────────────────────────────
546
+ if (preferences.gate_evaluation !== undefined) {
547
+ if (typeof preferences.gate_evaluation === "object" && preferences.gate_evaluation !== null) {
548
+ const ge = preferences.gate_evaluation;
549
+ const validGe = {};
550
+ if (ge.enabled !== undefined) {
551
+ if (typeof ge.enabled === "boolean")
552
+ validGe.enabled = ge.enabled;
553
+ else
554
+ errors.push("gate_evaluation.enabled must be a boolean");
555
+ }
556
+ if (ge.slice_gates !== undefined) {
557
+ if (Array.isArray(ge.slice_gates) && ge.slice_gates.every((g) => typeof g === "string")) {
558
+ validGe.slice_gates = ge.slice_gates;
559
+ }
560
+ else {
561
+ errors.push("gate_evaluation.slice_gates must be an array of strings");
562
+ }
563
+ }
564
+ if (ge.task_gates !== undefined) {
565
+ if (typeof ge.task_gates === "boolean")
566
+ validGe.task_gates = ge.task_gates;
567
+ else
568
+ errors.push("gate_evaluation.task_gates must be a boolean");
569
+ }
570
+ const knownGeKeys = new Set(["enabled", "slice_gates", "task_gates"]);
571
+ for (const key of Object.keys(ge)) {
572
+ if (!knownGeKeys.has(key)) {
573
+ warnings.push(`unknown gate_evaluation key "${key}" — ignored`);
574
+ }
575
+ }
576
+ if (Object.keys(validGe).length > 0) {
577
+ validated.gate_evaluation = validGe;
578
+ }
579
+ }
580
+ else {
581
+ errors.push("gate_evaluation must be an object");
582
+ }
583
+ }
545
584
  // ─── Verification Preferences ───────────────────────────────────────────
546
585
  if (preferences.verification_commands !== undefined) {
547
586
  if (Array.isArray(preferences.verification_commands)) {
@@ -20,11 +20,13 @@ Then:
20
20
  3. **Verify code changes exist.** Run `git diff --stat HEAD $(git merge-base HEAD main) -- ':!.gsd/'` (or the equivalent for the integration branch). If no non-`.gsd/` files appear in the diff, the milestone produced only planning artifacts and no actual code. Record this as a **verification failure**.
21
21
  4. Verify each **success criterion** from the milestone definition in `{{roadmapPath}}`. For each criterion, confirm it was met with specific evidence from slice summaries, test results, or observable behavior. Record any criterion that was NOT met as a **verification failure**.
22
22
  5. Verify the milestone's **definition of done** — all slices are `[x]`, all slice summaries exist, and any cross-slice integration points work correctly. Record any unmet items as a **verification failure**.
23
- 6. Validate **requirement status transitions**. For each requirement that changed status during this milestone, confirm the transition is supported by evidence. Requirements can move between Active, Validated, Deferred, Blocked, or Out of Scope — but only with proof.
23
+ 6. If the roadmap includes a **Horizontal Checklist**, verify each item was addressed during the milestone. Note unchecked items in the milestone summary.
24
+ 7. Fill the **Decision Re-evaluation** table in the milestone summary. For each key decision from `.gsd/DECISIONS.md` made during this milestone, evaluate whether it is still valid given what was actually built. Flag decisions that should be revisited next milestone.
25
+ 8. Validate **requirement status transitions**. For each requirement that changed status during this milestone, confirm the transition is supported by evidence. Requirements can move between Active, Validated, Deferred, Blocked, or Out of Scope — but only with proof.
24
26
 
25
27
  ### Verification Gate — STOP if verification failed
26
28
 
27
- **If ANY verification failure was recorded in steps 3, 4, or 5, you MUST follow the failure path below. Do NOT proceed to step 7.**
29
+ **If ANY verification failure was recorded in steps 3, 4, or 5, you MUST follow the failure path below. Do NOT proceed to step 9.**
28
30
 
29
31
  **Failure path** (verification failed):
30
32
  - Do NOT call `gsd_complete_milestone` — the milestone must not be marked as complete.
@@ -33,13 +35,30 @@ Then:
33
35
  - Write a clear summary of what failed and why to help the next attempt.
34
36
  - Say: "Milestone {{milestoneId}} verification FAILED — not complete." and stop.
35
37
 
36
- **Success path** (all verifications passed — continue with steps 711):
38
+ **Success path** (all verifications passed — continue with steps 913):
37
39
 
38
- 7. **Persist completion through `gsd_complete_milestone`.** Call it with: `milestoneId`, `title`, `oneLiner`, `narrative`, `successCriteriaResults`, `definitionOfDoneResults`, `requirementOutcomes`, `keyDecisions`, `keyFiles`, `lessonsLearned`, `followUps`, `deviations`, `verificationPassed: true`. The tool updates the milestone status in the DB, renders `{{milestoneSummaryPath}}`, and validates all slices are complete before proceeding.
39
- 8. For each requirement whose status changed in step 6, call `gsd_requirement_update` with the requirement ID and updated `status` and `validation` fields — the tool regenerates `.gsd/REQUIREMENTS.md` automatically.
40
- 9. Update `.gsd/PROJECT.md` to reflect milestone completion and current project state.
41
- 10. Review all slice summaries for cross-cutting lessons, patterns, or gotchas that emerged during this milestone. Append any non-obvious, reusable insights to `.gsd/KNOWLEDGE.md`.
42
- 11. Do not commit manually the system auto-commits your changes after this unit completes.
40
+ 9. **Persist completion through `gsd_complete_milestone`.** Call it with the parameters below. The tool updates the milestone status in the DB, renders `{{milestoneSummaryPath}}`, and validates all slices are complete before proceeding.
41
+
42
+ **Required parameters:**
43
+ - `milestoneId` (string) Milestone ID (e.g. M001)
44
+ - `title` (string)Milestone title
45
+ - `oneLiner` (string) — One-sentence summary of what the milestone achieved
46
+ - `narrative` (string) — Detailed narrative of what happened during the milestone
47
+ - `successCriteriaResults` (string) — Markdown detailing how each success criterion was met or not met
48
+ - `definitionOfDoneResults` (string) — Markdown detailing how each definition-of-done item was met
49
+ - `requirementOutcomes` (string) — Markdown detailing requirement status transitions with evidence
50
+ - `keyDecisions` (array of strings) — Key architectural/pattern decisions made during the milestone
51
+ - `keyFiles` (array of strings) — Key files created or modified during the milestone
52
+ - `lessonsLearned` (array of strings) — Lessons learned during the milestone
53
+ - `verificationPassed` (boolean) — Must be `true` — confirms that code change verification, success criteria, and definition of done checks all passed before completion
54
+
55
+ **Optional parameters:**
56
+ - `followUps` (string) — Follow-up items for future milestones
57
+ - `deviations` (string) — Deviations from the original plan
58
+ 10. For each requirement whose status changed in step 8, call `gsd_requirement_update` with the requirement ID and updated `status` and `validation` fields — the tool regenerates `.gsd/REQUIREMENTS.md` automatically.
59
+ 11. Update `.gsd/PROJECT.md` to reflect milestone completion and current project state.
60
+ 12. Review all slice summaries for cross-cutting lessons, patterns, or gotchas that emerged during this milestone. Append any non-obvious, reusable insights to `.gsd/KNOWLEDGE.md`.
61
+ 13. Do not commit manually — the system auto-commits your changes after this unit completes.
43
62
  - Say: "Milestone {{milestoneId}} complete."
44
63
 
45
64
  **Important:** Do NOT skip the code change verification, success criteria, or definition of done verification (steps 3-5). The milestone summary must reflect actual verified outcomes, not assumed success. Verification failures BLOCK completion — there is no override. The milestone stays in its current state until issues are resolved and verification is re-run.
@@ -23,14 +23,15 @@ Then:
23
23
  2. {{skillActivation}}
24
24
  3. Run all slice-level verification checks defined in the slice plan. All must pass before marking the slice done. If any fail, fix them first.
25
25
  4. If the slice plan includes observability/diagnostic surfaces, confirm they work. Skip this for simple slices that don't have observability sections.
26
- 5. If this slice produced evidence that a requirement changed status (Active Validated, Active Deferred, etc.), call `gsd_save_decision` with scope="requirement", decision="{requirement-id}", choice="{new-status}", rationale="{evidence}". Do NOT write `.gsd/REQUIREMENTS.md` directly the engine renders it from the database.
27
- 6. Write `{{sliceSummaryPath}}` (compress all task summaries).
28
- 7. Write `{{sliceUatPath}}` a concrete UAT script with real test cases derived from the slice plan and task summaries. Include preconditions, numbered steps with expected outcomes, and edge cases. This must NOT be a placeholder or generic template — tailor every test case to what this slice actually built.
29
- 8. Review task summaries for `key_decisions`. Append any significant decisions to `.gsd/DECISIONS.md` if missing.
30
- 9. Review task summaries for patterns, gotchas, or non-obvious lessons learned. If any would save future agents from repeating investigation or hitting the same issues, append them to `.gsd/KNOWLEDGE.md`. Only add entries that are genuinely useful — don't pad with obvious observations.
31
- 10. Call `gsd_complete_slice` with milestone_id, slice_id, the slice summary, and the UAT result. Do NOT manually mark the roadmap checkbox the tool writes to the DB and renders the ROADMAP.md projection automatically.
32
- 11. Do not run git commands — the system commits your changes and handles any merge after this unit succeeds.
33
- 12. Update `.gsd/PROJECT.md` if it existsrefresh current state if needed.
26
+ 5. If the slice involved runtime behavior, fill the **Operational Readiness** section (Q8) in the slice summary: health signal, failure signal, recovery procedure, and monitoring gaps. Omit entirely for simple slices with no runtime concerns.
27
+ 6. If this slice produced evidence that a requirement changed status (Active → Validated, Active → Deferred, etc.), call `gsd_save_decision` with scope="requirement", decision="{requirement-id}", choice="{new-status}", rationale="{evidence}". Do NOT write `.gsd/REQUIREMENTS.md` directly the engine renders it from the database.
28
+ 7. Write `{{sliceSummaryPath}}` (compress all task summaries).
29
+ 8. Write `{{sliceUatPath}}` — a concrete UAT script with real test cases derived from the slice plan and task summaries. Include preconditions, numbered steps with expected outcomes, and edge cases. This must NOT be a placeholder or generic template — tailor every test case to what this slice actually built.
30
+ 9. Review task summaries for `key_decisions`. Append any significant decisions to `.gsd/DECISIONS.md` if missing.
31
+ 10. Review task summaries for patterns, gotchas, or non-obvious lessons learned. If any would save future agents from repeating investigation or hitting the same issues, append them to `.gsd/KNOWLEDGE.md`. Only add entries that are genuinely useful — don't pad with obvious observations.
32
+ 11. Call `gsd_complete_slice` with milestone_id, slice_id, the slice summary, and the UAT result. Do NOT manually mark the roadmap checkbox — the tool writes to the DB and renders the ROADMAP.md projection automatically.
33
+ 12. Do not run git commandsthe system commits your changes and handles any merge after this unit succeeds.
34
+ 13. Update `.gsd/PROJECT.md` if it exists — refresh current state if needed.
34
35
 
35
36
  **You MUST call `gsd_complete_slice` with the slice summary and UAT content before finishing. The tool persists to both DB and disk and renders `{{sliceSummaryPath}}` and `{{sliceUatPath}}` automatically.**
36
37