gsd-pi 2.66.1 → 2.67.0-dev.43b0159

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 (397) hide show
  1. package/dist/claude-cli-check.d.ts +8 -0
  2. package/dist/claude-cli-check.js +36 -0
  3. package/dist/cli.js +40 -0
  4. package/dist/onboarding.js +19 -2
  5. package/dist/resources/extensions/ask-user-questions.js +79 -11
  6. package/dist/resources/extensions/claude-code-cli/partial-builder.js +4 -3
  7. package/dist/resources/extensions/claude-code-cli/readiness.js +63 -12
  8. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +10 -3
  9. package/dist/resources/extensions/gsd/auto/loop.js +13 -1
  10. package/dist/resources/extensions/gsd/auto/phases.js +22 -3
  11. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
  12. package/dist/resources/extensions/gsd/auto/session.js +1 -1
  13. package/dist/resources/extensions/gsd/auto-dashboard.js +65 -15
  14. package/dist/resources/extensions/gsd/auto-dispatch.js +30 -28
  15. package/dist/resources/extensions/gsd/auto-model-selection.js +12 -3
  16. package/dist/resources/extensions/gsd/auto-prompts.js +173 -25
  17. package/dist/resources/extensions/gsd/auto-recovery.js +11 -12
  18. package/dist/resources/extensions/gsd/auto.js +13 -1
  19. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -1
  20. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +18 -6
  21. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -0
  22. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +59 -5
  23. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +8 -5
  24. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +186 -14
  25. package/dist/resources/extensions/gsd/codebase-generator.js +4 -0
  26. package/dist/resources/extensions/gsd/commands/catalog.js +2 -1
  27. package/dist/resources/extensions/gsd/commands/dispatcher.js +1 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/core.js +94 -4
  29. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +49 -9
  30. package/dist/resources/extensions/gsd/context-store.js +134 -2
  31. package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -1
  32. package/dist/resources/extensions/gsd/detection.js +6 -0
  33. package/dist/resources/extensions/gsd/files.js +19 -2
  34. package/dist/resources/extensions/gsd/guided-flow.js +12 -8
  35. package/dist/resources/extensions/gsd/index.js +1 -1
  36. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +2 -0
  37. package/dist/resources/extensions/gsd/parsers-legacy.js +3 -1
  38. package/dist/resources/extensions/gsd/preferences.js +6 -1
  39. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  40. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  41. package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +7 -7
  42. package/dist/resources/extensions/gsd/prompts/discuss.md +3 -3
  43. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -3
  44. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -3
  45. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
  46. package/dist/resources/extensions/gsd/prompts/rethink.md +6 -2
  47. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  48. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  49. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +11 -9
  50. package/dist/resources/extensions/gsd/prompts/worktree-merge.md +3 -1
  51. package/dist/resources/extensions/gsd/safety/file-change-validator.js +2 -1
  52. package/dist/resources/extensions/gsd/state.js +2 -1
  53. package/dist/resources/extensions/gsd/visualizer-overlay.js +27 -26
  54. package/dist/resources/extensions/gsd/workflow-reconcile.js +46 -7
  55. package/dist/resources/extensions/remote-questions/manager.js +8 -0
  56. package/dist/resources/extensions/shared/interview-ui.js +10 -0
  57. package/dist/web/standalone/.next/BUILD_ID +1 -1
  58. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  59. package/dist/web/standalone/.next/build-manifest.json +4 -4
  60. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  61. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  62. package/dist/web/standalone/.next/required-server-files.json +3 -3
  63. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  64. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  65. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  66. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  74. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  76. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  77. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  78. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  80. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  90. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  102. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  122. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  132. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  138. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  152. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  154. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  156. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  158. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/index.html +1 -1
  168. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  169. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  170. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  171. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  172. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  173. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  174. package/dist/web/standalone/.next/server/app/page.js +2 -2
  175. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  177. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  178. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  179. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/middleware.js +2 -2
  182. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  184. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  185. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  186. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  187. package/dist/web/standalone/.next/static/chunks/{6502.8874bcae249c02e1.js → 6502.b804e48b7919f55e.js} +3 -3
  188. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  189. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  190. package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
  191. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  192. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  193. package/dist/web/standalone/.next/static/chunks/{webpack-9fed74684e1c5bb1.js → webpack-65f0501b197d1c49.js} +1 -1
  194. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  195. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  196. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  197. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  198. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  199. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  200. package/dist/web/standalone/server.js +1 -1
  201. package/package.json +1 -1
  202. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  203. package/packages/pi-ai/dist/providers/anthropic-shared.js +4 -3
  204. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  205. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  206. package/packages/pi-ai/dist/utils/json-parse.js +11 -1
  207. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  208. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  209. package/packages/pi-ai/dist/utils/repair-tool-json.js +60 -1
  210. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  211. package/packages/pi-ai/dist/utils/tests/json-parse.test.d.ts +2 -0
  212. package/packages/pi-ai/dist/utils/tests/json-parse.test.d.ts.map +1 -0
  213. package/packages/pi-ai/dist/utils/tests/json-parse.test.js +14 -0
  214. package/packages/pi-ai/dist/utils/tests/json-parse.test.js.map +1 -0
  215. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +10 -0
  216. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  217. package/packages/pi-ai/src/providers/anthropic-shared.ts +4 -3
  218. package/packages/pi-ai/src/utils/json-parse.ts +11 -1
  219. package/packages/pi-ai/src/utils/repair-tool-json.ts +69 -1
  220. package/packages/pi-ai/src/utils/tests/json-parse.test.ts +17 -0
  221. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +13 -0
  222. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +3 -0
  223. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -0
  225. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  226. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +16 -0
  227. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/retry-handler.js +58 -1
  229. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +58 -0
  231. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/sdk.d.ts +3 -0
  233. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/sdk.js +1 -0
  235. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  236. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.d.ts +2 -0
  237. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.d.ts.map +1 -0
  238. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +17 -0
  239. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -0
  240. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  241. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +2 -1
  242. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  243. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +1 -0
  244. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +9 -2
  246. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  248. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +2 -1
  249. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  251. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -1
  252. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +2 -2
  254. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  255. package/packages/pi-coding-agent/package.json +1 -1
  256. package/packages/pi-coding-agent/src/core/agent-session.ts +4 -0
  257. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +69 -0
  258. package/packages/pi-coding-agent/src/core/retry-handler.ts +66 -1
  259. package/packages/pi-coding-agent/src/core/sdk.ts +5 -0
  260. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +18 -0
  261. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +2 -1
  262. package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +11 -2
  263. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +2 -1
  264. package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -1
  265. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +2 -2
  266. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +13 -0
  267. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  268. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.d.ts +2 -0
  269. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.d.ts.map +1 -0
  270. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +35 -0
  271. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -0
  272. package/packages/pi-tui/dist/__tests__/tui.test.d.ts +2 -0
  273. package/packages/pi-tui/dist/__tests__/tui.test.d.ts.map +1 -0
  274. package/packages/pi-tui/dist/__tests__/tui.test.js +43 -0
  275. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -0
  276. package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
  277. package/packages/pi-tui/dist/autocomplete.js +9 -7
  278. package/packages/pi-tui/dist/autocomplete.js.map +1 -1
  279. package/packages/pi-tui/dist/components/__tests__/editor.test.d.ts +2 -0
  280. package/packages/pi-tui/dist/components/__tests__/editor.test.d.ts.map +1 -0
  281. package/packages/pi-tui/dist/components/__tests__/editor.test.js +54 -0
  282. package/packages/pi-tui/dist/components/__tests__/editor.test.js.map +1 -0
  283. package/packages/pi-tui/dist/components/editor.d.ts +3 -1
  284. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  285. package/packages/pi-tui/dist/components/editor.js +14 -3
  286. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  287. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  288. package/packages/pi-tui/dist/stdin-buffer.js +6 -0
  289. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  290. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  291. package/packages/pi-tui/dist/tui.js +8 -0
  292. package/packages/pi-tui/dist/tui.js.map +1 -1
  293. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +15 -0
  294. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +43 -0
  295. package/packages/pi-tui/src/__tests__/tui.test.ts +50 -0
  296. package/packages/pi-tui/src/autocomplete.ts +9 -7
  297. package/packages/pi-tui/src/components/__tests__/editor.test.ts +64 -0
  298. package/packages/pi-tui/src/components/editor.ts +14 -3
  299. package/packages/pi-tui/src/stdin-buffer.ts +7 -0
  300. package/packages/pi-tui/src/tui.ts +9 -0
  301. package/pkg/package.json +1 -1
  302. package/src/resources/extensions/ask-user-questions.ts +103 -11
  303. package/src/resources/extensions/claude-code-cli/partial-builder.ts +4 -3
  304. package/src/resources/extensions/claude-code-cli/readiness.ts +67 -12
  305. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +12 -3
  306. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +17 -0
  307. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +18 -0
  308. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -1
  309. package/src/resources/extensions/gsd/auto/loop.ts +14 -1
  310. package/src/resources/extensions/gsd/auto/phases.ts +27 -4
  311. package/src/resources/extensions/gsd/auto/run-unit.ts +14 -2
  312. package/src/resources/extensions/gsd/auto/session.ts +1 -1
  313. package/src/resources/extensions/gsd/auto-dashboard.ts +76 -16
  314. package/src/resources/extensions/gsd/auto-dispatch.ts +36 -35
  315. package/src/resources/extensions/gsd/auto-model-selection.ts +12 -3
  316. package/src/resources/extensions/gsd/auto-prompts.ts +195 -25
  317. package/src/resources/extensions/gsd/auto-recovery.ts +15 -15
  318. package/src/resources/extensions/gsd/auto.ts +12 -1
  319. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -1
  320. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +27 -6
  321. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -0
  322. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +67 -6
  323. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +11 -8
  324. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +209 -16
  325. package/src/resources/extensions/gsd/codebase-generator.ts +4 -0
  326. package/src/resources/extensions/gsd/commands/catalog.ts +2 -1
  327. package/src/resources/extensions/gsd/commands/dispatcher.ts +1 -2
  328. package/src/resources/extensions/gsd/commands/handlers/core.ts +113 -8
  329. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +49 -11
  330. package/src/resources/extensions/gsd/context-store.ts +167 -2
  331. package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -1
  332. package/src/resources/extensions/gsd/detection.ts +6 -0
  333. package/src/resources/extensions/gsd/files.ts +21 -2
  334. package/src/resources/extensions/gsd/guided-flow.ts +15 -8
  335. package/src/resources/extensions/gsd/index.ts +6 -0
  336. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +2 -0
  337. package/src/resources/extensions/gsd/parsers-legacy.ts +3 -1
  338. package/src/resources/extensions/gsd/preferences.ts +6 -1
  339. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  340. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  341. package/src/resources/extensions/gsd/prompts/discuss-prepared.md +7 -7
  342. package/src/resources/extensions/gsd/prompts/discuss.md +3 -3
  343. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -3
  344. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -3
  345. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
  346. package/src/resources/extensions/gsd/prompts/rethink.md +6 -2
  347. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  348. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  349. package/src/resources/extensions/gsd/prompts/validate-milestone.md +11 -9
  350. package/src/resources/extensions/gsd/prompts/worktree-merge.md +3 -1
  351. package/src/resources/extensions/gsd/safety/file-change-validator.ts +4 -1
  352. package/src/resources/extensions/gsd/state.ts +2 -1
  353. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +52 -1
  354. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +50 -2
  355. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +21 -7
  356. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +48 -0
  357. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  358. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +12 -0
  359. package/src/resources/extensions/gsd/tests/context-store.test.ts +176 -0
  360. package/src/resources/extensions/gsd/tests/core-overlay-fallback.test.ts +76 -0
  361. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +7 -1
  362. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +31 -0
  363. package/src/resources/extensions/gsd/tests/decision-scope-cascade.test.ts +370 -0
  364. package/src/resources/extensions/gsd/tests/detection.test.ts +37 -0
  365. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +50 -0
  366. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +35 -0
  367. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +34 -0
  368. package/src/resources/extensions/gsd/tests/health-widget.test.ts +45 -0
  369. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +53 -13
  370. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -2
  371. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +3 -3
  372. package/src/resources/extensions/gsd/tests/measurement.test.ts +531 -0
  373. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +3 -4
  374. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +21 -0
  375. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +71 -2
  376. package/src/resources/extensions/gsd/tests/parsers.test.ts +25 -0
  377. package/src/resources/extensions/gsd/tests/preferences.test.ts +37 -0
  378. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +26 -4
  379. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +60 -0
  380. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +9 -0
  381. package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +19 -0
  382. package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +73 -0
  383. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +98 -0
  384. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +2 -2
  385. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +26 -0
  386. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +59 -0
  387. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +91 -0
  388. package/src/resources/extensions/gsd/tests/write-gate.test.ts +210 -35
  389. package/src/resources/extensions/gsd/visualizer-overlay.ts +31 -27
  390. package/src/resources/extensions/gsd/workflow-reconcile.ts +59 -8
  391. package/src/resources/extensions/remote-questions/manager.ts +9 -0
  392. package/src/resources/extensions/shared/interview-ui.ts +13 -0
  393. package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
  394. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  395. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  396. /package/dist/web/standalone/.next/static/{y5P0reMrCMs-4-gswdawm → CrKrzIIxk55witDF1eS0L}/_buildManifest.js +0 -0
  397. /package/dist/web/standalone/.next/static/{y5P0reMrCMs-4-gswdawm → CrKrzIIxk55witDF1eS0L}/_ssgManifest.js +0 -0
@@ -15,6 +15,7 @@ export interface DecisionQueryOpts {
15
15
  }
16
16
 
17
17
  export interface RequirementQueryOpts {
18
+ milestoneId?: string;
18
19
  sliceId?: string;
19
20
  status?: string;
20
21
  }
@@ -67,7 +68,8 @@ export function queryDecisions(opts?: DecisionQueryOpts): Decision[] {
67
68
 
68
69
  /**
69
70
  * Query active (non-superseded) requirements with optional filters.
70
- * - sliceId: filters where primary_owner LIKE '%sliceId%' OR supporting_slices LIKE '%sliceId%'
71
+ * - milestoneId: combined with sliceId for precise filtering (e.g. %M005/S01%)
72
+ * - sliceId: filters where primary_owner LIKE '%pattern%' OR supporting_slices LIKE '%pattern%'
71
73
  * - status: filters where status = :status (exact match)
72
74
  *
73
75
  * Returns [] if DB is not available. Never throws.
@@ -81,9 +83,19 @@ export function queryRequirements(opts?: RequirementQueryOpts): Requirement[] {
81
83
  const clauses: string[] = ['superseded_by IS NULL'];
82
84
  const params: Record<string, unknown> = {};
83
85
 
84
- if (opts?.sliceId) {
86
+ // Combined milestone+slice filtering for precise scoping
87
+ if (opts?.milestoneId && opts?.sliceId) {
88
+ // Use combined pattern like %M005/S01% to avoid cross-milestone contamination
89
+ clauses.push('(primary_owner LIKE :combined_pattern OR supporting_slices LIKE :combined_pattern)');
90
+ params[':combined_pattern'] = `%${opts.milestoneId}/${opts.sliceId}%`;
91
+ } else if (opts?.sliceId) {
92
+ // Slice-only filtering (legacy behavior)
85
93
  clauses.push('(primary_owner LIKE :slice_pattern OR supporting_slices LIKE :slice_pattern)');
86
94
  params[':slice_pattern'] = `%${opts.sliceId}%`;
95
+ } else if (opts?.milestoneId) {
96
+ // Milestone-only filtering
97
+ clauses.push('(primary_owner LIKE :milestone_pattern OR supporting_slices LIKE :milestone_pattern)');
98
+ params[':milestone_pattern'] = `%${opts.milestoneId}%`;
87
99
  }
88
100
 
89
101
  if (opts?.status) {
@@ -194,3 +206,156 @@ export function queryArtifact(path: string): string | null {
194
206
  export function queryProject(): string | null {
195
207
  return queryArtifact('PROJECT.md');
196
208
  }
209
+
210
+ // ─── Knowledge Query ───────────────────────────────────────────────────────
211
+
212
+ /**
213
+ * Filter KNOWLEDGE.md sections by keyword matching.
214
+ * Uses H2 sections, matches keywords case-insensitively against:
215
+ * 1. Section header text
216
+ * 2. First paragraph of section content (up to first blank line or next heading)
217
+ *
218
+ * Per D020, returns empty string (not null) when no matches found.
219
+ * This signals "no relevant knowledge" vs "file not found".
220
+ *
221
+ * @param content - Full KNOWLEDGE.md content
222
+ * @param keywords - Keywords to match (case-insensitive)
223
+ * @returns Concatenated matching sections with H2 headers, or empty string
224
+ */
225
+ export async function queryKnowledge(content: string, keywords: string[]): Promise<string> {
226
+ if (!content || keywords.length === 0) return '';
227
+
228
+ // Lazy import to avoid circular dependency
229
+ const { extractAllSections } = await import('./files.js');
230
+
231
+ const sections = extractAllSections(content, 2);
232
+ if (sections.size === 0) return '';
233
+
234
+ // Normalize keywords for case-insensitive matching
235
+ const normalizedKeywords = keywords.map(k => k.toLowerCase());
236
+
237
+ const matchingSections: string[] = [];
238
+
239
+ for (const [header, body] of sections) {
240
+ // Extract first paragraph: everything up to first blank line or next heading
241
+ const firstParagraph = body.split(/\n\s*\n|\n#/)[0] || '';
242
+
243
+ // Check if any keyword matches header or first paragraph
244
+ const headerLower = header.toLowerCase();
245
+ const paragraphLower = firstParagraph.toLowerCase();
246
+
247
+ const matches = normalizedKeywords.some(kw =>
248
+ headerLower.includes(kw) || paragraphLower.includes(kw)
249
+ );
250
+
251
+ if (matches) {
252
+ matchingSections.push(`## ${header}\n\n${body}`);
253
+ }
254
+ }
255
+
256
+ return matchingSections.join('\n\n');
257
+ }
258
+
259
+ // ─── Roadmap Excerpt Formatter ─────────────────────────────────────────────
260
+
261
+ /**
262
+ * Format a minimal roadmap excerpt for prompt injection.
263
+ * Parses the slice table from roadmap content, extracts:
264
+ * 1. Header row + separator
265
+ * 2. Predecessor row (if sliceId depends on one via the Depends column)
266
+ * 3. Target slice row
267
+ * 4. Reference directive pointing to full roadmap path
268
+ *
269
+ * Per D021, this minimizes injected content while preserving dependency awareness.
270
+ * Returns empty string if sliceId is not found in the table.
271
+ * Never throws.
272
+ *
273
+ * @param roadmapContent - Full content of the M###-ROADMAP.md file
274
+ * @param sliceId - Target slice ID (e.g. 'S02')
275
+ * @param roadmapPath - Optional path for reference directive (defaults to generic)
276
+ */
277
+ export function formatRoadmapExcerpt(
278
+ roadmapContent: string,
279
+ sliceId: string,
280
+ roadmapPath = 'ROADMAP.md',
281
+ ): string {
282
+ if (!roadmapContent || !sliceId) return '';
283
+
284
+ const lines = roadmapContent.split('\n');
285
+
286
+ // Find the slice table header: | ID | Slice | ... (case insensitive)
287
+ let headerIndex = -1;
288
+ for (let i = 0; i < lines.length; i++) {
289
+ const line = lines[i];
290
+ if (line && /^\s*\|\s*ID\s*\|\s*Slice\s*\|/i.test(line)) {
291
+ headerIndex = i;
292
+ break;
293
+ }
294
+ }
295
+
296
+ if (headerIndex === -1) return '';
297
+
298
+ // The separator should be the next line (|---|---|...)
299
+ const separatorIndex = headerIndex + 1;
300
+ if (separatorIndex >= lines.length) return '';
301
+
302
+ const headerLine = lines[headerIndex];
303
+ const separatorLine = lines[separatorIndex];
304
+
305
+ // Validate separator line looks like |---|---|... (may include : for alignment)
306
+ if (!separatorLine || !/^\s*\|[\s:\-|]+\|/.test(separatorLine)) return '';
307
+
308
+ // Parse table rows after separator
309
+ interface SliceRow {
310
+ line: string;
311
+ id: string;
312
+ depends: string;
313
+ }
314
+
315
+ const sliceRows: SliceRow[] = [];
316
+ for (let i = separatorIndex + 1; i < lines.length; i++) {
317
+ const line = lines[i];
318
+ if (!line || !line.trim().startsWith('|')) break; // End of table
319
+
320
+ // Parse row: | ID | Slice | Risk | Depends | Done | After this |
321
+ const cells = line.split('|').map(c => c.trim());
322
+ // cells[0] is empty (before first |), cells[1] is ID, etc.
323
+ if (cells.length < 5) continue;
324
+
325
+ const id = cells[1] || '';
326
+ const depends = cells[4] || ''; // Depends column (0-indexed: empty, ID, Slice, Risk, Depends, ...)
327
+
328
+ sliceRows.push({ line, id, depends });
329
+ }
330
+
331
+ // Find target slice row
332
+ const targetRow = sliceRows.find(r => r.id === sliceId);
333
+ if (!targetRow) return '';
334
+
335
+ // Find predecessor if target depends on one
336
+ // Depends column may contain: '—', 'S01', 'S01, S02', etc.
337
+ let predecessorRow: SliceRow | undefined;
338
+ const dependsRaw = targetRow.depends;
339
+ if (dependsRaw && dependsRaw !== '—' && dependsRaw !== '-') {
340
+ // Extract first dependency (e.g. 'S01' from 'S01, S02')
341
+ const depMatch = dependsRaw.match(/S\d+/);
342
+ if (depMatch) {
343
+ predecessorRow = sliceRows.find(r => r.id === depMatch[0]);
344
+ }
345
+ }
346
+
347
+ // Build excerpt
348
+ const excerptLines: string[] = [headerLine!, separatorLine!];
349
+
350
+ if (predecessorRow) {
351
+ excerptLines.push(predecessorRow.line);
352
+ }
353
+
354
+ excerptLines.push(targetRow.line);
355
+
356
+ // Add reference directive
357
+ excerptLines.push('');
358
+ excerptLines.push(`> See full roadmap: ${roadmapPath}`);
359
+
360
+ return excerptLines.join('\n');
361
+ }
@@ -179,7 +179,9 @@ export class CustomWorkflowEngine implements WorkflowEngine {
179
179
  state: EngineState,
180
180
  completedStep: CompletedStep,
181
181
  ): Promise<ReconcileResult> {
182
- const graph = state.raw as WorkflowGraph;
182
+ // Re-read the graph from disk so we do not overwrite concurrent
183
+ // workflow edits with a stale in-memory snapshot from deriveState().
184
+ const graph = readGraph(this.runDir);
183
185
 
184
186
  // Extract stepId from "<workflowName>/<stepId>"
185
187
  const { milestone, slice, task } = parseUnitId(completedStep.unitId);
@@ -242,6 +242,12 @@ const TEST_MARKERS = [
242
242
  /** Directories skipped during bounded recursive project scans. */
243
243
  const RECURSIVE_SCAN_IGNORED_DIRS = new Set([
244
244
  ".git",
245
+ ".gsd",
246
+ ".planning",
247
+ ".plans",
248
+ ".claude",
249
+ ".cursor",
250
+ ".vscode",
245
251
  "node_modules",
246
252
  ".venv",
247
253
  "venv",
@@ -132,6 +132,25 @@ function escapeRegex(s: string): string {
132
132
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
133
133
  }
134
134
 
135
+ /**
136
+ * Normalize a task-plan file reference that may include inline description text
137
+ * after the path, for example:
138
+ * "docs/file.md — explanation"
139
+ * "docs/file.md - explanation"
140
+ */
141
+ export function normalizePlannedFileReference(value: string): string {
142
+ const trimmed = value.trim().replace(/`/g, "");
143
+ const match = /^(.*?)(?:\s+(?:—|-)\s+)(.+)$/.exec(trimmed);
144
+ if (!match) return trimmed;
145
+
146
+ const pathCandidate = match[1].trim();
147
+ if (pathCandidate.includes("/") || pathCandidate.includes("\\") || pathCandidate.includes(".")) {
148
+ return pathCandidate;
149
+ }
150
+
151
+ return trimmed;
152
+ }
153
+
135
154
  /** Parse bullet list items from a text block. */
136
155
  export function parseBullets(text: string): string[] {
137
156
  return text.split('\n')
@@ -622,11 +641,11 @@ export function parseTaskPlanIO(content: string): { inputFiles: string[]; output
622
641
  let match: RegExpExecArray | null;
623
642
  backtickPathRegex.lastIndex = 0;
624
643
  while ((match = backtickPathRegex.exec(trimmed)) !== null) {
625
- const candidate = match[1];
644
+ const candidate = normalizePlannedFileReference(match[1]);
626
645
  // Filter out things that look like code tokens rather than file paths
627
646
  // (e.g. `true`, `false`, `npm run test`). A file path has at least one
628
647
  // dot or slash.
629
- if (candidate.includes("/") || candidate.includes(".")) {
648
+ if (candidate.includes("/") || candidate.includes("\\") || candidate.includes(".")) {
630
649
  paths.push(candidate);
631
650
  }
632
651
  }
@@ -186,12 +186,13 @@ export function checkAutoStartAfterDiscuss(): boolean {
186
186
  // Parse PROJECT.md for milestone sequence, warn if any are missing context.
187
187
  // Don't block — milestones can be intentionally queued without context.
188
188
  const projectFile = resolveGsdRootFile(basePath, "PROJECT");
189
+ let projectIds: string[] = [];
189
190
  if (projectFile) {
190
191
  try {
191
192
  const projectContent = readFileSync(projectFile, "utf-8");
192
- const milestoneIds = parseMilestoneSequenceFromProject(projectContent);
193
- if (milestoneIds.length > 1) {
194
- const missing = milestoneIds.filter(id => {
193
+ projectIds = parseMilestoneSequenceFromProject(projectContent);
194
+ if (projectIds.length > 1) {
195
+ const missing = projectIds.filter(id => {
195
196
  const hasContext = !!resolveMilestoneFile(basePath, id, "CONTEXT");
196
197
  const hasDraft = !!resolveMilestoneFile(basePath, id, "CONTEXT-DRAFT");
197
198
  const hasDir = existsSync(join(gsdRoot(basePath), "milestones", id));
@@ -210,9 +211,17 @@ export function checkAutoStartAfterDiscuss(): boolean {
210
211
 
211
212
  // Gate 4: Discussion manifest process verification (multi-milestone only)
212
213
  // The LLM writes DISCUSSION-MANIFEST.json after each Phase 3 gate decision.
213
- // If the manifest exists but gates_completed < total, the LLM hasn't finished
214
- // presenting all readiness gates to the user — block auto-start.
214
+ // If the project is multi-milestone, the manifest is required. When it is
215
+ // missing, fail closed instead of assuming the discussion finished.
215
216
  const manifestPath = join(gsdRoot(basePath), "DISCUSSION-MANIFEST.json");
217
+ const requiresManifest = projectIds.length > 1 || findMilestoneIds(basePath).length > 1;
218
+ if (requiresManifest && !existsSync(manifestPath)) {
219
+ ctx.ui.notify(
220
+ "Multi-milestone discussion manifest is missing. Auto-start will remain paused until the manifest is written.",
221
+ "warning",
222
+ );
223
+ return false;
224
+ }
216
225
  if (existsSync(manifestPath)) {
217
226
  try {
218
227
  const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
@@ -225,9 +234,7 @@ export function checkAutoStartAfterDiscuss(): boolean {
225
234
  }
226
235
 
227
236
  // Cross-check manifest milestones against PROJECT.md if available
228
- if (projectFile) {
229
- const projectContent = readFileSync(projectFile, "utf-8");
230
- const projectIds = parseMilestoneSequenceFromProject(projectContent);
237
+ if (projectIds.length > 0) {
231
238
  const manifestIds = Object.keys(manifest.milestones ?? {});
232
239
  const untracked = projectIds.filter(id => !manifestIds.includes(id));
233
240
  if (untracked.length > 0) {
@@ -3,10 +3,16 @@ import type { ExtensionAPI } from "@gsd/pi-coding-agent";
3
3
  export {
4
4
  isDepthConfirmationAnswer,
5
5
  isDepthVerified,
6
+ isGateQuestionId,
6
7
  isQueuePhaseActive,
7
8
  setQueuePhaseActive,
8
9
  shouldBlockContextWrite,
10
+ shouldBlockPendingGate,
11
+ shouldBlockPendingGateBash,
9
12
  shouldBlockQueueExecution,
13
+ setPendingGate,
14
+ clearPendingGate,
15
+ getPendingGate,
10
16
  } from "./bootstrap/write-gate.js";
11
17
 
12
18
  export default async function registerExtension(pi: ExtensionAPI) {
@@ -490,6 +490,8 @@ export class ParallelMonitorOverlay {
490
490
 
491
491
  // Apply scroll — use terminal rows as height estimate
492
492
  const termHeight = process.stdout.rows || 40;
493
+ const maxScroll = Math.max(0, lines.length - termHeight);
494
+ this.scrollOffset = Math.min(Math.max(this.scrollOffset, 0), maxScroll);
493
495
  const visible = lines.slice(this.scrollOffset, this.scrollOffset + termHeight);
494
496
  this.cachedLines = visible;
495
497
  return visible;
@@ -210,7 +210,9 @@ function _parsePlanImpl(content: string): SlicePlan {
210
210
  for (const line of lines) {
211
211
  const cbMatch = line.match(/^-\s+\[([ xX])\]\s+\*\*([\w.]+):\s+(.+?)\*\*\s*(.*)/);
212
212
  // Heading-style: ### T01 -- Title, ### T01: Title, ### T01 — Title
213
- const hdMatch = !cbMatch ? line.match(/^#{2,4}\s+([\w.]+)\s*(?:--|—|:)\s*(.+)/) : null;
213
+ const hdMatch = !cbMatch
214
+ ? line.match(/^#{2,4}\s+([A-Z]+\d+(?:\.[A-Z]+\d+)*)\s*(?:--|—|:)\s*(.+)/)
215
+ : null;
214
216
  if (cbMatch || hdMatch) {
215
217
  const taskId = cbMatch ? cbMatch[2] : hdMatch![1];
216
218
  // Skip tasks already found in the Tasks section
@@ -200,11 +200,13 @@ function loadPreferencesFile(path: string, scope: "global" | "project"): LoadedG
200
200
  }
201
201
 
202
202
  let _warnedUnrecognizedFormat = false;
203
+ let _warnedSectionParse = false;
203
204
 
204
205
  /** @internal Reset the warn-once flags — exported for testing only. */
205
206
  export function _resetParseWarningFlag(): void {
206
207
  _warnedUnrecognizedFormat = false;
207
208
  _warnedFrontmatterParse = false;
209
+ _warnedSectionParse = false;
208
210
  }
209
211
 
210
212
  /** @internal Exported for testing only */
@@ -309,7 +311,10 @@ function parseHeadingListFormat(content: string): GSDPreferences {
309
311
 
310
312
  typed[targetSection] = value;
311
313
  } catch (e) {
312
- logWarning("guided", `preferences section parse failed: ${(e as Error).message}`);
314
+ if (!_warnedSectionParse) {
315
+ _warnedSectionParse = true;
316
+ logWarning("guided", `preferences section parse failed: ${(e as Error).message}`);
317
+ }
313
318
  }
314
319
  }
315
320
 
@@ -63,6 +63,6 @@ Then:
63
63
  13. Do not commit manually — the system auto-commits your changes after this unit completes.
64
64
  - Say: "Milestone {{milestoneId}} complete."
65
65
 
66
- **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.
66
+ **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. **If a verification tool itself fails, errors, or returns unexpected output, treat it as a verification failure** — never rationalize past a tool error ("tool didn't respond, assuming success" is forbidden). A tool that cannot verify is a tool that did not verify.
67
67
 
68
68
  **File system safety:** When scanning milestone directories for evidence, use `ls` or `find` to list directory contents first — never pass a directory path (e.g. `tasks/`, `slices/`) directly to the `read` tool. The `read` tool only accepts file paths, not directories.
@@ -25,11 +25,11 @@ Then:
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
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
27
  6. If this slice produced evidence that a requirement changed status (Active → Validated, Active → Deferred, etc.), call `gsd_requirement_update` with the requirement ID, updated `status`, and `validation` 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.
28
+ 7. Prepare the slice completion content you will pass to `gsd_complete_slice` using the camelCase fields `milestoneId`, `sliceId`, `sliceTitle`, `oneLiner`, `narrative`, `verification`, and `uatContent`. Do **not** manually write `{{sliceSummaryPath}}`. Do **not** manually write `{{sliceUatPath}}` the DB-backed tool is the canonical write path for both artifacts.
29
+ 8. Draft the UAT content you will pass as `uatContent` — 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
30
  9. Review task summaries for `key_decisions`. Append any significant decisions to `.gsd/DECISIONS.md` if missing.
31
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 milestoneId, sliceId, 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. Call `gsd_complete_slice` with the camelCase fields `milestoneId`, `sliceId`, `sliceTitle`, `oneLiner`, `narrative`, `verification`, and `uatContent`, plus any optional enrichment fields you have. Do NOT manually mark the roadmap checkbox — the tool writes to the DB, renders `{{sliceSummaryPath}}` and `{{sliceUatPath}}`, and updates the ROADMAP.md projection automatically.
33
33
  12. Do not run git commands — the system commits your changes and handles any merge after this unit succeeds.
34
34
  13. Update `.gsd/PROJECT.md` if it exists — refresh current state if needed: use the `write` tool with `path: ".gsd/PROJECT.md"` and `content` containing the full updated document reflecting current project state. Do NOT use the `edit` tool for this — PROJECT.md is a full-document refresh.
35
35
 
@@ -109,7 +109,7 @@ Options:
109
109
  - "Needs adjustment" — user will clarify, then re-present scope
110
110
  ```
111
111
 
112
- **Do NOT proceed to Layer 2 until the user explicitly approves the scope.**
112
+ **CRITICAL — Non-bypassable gate:** Do NOT proceed to Layer 2 until the user explicitly approves the scope. If `ask_user_questions` fails, errors, returns no response, or the user's response does not match a provided option, you MUST re-ask — never rationalize past the block. "Tool not responding, I'll proceed," "auth issues," or "I'll use my recommended scope" are all **forbidden**. The gate exists to protect the user's work; treat a block as an instruction to wait, not an obstacle to work around.
113
113
 
114
114
  ---
115
115
 
@@ -120,7 +120,7 @@ Before presenting Layer 2 findings, use your available web search tools to resea
120
120
  1. Search for "[technology] [version] best practices [current year]"
121
121
  2. Search for "[technology] [version] known issues"
122
122
 
123
- Summarize findings concisely. If no search tools are available, note this and proceed using your training knowledge — don't block the discussion on missing search results.
123
+ Summarize findings concisely. If search tools fail or are unavailable, note this and proceed using your training knowledge — but do NOT use a search failure as justification to skip any gate.
124
124
 
125
125
  Present ecosystem findings at the start of Layer 2 alongside your architecture recommendation.
126
126
 
@@ -180,7 +180,7 @@ Options:
180
180
  - "Want to adjust" — user will clarify, then re-present architecture
181
181
  ```
182
182
 
183
- **Do NOT proceed to Layer 3 until the user explicitly approves the architecture.**
183
+ **CRITICAL — Non-bypassable gate:** Do NOT proceed to Layer 3 until the user explicitly approves the architecture. If `ask_user_questions` fails, errors, returns no response, or the user's response does not match a provided option, you MUST re-ask — never rationalize past the block. The gate exists to protect the user's work; treat a block as an instruction to wait, not an obstacle to work around.
184
184
 
185
185
  ---
186
186
 
@@ -243,7 +243,7 @@ Options:
243
243
  - "Want to adjust error handling" — user will clarify, then re-present errors
244
244
  ```
245
245
 
246
- **Do NOT proceed to Layer 4 until the user explicitly approves error handling.**
246
+ **CRITICAL — Non-bypassable gate:** Do NOT proceed to Layer 4 until the user explicitly approves error handling. If `ask_user_questions` fails, errors, returns no response, or the user's response does not match a provided option, you MUST re-ask — never rationalize past the block. The gate exists to protect the user's work; treat a block as an instruction to wait, not an obstacle to work around.
247
247
 
248
248
  ---
249
249
 
@@ -297,7 +297,7 @@ Options:
297
297
  - "Want to adjust the quality bar" — user will clarify, then re-present quality
298
298
  ```
299
299
 
300
- **Do NOT proceed to Output Phase until the user explicitly approves the quality bar.**
300
+ **CRITICAL — Non-bypassable gate:** Do NOT proceed to Output Phase until the user explicitly approves the quality bar. If `ask_user_questions` fails, errors, returns no response, or the user's response does not match a provided option, you MUST re-ask — never rationalize past the block. The gate exists to protect the user's work; treat a block as an instruction to wait, not an obstacle to work around.
301
301
 
302
302
  ---
303
303
 
@@ -315,13 +315,13 @@ Before writing a roadmap, produce or update `.gsd/REQUIREMENTS.md`.
315
315
 
316
316
  Use it as the project's explicit capability contract. Requirements discovered during the 4-layer discussion should be captured here with source `user` or `inferred` as appropriate.
317
317
 
318
- **Print the requirements in chat before writing the roadmap.** Print a markdown table with columns: ID, Title, Status, Owner, Source. Group by status (Active, Deferred, Out of Scope). After the table, ask: "Confirm, adjust, or add?"
318
+ **Print the requirements in chat before writing the roadmap.** Print a markdown table with columns: ID, Title, Status, Owner, Source. Group by status (Active, Deferred, Out of Scope). After the table, ask: "Confirm, adjust, or add?" **Non-bypassable:** If the user does not respond or gives an ambiguous answer, you MUST re-ask — never proceed to roadmap creation without explicit requirement confirmation.
319
319
 
320
320
  ### Roadmap Preview
321
321
 
322
322
  Before writing any files, **print the planned roadmap in chat** so the user can see and approve it. Print a markdown table with columns: Slice, Title, Risk, Depends, Demo. One row per slice. Below the table, print the milestone definition of done as a bullet list.
323
323
 
324
- If the user raises a substantive objection, adjust the roadmap. Otherwise, present the roadmap and ask: "Ready to write, or want to adjust?" — one gate, not two.
324
+ If the user raises a substantive objection, adjust the roadmap. Otherwise, present the roadmap and ask: "Ready to write, or want to adjust?" — one gate, not two. **Non-bypassable:** If the user does not respond or gives an ambiguous answer, you MUST re-ask — never write files without explicit approval. A missing response is not a "yes."
325
325
 
326
326
  ### Naming Convention
327
327
 
@@ -173,7 +173,7 @@ For multi-milestone projects, requirements should span the full vision. Requirem
173
173
 
174
174
  If the project is new or has no `REQUIREMENTS.md`, surface candidate requirements in chat before writing the roadmap. Ask for correction only on material omissions, wrong ownership, or wrong scope. If the user has already been specific and raises no substantive objection, treat the requirement set as confirmed and continue.
175
175
 
176
- **Print the requirements in chat before writing the roadmap.** Do not say "here are the requirements" and then only write them to a file. The user must see them in the terminal. Print a markdown table with columns: ID, Title, Status, Owner, Source. Group by status (Active, Deferred, Out of Scope). After the table, ask: "Confirm, adjust, or add?"
176
+ **Print the requirements in chat before writing the roadmap.** Do not say "here are the requirements" and then only write them to a file. The user must see them in the terminal. Print a markdown table with columns: ID, Title, Status, Owner, Source. Group by status (Active, Deferred, Out of Scope). After the table, ask: "Confirm, adjust, or add?" **Non-bypassable:** If the user does not respond or gives an ambiguous answer, you MUST re-ask — never proceed to roadmap creation without explicit requirement confirmation.
177
177
 
178
178
  ## Scope Assessment
179
179
 
@@ -185,7 +185,7 @@ Before moving to output, confirm the size estimate from your reflection still ho
185
185
 
186
186
  Before writing any files, **print the planned roadmap in chat** so the user can see and approve it. Print a markdown table with columns: Slice, Title, Risk, Depends, Demo. One row per slice. Below the table, print the milestone definition of done as a bullet list.
187
187
 
188
- If the user raises a substantive objection, adjust the roadmap. Otherwise, present the roadmap and ask: "Ready to write, or want to adjust?" — one gate, not two.
188
+ If the user raises a substantive objection, adjust the roadmap. Otherwise, present the roadmap and ask: "Ready to write, or want to adjust?" — one gate, not two. **Non-bypassable:** If the user does not respond or gives an ambiguous answer, you MUST re-ask — never write files without explicit approval. A missing response is not a "yes."
189
189
 
190
190
  ### Naming Convention
191
191
 
@@ -242,7 +242,7 @@ If a milestone has no dependencies, omit the frontmatter. The dependency chain f
242
242
 
243
243
  #### Phase 3: Sequential readiness gate for remaining milestones
244
244
 
245
- For each remaining milestone **one at a time, in sequence**, decide the most likely readiness mode from the evidence you already have, then use `ask_user_questions` to let the user correct that recommendation. Present three options:
245
+ For each remaining milestone **one at a time, in sequence**, decide the most likely readiness mode from the evidence you already have, then use `ask_user_questions` to let the user correct that recommendation. **Non-bypassable:** If `ask_user_questions` fails, errors, returns no response, or the user's response does not match a provided option, you MUST re-ask — never rationalize past the block or auto-select a readiness mode. Present three options:
246
246
 
247
247
  - **"Discuss now"** — The user wants to conduct a focused discussion for this milestone in the current session, while the context from the broader discussion is still fresh. Proceed with a focused discussion for this milestone (reflection → investigation → questioning → depth verification). When the discussion concludes, write a full `CONTEXT.md`. Then move to the gate for the next milestone.
248
248
  - **"Write draft for later"** — This milestone has seed material from the current conversation but needs its own dedicated discussion in a future session. Write a `CONTEXT-DRAFT.md` capturing the seed material (what was discussed, key ideas, provisional scope, open questions). Mark it clearly as a draft, not a finalized context. **What happens downstream:** When auto-mode reaches this milestone, it pauses and notifies the user: "M00x has draft context — needs discussion. Run /gsd." The `/gsd` wizard shows a "Discuss from draft" option that seeds the new discussion with this draft, so nothing from the current conversation is lost. After the dedicated discussion produces a full CONTEXT.md, the draft file is automatically deleted.
@@ -69,14 +69,14 @@ Then:
69
69
  16. If you made an architectural, pattern, library, or observability decision during this task that downstream work should know about, append it to `.gsd/DECISIONS.md` (read the template at `~/.gsd/agent/extensions/gsd/templates/decisions.md` if the file doesn't exist yet). Not every task produces decisions — only append when a meaningful choice was made.
70
70
  17. If you discover a non-obvious rule, recurring gotcha, or useful pattern during execution, append it to `.gsd/KNOWLEDGE.md`. Only add entries that would save future agents from repeating your investigation. Don't add obvious things.
71
71
  18. Read the template at `~/.gsd/agent/extensions/gsd/templates/task-summary.md`
72
- 19. Write `{{taskSummaryPath}}`
73
- 20. Call `gsd_complete_task` with milestoneId, sliceId, taskId, and a summary of what was accomplished. This is your final required step — do NOT manually edit PLAN.md checkboxes. The tool marks the task complete, updates the DB, and renders PLAN.md automatically.
72
+ 19. Use that template to prepare the completion content you will pass to `gsd_complete_task` using the camelCase fields `milestoneId`, `sliceId`, `taskId`, `oneLiner`, `narrative`, `verification`, and `verificationEvidence`. Do **not** manually write `{{taskSummaryPath}}` — the DB-backed tool is the canonical write path and renders the summary file for you.
73
+ 20. Call `gsd_complete_task` with milestoneId, sliceId, taskId, and the completion fields derived from the template. This is your final required step — do NOT manually edit PLAN.md checkboxes. The tool marks the task complete, updates the DB, renders `{{taskSummaryPath}}`, and updates PLAN.md automatically.
74
74
  21. Do not run git commands — the system reads your task summary after completion and creates a meaningful commit from it (type inferred from title, message from your one-liner, key files from frontmatter). Write a clear, specific one-liner in the summary — it becomes the commit message.
75
75
 
76
76
  All work stays in your working directory: `{{workingDirectory}}`.
77
77
 
78
78
  **Autonomous execution:** Do not call `ask_user_questions` or `secure_env_collect`. You are running in auto-mode — there is no human available to answer questions. Make reasonable assumptions and document them in the task summary. If a decision genuinely requires human input, note it in the summary and proceed with the best available option.
79
79
 
80
- **You MUST call `gsd_complete_task` AND write `{{taskSummaryPath}}` before finishing.**
80
+ **You MUST call `gsd_complete_task` before finishing. Do not manually write `{{taskSummaryPath}}`.**
81
81
 
82
82
  When done, say: "Task {{taskId}} complete."
@@ -92,15 +92,15 @@ Before moving to the wrap-up gate, verify you have covered:
92
92
  - header: "Depth Check"
93
93
  - question: "Did I capture the depth right?"
94
94
  - options: "Yes, you got it (Recommended)", "Not quite — let me clarify"
95
- - **The question ID must contain `depth_verification`** (e.g. `depth_verification_confirm`) — this enables the write-gate downstream.
95
+ - **The question ID must contain `depth_verification` and the milestone id** (e.g. `depth_verification_{{milestoneId}}_confirm`) — this enables the write-gate downstream and keeps verification scoped to the milestone being discussed.
96
96
 
97
- **If `{{structuredQuestionsAvailable}}` is `false`:** ask in plain text: "Did I capture that correctly? If not, tell me what I missed." Wait for confirmation before proceeding.
97
+ **If `{{structuredQuestionsAvailable}}` is `false`:** ask in plain text: "Did I capture that correctly? If not, tell me what I missed." Wait for explicit confirmation before proceeding. **The same non-bypassable gate applies to the plain-text path** — if the user does not respond, gives an ambiguous answer, or does not explicitly confirm, you MUST re-ask. Never rationalize past a missing confirmation.
98
98
 
99
99
  If they clarify, absorb the correction and re-verify.
100
100
 
101
101
  The depth verification is the only required confirmation gate. Do not add a second "ready to proceed?" gate after it.
102
102
 
103
- **CRITICAL — Non-bypassable gate:** The system mechanically blocks CONTEXT.md writes until the user selects the "(Recommended)" option. If the user declines, cancels, or the tool fails, you MUST re-ask — never rationalize past the block ("tool not responding, I'll proceed" is forbidden). The gate exists to protect the user's work; treat a block as an instruction, not an obstacle to work around.
103
+ **CRITICAL — Non-bypassable gate:** The system mechanically blocks CONTEXT.md writes until the user selects the "(Recommended)" option (structured path) or explicitly confirms (plain-text path). If the user declines, cancels, does not respond, or the tool fails, you MUST re-ask — never rationalize past the block ("tool not responding, I'll proceed" is forbidden). The gate exists to protect the user's work; treat a block as an instruction, not an obstacle to work around.
104
104
 
105
105
  ---
106
106
 
@@ -41,11 +41,13 @@ After each round of answers, decide whether you already have enough signal to wr
41
41
  - Ask a single wrap-up question only when you genuinely believe the slice is well understood or the user signals they want to stop.
42
42
  - When you do ask it, offer two choices: "Write the context file" *(recommended when the slice is well understood)* or "One more pass". Use `ask_user_questions` if available, otherwise ask in plain text.
43
43
 
44
+ **CRITICAL — Non-bypassable gate:** Do NOT write the context file until the user explicitly selects "Write the context file." If `ask_user_questions` fails, errors, returns no response, or the user's response does not match a provided option, you MUST re-ask — never rationalize past the block. "Tool not responding, I'll proceed," "auth issues," or "the slice seems well understood, I'll write it" are all **forbidden**. The gate exists to protect the user's work; treat a block as an instruction to wait, not an obstacle to work around.
45
+
44
46
  ---
45
47
 
46
48
  ## Output
47
49
 
48
- Once the user is ready to wrap up:
50
+ Once the user has explicitly confirmed they are ready to write the context file:
49
51
 
50
52
  1. Use the **Slice Context** output template below
51
53
  2. `mkdir -p {{sliceDirPath}}`
@@ -12,7 +12,7 @@ You are a project reorganization assistant for a GSD (Get Shit Done) project. Th
12
12
 
13
13
  1. Present the current milestone order as a clear numbered list with status indicators (e.g. ✅ complete, ▶ active, ⏳ pending, ⏸ parked)
14
14
  2. Ask: **"What would you like to change?"**
15
- 3. Execute changes conversationally, confirming destructive operations before proceeding
15
+ 3. Execute changes conversationally, confirming destructive operations before proceeding. **Non-bypassable:** For any destructive operation (discard, skip, reorder that breaks dependencies), you MUST get explicit user confirmation before executing. If the user does not respond, gives an ambiguous answer, or `ask_user_questions` fails, you MUST re-ask — never rationalize past the block. A missing confirmation is a "do not proceed."
16
16
 
17
17
  ## Supported Operations
18
18
 
@@ -53,8 +53,12 @@ gsd_skip_slice({ milestoneId: "M003", sliceId: "S02", reason: "Descoped — feat
53
53
  Skipped slices are treated as closed by the state machine (like "complete" but distinct). Use when a slice is no longer needed or has been superseded. The slice data is preserved for reference.
54
54
  **Do NOT** just check the slice checkbox in the roadmap — this does not update the DB and auto-mode will resume the slice.
55
55
 
56
+ **CRITICAL — Non-bypassable gate:** Skipping a slice is a permanent DB operation. You MUST confirm with the user before calling `gsd_skip_slice`. If the user does not respond or gives an ambiguous answer, you MUST re-ask — never proceed without explicit approval.
57
+
56
58
  ### Discard a milestone
57
- **Permanently** delete a milestone directory and prune it from QUEUE-ORDER.json. **Always confirm with the user before discarding.** Warn explicitly if the milestone has completed work.
59
+ **Permanently** delete a milestone directory and prune it from QUEUE-ORDER.json.
60
+
61
+ **CRITICAL — Non-bypassable gate:** Discarding is irreversible. You MUST confirm with the user before discarding. Warn explicitly if the milestone has completed work. If the user does not respond or gives an ambiguous answer, you MUST re-ask — never rationalize past the block. A missing confirmation is a "do not discard."
58
62
 
59
63
  ### Add a new milestone
60
64
  Use the `gsd_milestone_generate_id` tool to get the next ID, then call `gsd_summary_save` with `milestone_id: {ID}`, `artifact_type: "CONTEXT"`, and the scope/goals/success criteria as `content` — the tool writes the context file to disk and persists to DB. Update QUEUE-ORDER.json to place it at the desired position.
@@ -38,7 +38,7 @@ GSD ships with bundled skills. Load the relevant skill file with the `read` tool
38
38
  - Never print, echo, log, or restate secrets or credentials. Report only key names and applied/skipped status.
39
39
  - Never ask the user to edit `.env` files or set secrets manually. Use `secure_env_collect`.
40
40
  - In enduring files, write current state only unless the file is explicitly historical.
41
- - **Never take outward-facing actions on GitHub (or any external service) without explicit user confirmation.** This includes: creating issues, closing issues, merging PRs, approving PRs, posting comments, pushing to remote branches, publishing packages, or any other action that affects state outside the local filesystem. Read-only operations (listing, viewing, diffing) are fine. Always present what you intend to do and get a clear "yes" before executing.
41
+ - **Never take outward-facing actions on GitHub (or any external service) without explicit user confirmation.** This includes: creating issues, closing issues, merging PRs, approving PRs, posting comments, pushing to remote branches, publishing packages, or any other action that affects state outside the local filesystem. Read-only operations (listing, viewing, diffing) are fine. Always present what you intend to do and get a clear "yes" before executing. **Non-bypassable:** If the user does not respond, gives an ambiguous answer, or `ask_user_questions` fails, you MUST re-ask — never rationalize past the block ("tool not responding, I'll proceed" is forbidden). A missing "yes" is a "no."
42
42
 
43
43
  If a `GSD Skill Preferences` block is present below this contract, treat it as explicit durable guidance for which skills to use, prefer, or avoid during GSD work. Follow it where it does not conflict with required GSD artifact rules, verification requirements, or higher-priority system/developer instructions.
44
44
 
@@ -51,7 +51,7 @@ For each capture, classify it as one of:
51
51
 
52
52
  For captures classified as **note** or **defer**, auto-confirm without asking — these are low-impact.
53
53
  For captures classified as **stop** or **backtrack**, auto-confirm without asking — these are urgent user directives that must be honored immediately.
54
- For captures classified as **quick-task**, **inject**, or **replan**, ask the user to confirm or choose a different classification.
54
+ For captures classified as **quick-task**, **inject**, or **replan**, ask the user to confirm or choose a different classification. **Non-bypassable:** If `ask_user_questions` fails, errors, or the user does not respond, you MUST re-ask — never auto-confirm these classifications without explicit user approval.
55
55
 
56
56
  3. **Update** `.gsd/CAPTURES.md` — for each capture, update its section with the confirmed classification:
57
57
  - Change `**Status:** pending` to `**Status:** resolved`