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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (613) hide show
  1. package/README.md +10 -8
  2. package/dist/cli.js +5 -1
  3. package/dist/headless-events.d.ts +2 -1
  4. package/dist/headless-events.js +11 -3
  5. package/dist/headless-milestone-readiness.d.ts +29 -0
  6. package/dist/headless-milestone-readiness.js +161 -0
  7. package/dist/headless.js +27 -3
  8. package/dist/print-mode-exit.d.ts +12 -0
  9. package/dist/print-mode-exit.js +14 -0
  10. package/dist/resources/.managed-resources-content-hash +1 -1
  11. package/dist/resources/GSD-WORKFLOW.md +18 -49
  12. package/dist/resources/extensions/browser-tools/capture.js +2 -77
  13. package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
  14. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
  15. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
  16. package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
  17. package/dist/resources/extensions/gsd/auto/loop.js +24 -4
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +19 -1
  19. package/dist/resources/extensions/gsd/auto/unit-phase.js +37 -5
  20. package/dist/resources/extensions/gsd/auto-artifact-paths.js +16 -10
  21. package/dist/resources/extensions/gsd/auto-dispatch.js +76 -19
  22. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
  23. package/dist/resources/extensions/gsd/auto-prompts.js +137 -22
  24. package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
  25. package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -5
  26. package/dist/resources/extensions/gsd/auto-start.js +29 -9
  27. package/dist/resources/extensions/gsd/auto-tool-tracking.js +40 -0
  28. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-sync.js +7 -3
  30. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
  31. package/dist/resources/extensions/gsd/auto.js +20 -6
  32. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -4
  33. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -7
  34. package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
  35. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +88 -50
  36. package/dist/resources/extensions/gsd/command-feedback.js +16 -12
  37. package/dist/resources/extensions/gsd/commands-verdict.js +10 -9
  38. package/dist/resources/extensions/gsd/compat/compat-marker.js +98 -6
  39. package/dist/resources/extensions/gsd/constants.js +12 -13
  40. package/dist/resources/extensions/gsd/context-masker.js +97 -21
  41. package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
  42. package/dist/resources/extensions/gsd/db/engine.js +56 -18
  43. package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
  44. package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
  45. package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
  46. package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
  47. package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
  48. package/dist/resources/extensions/gsd/docs/preferences-reference.md +26 -4
  49. package/dist/resources/extensions/gsd/doctor-engine-checks.js +24 -8
  50. package/dist/resources/extensions/gsd/error-classifier.js +12 -2
  51. package/dist/resources/extensions/gsd/exec-sandbox.js +1 -0
  52. package/dist/resources/extensions/gsd/flat-phase-migration.js +168 -21
  53. package/dist/resources/extensions/gsd/git-service.js +19 -7
  54. package/dist/resources/extensions/gsd/gsd-db.js +262 -76
  55. package/dist/resources/extensions/gsd/guided-flow.js +40 -15
  56. package/dist/resources/extensions/gsd/markdown-renderer.js +20 -22
  57. package/dist/resources/extensions/gsd/md-importer.js +107 -20
  58. package/dist/resources/extensions/gsd/migrate/command.js +19 -162
  59. package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
  60. package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
  61. package/dist/resources/extensions/gsd/migrate/planning-writer.js +12 -17
  62. package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
  63. package/dist/resources/extensions/gsd/model-cost-table.js +2 -0
  64. package/dist/resources/extensions/gsd/model-router.js +11 -0
  65. package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
  66. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
  67. package/dist/resources/extensions/gsd/paths.js +70 -16
  68. package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
  69. package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
  70. package/dist/resources/extensions/gsd/planning-subagent-registry.js +25 -0
  71. package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
  72. package/dist/resources/extensions/gsd/preferences-types.js +5 -0
  73. package/dist/resources/extensions/gsd/preferences-validation.js +48 -1
  74. package/dist/resources/extensions/gsd/preferences.js +17 -0
  75. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  76. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
  77. package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
  78. package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
  79. package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
  80. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
  81. package/dist/resources/extensions/gsd/skill-activation.js +17 -3
  82. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +125 -15
  83. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +17 -4
  84. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +5 -2
  85. package/dist/resources/extensions/gsd/stop-notice.js +24 -1
  86. package/dist/resources/extensions/gsd/sync-lock.js +13 -7
  87. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
  88. package/dist/resources/extensions/gsd/tools/complete-task.js +94 -6
  89. package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
  90. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
  91. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
  92. package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
  93. package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
  94. package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
  95. package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
  96. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
  97. package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
  98. package/dist/resources/extensions/gsd/unit-registry.js +4 -0
  99. package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
  100. package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
  101. package/dist/resources/extensions/gsd/workspace.js +2 -1
  102. package/dist/resources/extensions/gsd/worktree-state-projection.js +26 -18
  103. package/dist/resources/extensions/mac-tools/index.js +31 -9
  104. package/dist/resources/extensions/shared/interview-ui.js +43 -6
  105. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  106. package/dist/web/standalone/.next/BUILD_ID +1 -1
  107. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  108. package/dist/web/standalone/.next/build-manifest.json +3 -3
  109. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  110. package/dist/web/standalone/.next/required-server-files.json +3 -3
  111. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  112. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  122. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  131. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  150. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  172. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  188. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  204. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  208. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/index.html +1 -1
  218. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  219. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  220. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  221. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  222. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  223. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  224. package/dist/web/standalone/.next/server/app/page.js +2 -2
  225. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  227. package/dist/web/standalone/.next/server/chunks/1991.js +2 -2
  228. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  229. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  230. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  231. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/middleware.js +3 -3
  233. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  234. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  235. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  236. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  237. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  238. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  239. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  240. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  241. package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
  242. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  243. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  244. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  245. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  246. package/dist/web/standalone/package.json +0 -1
  247. package/dist/web/standalone/server.js +1 -1
  248. package/dist/web-mode.js +31 -3
  249. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  250. package/integrations/hermes/pyproject.toml +1 -1
  251. package/package.json +13 -10
  252. package/packages/cloud-mcp-gateway/package.json +2 -2
  253. package/packages/contracts/dist/workflow.d.ts +14 -0
  254. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  255. package/packages/contracts/dist/workflow.js +16 -0
  256. package/packages/contracts/dist/workflow.js.map +1 -1
  257. package/packages/contracts/package.json +1 -1
  258. package/packages/daemon/dist/cloud-config.d.ts +1 -1
  259. package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
  260. package/packages/daemon/dist/cloud-config.js +5 -1
  261. package/packages/daemon/dist/cloud-config.js.map +1 -1
  262. package/packages/daemon/dist/cloud-config.test.js +51 -1
  263. package/packages/daemon/dist/cloud-config.test.js.map +1 -1
  264. package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
  265. package/packages/daemon/dist/local-tool-executor.js +2 -0
  266. package/packages/daemon/dist/local-tool-executor.js.map +1 -1
  267. package/packages/daemon/package.json +6 -6
  268. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  269. package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
  270. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  271. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  272. package/packages/gsd-agent-core/dist/sdk.js +1 -0
  273. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  274. package/packages/gsd-agent-core/package.json +5 -5
  275. package/packages/gsd-agent-modes/package.json +7 -7
  276. package/packages/gsd-cloud/README.md +9 -3
  277. package/packages/gsd-cloud/dist/background-cli.test.d.ts +2 -0
  278. package/packages/gsd-cloud/dist/background-cli.test.d.ts.map +1 -0
  279. package/packages/gsd-cloud/dist/background-cli.test.js +248 -0
  280. package/packages/gsd-cloud/dist/background-cli.test.js.map +1 -0
  281. package/packages/gsd-cloud/dist/cli.d.ts +5 -0
  282. package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
  283. package/packages/gsd-cloud/dist/cli.js +266 -0
  284. package/packages/gsd-cloud/dist/cli.js.map +1 -0
  285. package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
  286. package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
  287. package/packages/gsd-cloud/dist/cloud-config.js +237 -0
  288. package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
  289. package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
  290. package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
  291. package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
  292. package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
  293. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
  294. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
  295. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
  296. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
  297. package/packages/gsd-cloud/dist/cloud-runtime.d.ts +33 -0
  298. package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
  299. package/packages/gsd-cloud/dist/cloud-runtime.js +260 -0
  300. package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
  301. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
  302. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
  303. package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
  304. package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
  305. package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
  306. package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
  307. package/packages/gsd-cloud/dist/cloud-token.js +37 -0
  308. package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
  309. package/packages/gsd-cloud/dist/config.d.ts +17 -0
  310. package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
  311. package/packages/gsd-cloud/dist/config.js +146 -0
  312. package/packages/gsd-cloud/dist/config.js.map +1 -0
  313. package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
  314. package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
  315. package/packages/gsd-cloud/dist/device-flow.js +128 -0
  316. package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
  317. package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
  318. package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
  319. package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
  320. package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
  321. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
  322. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
  323. package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
  324. package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
  325. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
  326. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
  327. package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
  328. package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
  329. package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
  330. package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
  331. package/packages/gsd-cloud/dist/executors/executor.js +11 -0
  332. package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
  333. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
  334. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
  335. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
  336. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
  337. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
  338. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
  339. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
  340. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
  341. package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
  342. package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
  343. package/packages/gsd-cloud/dist/executors/index.js +29 -0
  344. package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
  345. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
  346. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
  347. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
  348. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
  349. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
  350. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
  351. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
  352. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
  353. package/packages/gsd-cloud/dist/index.d.ts +7 -0
  354. package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
  355. package/packages/gsd-cloud/dist/index.js +8 -0
  356. package/packages/gsd-cloud/dist/index.js.map +1 -0
  357. package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
  358. package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
  359. package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
  360. package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
  361. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
  362. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
  363. package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
  364. package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
  365. package/packages/gsd-cloud/dist/logger.d.ts +25 -0
  366. package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
  367. package/packages/gsd-cloud/dist/logger.js +72 -0
  368. package/packages/gsd-cloud/dist/logger.js.map +1 -0
  369. package/packages/gsd-cloud/dist/runtime-process.d.ts +27 -0
  370. package/packages/gsd-cloud/dist/runtime-process.d.ts.map +1 -0
  371. package/packages/gsd-cloud/dist/runtime-process.js +272 -0
  372. package/packages/gsd-cloud/dist/runtime-process.js.map +1 -0
  373. package/packages/gsd-cloud/dist/runtime-process.test.d.ts +2 -0
  374. package/packages/gsd-cloud/dist/runtime-process.test.d.ts.map +1 -0
  375. package/packages/gsd-cloud/dist/runtime-process.test.js +97 -0
  376. package/packages/gsd-cloud/dist/runtime-process.test.js.map +1 -0
  377. package/packages/gsd-cloud/dist/types.d.ts +51 -0
  378. package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
  379. package/packages/gsd-cloud/dist/types.js +9 -0
  380. package/packages/gsd-cloud/dist/types.js.map +1 -0
  381. package/packages/gsd-cloud/package.json +3 -3
  382. package/packages/mcp-server/README.md +15 -2
  383. package/packages/mcp-server/dist/cli-runner.d.ts +3 -0
  384. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
  385. package/packages/mcp-server/dist/cli-runner.js +119 -33
  386. package/packages/mcp-server/dist/cli-runner.js.map +1 -1
  387. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  388. package/packages/mcp-server/dist/server.js +5 -5
  389. package/packages/mcp-server/dist/server.js.map +1 -1
  390. package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
  391. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  392. package/packages/mcp-server/dist/workflow-tools.js +64 -2
  393. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  394. package/packages/mcp-server/package.json +4 -4
  395. package/packages/native/package.json +1 -1
  396. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  397. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  398. package/packages/pi-agent-core/dist/agent.js +2 -0
  399. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  400. package/packages/pi-agent-core/package.json +1 -1
  401. package/packages/pi-ai/dist/models.generated.d.ts +136 -0
  402. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  403. package/packages/pi-ai/dist/models.generated.js +124 -0
  404. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  405. package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
  406. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  407. package/packages/pi-ai/dist/providers/anthropic.js +25 -1
  408. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  409. package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
  410. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  411. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  412. package/packages/pi-ai/dist/providers/openai-completions.js +103 -0
  413. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  414. package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
  415. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  416. package/packages/pi-ai/package.json +1 -1
  417. package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
  418. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  419. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -1
  420. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  421. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +11 -1
  422. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  423. package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
  424. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  425. package/packages/pi-coding-agent/package.json +7 -7
  426. package/packages/pi-tui/package.json +2 -2
  427. package/packages/rpc-client/package.json +2 -2
  428. package/pkg/package.json +1 -1
  429. package/src/resources/GSD-WORKFLOW.md +18 -49
  430. package/src/resources/extensions/browser-tools/capture.ts +2 -86
  431. package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
  432. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
  433. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
  434. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
  435. package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
  436. package/src/resources/extensions/gsd/auto/loop.ts +48 -4
  437. package/src/resources/extensions/gsd/auto/run-unit.ts +20 -1
  438. package/src/resources/extensions/gsd/auto/unit-phase.ts +41 -5
  439. package/src/resources/extensions/gsd/auto-artifact-paths.ts +16 -9
  440. package/src/resources/extensions/gsd/auto-dispatch.ts +87 -19
  441. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
  442. package/src/resources/extensions/gsd/auto-prompts.ts +156 -20
  443. package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
  444. package/src/resources/extensions/gsd/auto-runtime-state.ts +12 -7
  445. package/src/resources/extensions/gsd/auto-start.ts +31 -8
  446. package/src/resources/extensions/gsd/auto-tool-tracking.ts +56 -0
  447. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
  448. package/src/resources/extensions/gsd/auto-worktree-sync.ts +10 -3
  449. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
  450. package/src/resources/extensions/gsd/auto.ts +25 -8
  451. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +92 -4
  452. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -12
  453. package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
  454. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +87 -53
  455. package/src/resources/extensions/gsd/command-feedback.ts +19 -12
  456. package/src/resources/extensions/gsd/commands-verdict.ts +16 -9
  457. package/src/resources/extensions/gsd/compat/compat-marker.ts +119 -8
  458. package/src/resources/extensions/gsd/constants.ts +14 -13
  459. package/src/resources/extensions/gsd/context-masker.ts +98 -2
  460. package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
  461. package/src/resources/extensions/gsd/db/engine.ts +58 -19
  462. package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
  463. package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
  464. package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
  465. package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
  466. package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
  467. package/src/resources/extensions/gsd/docs/preferences-reference.md +26 -4
  468. package/src/resources/extensions/gsd/doctor-engine-checks.ts +30 -7
  469. package/src/resources/extensions/gsd/error-classifier.ts +13 -2
  470. package/src/resources/extensions/gsd/exec-sandbox.ts +1 -0
  471. package/src/resources/extensions/gsd/flat-phase-migration.ts +174 -19
  472. package/src/resources/extensions/gsd/git-service.ts +19 -6
  473. package/src/resources/extensions/gsd/gsd-db.ts +340 -85
  474. package/src/resources/extensions/gsd/guided-flow.ts +50 -14
  475. package/src/resources/extensions/gsd/markdown-renderer.ts +28 -30
  476. package/src/resources/extensions/gsd/md-importer.ts +114 -16
  477. package/src/resources/extensions/gsd/migrate/command.ts +21 -227
  478. package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
  479. package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
  480. package/src/resources/extensions/gsd/migrate/planning-writer.ts +12 -20
  481. package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
  482. package/src/resources/extensions/gsd/model-cost-table.ts +2 -0
  483. package/src/resources/extensions/gsd/model-router.ts +12 -0
  484. package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
  485. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
  486. package/src/resources/extensions/gsd/paths.ts +77 -16
  487. package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
  488. package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
  489. package/src/resources/extensions/gsd/planning-subagent-registry.ts +31 -0
  490. package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
  491. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  492. package/src/resources/extensions/gsd/preferences-validation.ts +62 -0
  493. package/src/resources/extensions/gsd/preferences.ts +25 -0
  494. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  495. package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
  496. package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
  497. package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
  498. package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
  499. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
  500. package/src/resources/extensions/gsd/skill-activation.ts +17 -3
  501. package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +162 -15
  502. package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +20 -4
  503. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +4 -2
  504. package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
  505. package/src/resources/extensions/gsd/stop-notice.ts +29 -1
  506. package/src/resources/extensions/gsd/sync-lock.ts +14 -6
  507. package/src/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
  508. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
  509. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +264 -0
  510. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
  511. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +21 -1
  512. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +74 -1
  513. package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
  514. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
  515. package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
  516. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +10 -0
  517. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +129 -0
  518. package/src/resources/extensions/gsd/tests/complete-task.test.ts +362 -1
  519. package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
  520. package/src/resources/extensions/gsd/tests/db-engine-cjs-compat.test.ts +12 -0
  521. package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
  522. package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
  523. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
  524. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
  525. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
  526. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
  527. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
  528. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
  529. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +83 -0
  530. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
  531. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
  532. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +33 -1
  533. package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
  534. package/src/resources/extensions/gsd/tests/external-markdown-edit.test.ts +38 -1
  535. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +201 -0
  536. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +20 -1
  537. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
  538. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +57 -0
  539. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +22 -0
  540. package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
  541. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +13 -0
  542. package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
  543. package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
  544. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
  545. package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
  546. package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
  547. package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
  548. package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
  549. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  550. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  551. package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
  552. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
  553. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
  554. package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
  555. package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
  556. package/src/resources/extensions/gsd/tests/planning-writer.test.ts +29 -0
  557. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
  558. package/src/resources/extensions/gsd/tests/preferences.test.ts +84 -0
  559. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +4 -0
  560. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +87 -0
  561. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +121 -1
  562. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
  563. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
  564. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +105 -0
  565. package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
  566. package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
  567. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  568. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
  569. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
  570. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
  571. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +52 -0
  572. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +38 -1
  573. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
  574. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
  575. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +14 -0
  576. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  577. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
  578. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +73 -0
  579. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
  580. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +7 -0
  581. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
  582. package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
  583. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
  584. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
  585. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +60 -0
  586. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +34 -0
  587. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
  588. package/src/resources/extensions/gsd/tools/complete-task.ts +140 -5
  589. package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
  590. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
  591. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
  592. package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
  593. package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
  594. package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
  595. package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
  596. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
  597. package/src/resources/extensions/gsd/types.ts +11 -0
  598. package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
  599. package/src/resources/extensions/gsd/unit-registry.ts +4 -0
  600. package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
  601. package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
  602. package/src/resources/extensions/gsd/workspace.ts +2 -1
  603. package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -24
  604. package/src/resources/extensions/mac-tools/index.ts +52 -9
  605. package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
  606. package/src/resources/extensions/shared/interview-ui.ts +47 -8
  607. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +29 -0
  608. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  609. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  610. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  611. package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
  612. /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → DXD9fZPnqtjZSlT5xdC3v}/_buildManifest.js +0 -0
  613. /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → DXD9fZPnqtjZSlT5xdC3v}/_ssgManifest.js +0 -0
@@ -0,0 +1,139 @@
1
+ // GSD Extension - Auto-migration gate tests (plan 026).
2
+ // Covers needsAutoMigration's trigger (empty milestones table + .gsd/milestones
3
+ // present) and validateMigration's engine-vs-markdown count comparison.
4
+
5
+ import { describe, test } from 'node:test';
6
+ import assert from 'node:assert/strict';
7
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+ import { tmpdir } from 'node:os';
10
+
11
+ import { openDatabase, closeDatabase, insertMilestone, insertSlice } from '../gsd-db.ts';
12
+ import { needsAutoMigration, validateMigration } from '../workflow-migration.ts';
13
+
14
+ function makeProject(): string {
15
+ return mkdtempSync(join(tmpdir(), 'gsd-migration-gates-'));
16
+ }
17
+
18
+ function openProjectDb(base: string): string {
19
+ const gsdDir = join(base, '.gsd');
20
+ mkdirSync(gsdDir, { recursive: true });
21
+ const dbPath = join(gsdDir, 'gsd.db');
22
+ assert.ok(openDatabase(dbPath), 'openDatabase should succeed');
23
+ return dbPath;
24
+ }
25
+
26
+ function cleanup(base: string): void {
27
+ closeDatabase();
28
+ rmSync(base, { recursive: true, force: true });
29
+ }
30
+
31
+ function writeRoadmap(base: string, mId: string, sliceLines: string[]): void {
32
+ const mDir = join(base, '.gsd', 'milestones', mId);
33
+ mkdirSync(mDir, { recursive: true });
34
+ writeFileSync(join(mDir, 'ROADMAP.md'), [
35
+ `# ${mId}: Test`,
36
+ '',
37
+ '## Slices',
38
+ '',
39
+ ...sliceLines,
40
+ '',
41
+ ].join('\n'));
42
+ }
43
+
44
+ describe('needsAutoMigration', () => {
45
+ test('false for a fresh project with no legacy markdown', () => {
46
+ const base = makeProject();
47
+ try {
48
+ openProjectDb(base);
49
+ assert.equal(needsAutoMigration(base), false, 'no .gsd/milestones dir → no migration');
50
+ } finally {
51
+ cleanup(base);
52
+ }
53
+ });
54
+
55
+ test('true when engine tables are empty and .gsd/milestones exists', () => {
56
+ const base = makeProject();
57
+ try {
58
+ openProjectDb(base);
59
+ mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
60
+ assert.equal(needsAutoMigration(base), true, 'legacy markdown + empty engine → migrate');
61
+ } finally {
62
+ cleanup(base);
63
+ }
64
+ });
65
+
66
+ test('false once the milestones table has rows (migration already done)', () => {
67
+ const base = makeProject();
68
+ try {
69
+ openProjectDb(base);
70
+ mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
71
+ insertMilestone({ id: 'M001', title: 'Migrated' });
72
+ assert.equal(needsAutoMigration(base), false, 'engine rows present → migration already done');
73
+ } finally {
74
+ cleanup(base);
75
+ }
76
+ });
77
+
78
+ test('false when no database connection is open', () => {
79
+ const base = makeProject();
80
+ try {
81
+ mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
82
+ closeDatabase();
83
+ assert.equal(needsAutoMigration(base), false, 'no DB → cannot migrate');
84
+ } finally {
85
+ cleanup(base);
86
+ }
87
+ });
88
+ });
89
+
90
+ describe('validateMigration', () => {
91
+ test('reports no discrepancies when engine counts match markdown', () => {
92
+ const base = makeProject();
93
+ try {
94
+ openProjectDb(base);
95
+ writeRoadmap(base, 'M001', ['- [ ] **S01: Test Slice** `risk:low` `depends:[]`']);
96
+ insertMilestone({ id: 'M001', title: 'Test' });
97
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Test Slice' });
98
+
99
+ const result = validateMigration(base);
100
+ assert.deepEqual(result.discrepancies, [], 'matching engine/markdown counts → clean');
101
+ } finally {
102
+ cleanup(base);
103
+ }
104
+ });
105
+
106
+ test('reports discrepancies when engine counts diverge from markdown', () => {
107
+ const base = makeProject();
108
+ try {
109
+ openProjectDb(base);
110
+ writeRoadmap(base, 'M001', [
111
+ '- [ ] **S01: Test Slice** `risk:low` `depends:[]`',
112
+ '- [ ] **S02: Second Slice** `risk:low` `depends:[]`',
113
+ ]);
114
+ // Engine has no rows at all → milestone and slice counts both diverge.
115
+ const result = validateMigration(base);
116
+ assert.ok(
117
+ result.discrepancies.some((d) => d.includes('Milestone count mismatch')),
118
+ `expected milestone mismatch, got: ${result.discrepancies.join('; ')}`,
119
+ );
120
+ assert.ok(
121
+ result.discrepancies.some((d) => d.includes('Slice count mismatch')),
122
+ `expected slice mismatch, got: ${result.discrepancies.join('; ')}`,
123
+ );
124
+ } finally {
125
+ cleanup(base);
126
+ }
127
+ });
128
+
129
+ test('reports a validation failure when no database connection is open', () => {
130
+ const base = makeProject();
131
+ try {
132
+ closeDatabase();
133
+ const result = validateMigration(base);
134
+ assert.deepEqual(result.discrepancies, ['No database connection for validation']);
135
+ } finally {
136
+ cleanup(base);
137
+ }
138
+ });
139
+ });
@@ -352,7 +352,7 @@ test('workflow-projections: regenerateIfMissing SUMMARY is idempotent for flat-p
352
352
  keyDecisions: ['Use centralized task summary paths.'],
353
353
  });
354
354
 
355
- const summaryPath = join(phaseDir, 'T01-SUMMARY.md');
355
+ const summaryPath = join(phaseDir, 'S01-T01-SUMMARY.md');
356
356
  assert.ok(!existsSync(summaryPath), 'precondition: flat-phase task summary absent');
357
357
 
358
358
  const first = await regenerateIfMissing(base, 'M001', 'S01', 'SUMMARY');
@@ -399,7 +399,7 @@ test('workflow-projections: flat-phase SUMMARY regeneration ignores stale nested
399
399
  status: 'complete',
400
400
  });
401
401
 
402
- const rootSummaryPath = join(phaseDir, 'T01-SUMMARY.md');
402
+ const rootSummaryPath = join(phaseDir, 'S01-T01-SUMMARY.md');
403
403
  assert.ok(!existsSync(rootSummaryPath), 'precondition: canonical flat-phase task summary absent');
404
404
 
405
405
  const regenerated = await regenerateIfMissing(base, 'M001', 'S01', 'SUMMARY');
@@ -440,8 +440,8 @@ test('workflow-projections: renderSummaryProjection uses milestone title when cr
440
440
  status: 'complete',
441
441
  });
442
442
 
443
- const titleSummaryPath = join(base, '.gsd', 'phases', '01-milestone', 'T01-SUMMARY.md');
444
- const idSummaryPath = join(base, '.gsd', 'phases', '01-m001', 'T01-SUMMARY.md');
443
+ const titleSummaryPath = join(base, '.gsd', 'phases', '01-milestone', 'S01-T01-SUMMARY.md');
444
+ const idSummaryPath = join(base, '.gsd', 'phases', '01-m001', 'S01-T01-SUMMARY.md');
445
445
 
446
446
  renderSummaryProjection(base, 'M001', 'S01', 'T01');
447
447
 
@@ -97,6 +97,42 @@ test("projectRootToWorktree forwards root PROJECT.md into isolated worktrees", (
97
97
  }
98
98
  });
99
99
 
100
+ test("projectRootToWorktree projects flat-phase discuss artifacts before dispatch", () => {
101
+ const { dir, cleanup } = makeProjectRoot();
102
+ try {
103
+ const worktree = join(dir, ".gsd", "worktrees", "M001");
104
+ mkdirSync(join(worktree, ".gsd", "phases", "01-foundation"), { recursive: true });
105
+
106
+ const projectPhaseDir = join(dir, ".gsd", "phases", "01-foundation");
107
+ mkdirSync(projectPhaseDir, { recursive: true });
108
+ writeFileSync(join(projectPhaseDir, "01-CONTEXT.md"), "# M001 Context\n");
109
+ writeFileSync(join(projectPhaseDir, "01-DISCUSSION.md"), "# M001 Discussion\n");
110
+
111
+ const metaDir = join(dir, ".gsd", "milestones", "M001");
112
+ mkdirSync(metaDir, { recursive: true });
113
+ writeFileSync(join(metaDir, "M001-META.json"), '{"branch":"milestone/M001"}');
114
+
115
+ const workspace = createWorkspace(worktree);
116
+ const scope = scopeMilestone(workspace, "M001");
117
+ new WorktreeStateProjection().projectRootToWorktree(scope);
118
+
119
+ assert.ok(
120
+ !existsSync(join(worktree, ".gsd", "milestones")),
121
+ "stale metadata-only legacy milestones/ scaffold is not projected into the worktree",
122
+ );
123
+ assert.ok(
124
+ existsSync(join(worktree, ".gsd", "phases", "01-foundation", "01-CONTEXT.md")),
125
+ "flat-phase CONTEXT.md is projected into the worktree",
126
+ );
127
+ assert.ok(
128
+ existsSync(join(worktree, ".gsd", "phases", "01-foundation", "01-DISCUSSION.md")),
129
+ "flat-phase DISCUSSION.md is projected into the worktree",
130
+ );
131
+ } finally {
132
+ cleanup();
133
+ }
134
+ });
135
+
100
136
  test("projectRootToWorktree projects prior-milestone slice/task SUMMARY.md, not just top-level files", () => {
101
137
  // Regression: a worktree opened for the CURRENT milestone (M002) must also
102
138
  // receive the full subtree of OTHER, already-completed milestones (M001) so
@@ -246,6 +246,66 @@ describe('worktree-sync-milestones', async () => {
246
246
  }
247
247
  }
248
248
 
249
+ // ─── 7b. flat-phase sync skips empty legacy milestones root ───────────
250
+ console.log('\n=== 7b. flat-phase sync skips empty legacy milestones root ===');
251
+ {
252
+ const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-sync-flat-main-'));
253
+ const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-sync-flat-wt-'));
254
+
255
+ try {
256
+ const phaseDir = join(mainBase, '.gsd', 'phases', '01-foundation');
257
+ mkdirSync(phaseDir, { recursive: true });
258
+ mkdirSync(join(mainBase, '.gsd', 'milestones'), { recursive: true });
259
+ mkdirSync(join(wtBase, '.gsd'), { recursive: true });
260
+ writeFileSync(join(phaseDir, '01-CONTEXT.md'), '# Foundation\n');
261
+
262
+ syncGsdStateToWorktree(mainBase, wtBase);
263
+
264
+ assert.ok(
265
+ existsSync(join(wtBase, '.gsd', 'phases', '01-foundation', '01-CONTEXT.md')),
266
+ 'flat-phase artifact is synced to worktree',
267
+ );
268
+ assert.ok(
269
+ !existsSync(join(wtBase, '.gsd', 'milestones')),
270
+ 'empty legacy milestones/ root is not recreated in worktree',
271
+ );
272
+ } finally {
273
+ rmSync(mainBase, { recursive: true, force: true });
274
+ rmSync(wtBase, { recursive: true, force: true });
275
+ }
276
+ }
277
+
278
+ // ─── 7c. flat-phase sync skips metadata-only legacy milestone dirs ────
279
+ console.log('\n=== 7c. flat-phase sync skips metadata-only legacy milestone dirs ===');
280
+ {
281
+ const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-sync-flat-meta-main-'));
282
+ const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-sync-flat-meta-wt-'));
283
+
284
+ try {
285
+ const phaseDir = join(mainBase, '.gsd', 'phases', '01-foundation');
286
+ const metaDir = join(mainBase, '.gsd', 'milestones', 'M001');
287
+ mkdirSync(phaseDir, { recursive: true });
288
+ mkdirSync(metaDir, { recursive: true });
289
+ mkdirSync(join(wtBase, '.gsd'), { recursive: true });
290
+ writeFileSync(join(phaseDir, '01-CONTEXT.md'), '# Foundation\n');
291
+ writeFileSync(join(metaDir, 'M001-META.json'), '{"integrationBranch":"main"}\n');
292
+
293
+ syncGsdStateToWorktree(mainBase, wtBase);
294
+
295
+ assert.ok(
296
+ existsSync(join(wtBase, '.gsd', 'phases', '01-foundation', '01-CONTEXT.md')),
297
+ 'flat-phase artifact is synced to worktree',
298
+ );
299
+ assert.ok(
300
+ !existsSync(join(wtBase, '.gsd', 'milestones')),
301
+ 'metadata-only legacy milestones/ scaffold is not recreated in worktree',
302
+ );
303
+ } finally {
304
+ rmSync(mainBase, { recursive: true, force: true });
305
+ rmSync(wtBase, { recursive: true, force: true });
306
+ }
307
+ }
308
+
249
309
  // ─── 8. syncWorktreeStateBack does not copy task projections ───────────
250
310
  console.log('\n=== 8. syncWorktreeStateBack leaves task projections in worktree ===');
251
311
  {
@@ -13,6 +13,7 @@ import { GSD_PHASE_SCOPE_DISPLAY_REASON, GSD_SECTION_CLOSE_GATE_DISPLAY_REASON }
13
13
  import { ALLOWED_PLANNING_DISPATCH_AGENTS, shouldBlockPlanningUnit } from '../bootstrap/write-gate.ts';
14
14
  import { extractSubagentAgentClasses } from '../bootstrap/subagent-input.ts';
15
15
  import { isDeterministicPolicyError } from '../auto-tool-tracking.ts';
16
+ import { applyPlanningSubagentPreferences } from '../planning-subagent-policy.ts';
16
17
  import type { ToolsPolicy } from '../unit-context-manifest.ts';
17
18
 
18
19
  const BASE = join('/tmp', 'fake-project');
@@ -335,6 +336,39 @@ test('planning-dispatch: still allows writes inside .gsd/', () => {
335
336
  assert.strictEqual(r.block, false);
336
337
  });
337
338
 
339
+ test('planning_subagents: upgrades plan-milestone to controlled read-only dispatch', () => {
340
+ const policy = applyPlanningSubagentPreferences('plan-milestone', PLANNING, {
341
+ planning_subagents: {
342
+ 'plan-milestone': { allowed: ['security'] },
343
+ },
344
+ });
345
+ const allowed = shouldBlockPlanningUnit('subagent', '', BASE, 'plan-milestone', policy, ['security']);
346
+ assert.strictEqual(allowed.block, false);
347
+
348
+ const blocked = shouldBlockPlanningUnit('subagent', '', BASE, 'plan-milestone', policy, ['reviewer']);
349
+ assert.strictEqual(blocked.block, true);
350
+ assert.match(blocked.reason!, /planning_subagents/);
351
+ assert.match(blocked.reason!, /permitted agents for this unit: security/);
352
+ });
353
+
354
+ test('planning_subagents: widens plan-slice manifest allowlist without allowing unsafe agents', () => {
355
+ const policy = applyPlanningSubagentPreferences('plan-slice', {
356
+ mode: 'planning-dispatch',
357
+ allowedSubagents: ['scout', 'planner'],
358
+ }, {
359
+ planning_subagents: {
360
+ 'plan-slice': { allowed: ['security'] },
361
+ },
362
+ });
363
+
364
+ const added = shouldBlockPlanningUnit('subagent', '', BASE, 'plan-slice', policy, ['security']);
365
+ assert.strictEqual(added.block, false);
366
+
367
+ const unsafe = shouldBlockPlanningUnit('subagent', '', BASE, 'plan-slice', policy, ['worker']);
368
+ assert.strictEqual(unsafe.block, true);
369
+ assert.match(unsafe.reason!, /read-only specialists/);
370
+ });
371
+
338
372
  // ─── planning mode: pass-through tools ────────────────────────────────────
339
373
 
340
374
  test('planning-unit: allows read tool', () => {
@@ -26,6 +26,7 @@ import { tmpdir } from "node:os";
26
26
 
27
27
  import { registerHooks } from "../bootstrap/register-hooks.ts";
28
28
  import {
29
+ _setWriteGateInterleaveHookForTest,
29
30
  childWriteGateAdapter,
30
31
  clearDiscussionFlowState,
31
32
  getPendingGate,
@@ -36,6 +37,9 @@ import {
36
37
  setPendingGate,
37
38
  type WriteGateSnapshot,
38
39
  } from "../bootstrap/write-gate.ts";
40
+ import { acquireSyncLock, releaseSyncLock } from "../sync-lock.ts";
41
+
42
+ const WRITE_GATE_LOCK_NAME = "write-gate.lock";
39
43
 
40
44
  function makeTempDir(prefix: string): string {
41
45
  const dir = join(
@@ -356,3 +360,51 @@ test("seam: mutateWriteGateState reset path drops stale pendingGateId on a corru
356
360
  assert.equal(persisted.pendingGateId, null, "stale pending id must not be persisted after a corrupt-snapshot reconcile");
357
361
  assert.deepEqual(persisted.verifiedDepthMilestones, ["M099"]);
358
362
  });
363
+
364
+ // ── (f) cross-process lock closes the read-merge-write lost-update window ────
365
+
366
+ test("seam: read-merge-write holds the write-gate lock across the whole critical section", (t) => {
367
+ const dir = makeTempDir("lock-held");
368
+ t.after(() => {
369
+ _setWriteGateInterleaveHookForTest(null);
370
+ cleanup(dir);
371
+ });
372
+
373
+ // Fire inside the host's critical section, standing in for the OTHER process
374
+ // attempting to enter its own read-merge-write. The lock must lock it out.
375
+ let peerAcquiredMidSection: boolean | null = null;
376
+ _setWriteGateInterleaveHookForTest((lockRoot) => {
377
+ const res = acquireSyncLock(lockRoot, 0, WRITE_GATE_LOCK_NAME);
378
+ peerAcquiredMidSection = res.acquired;
379
+ if (res.acquired) releaseSyncLock(lockRoot, WRITE_GATE_LOCK_NAME);
380
+ });
381
+
382
+ markDepthVerified("M001", dir);
383
+
384
+ assert.equal(
385
+ peerAcquiredMidSection,
386
+ false,
387
+ "a concurrent process must be locked out of the read-merge-write section — this is what prevents the lost-update",
388
+ );
389
+ // The lock is released after the mutation, and the mutation still took effect.
390
+ assert.ok(loadWriteGateSnapshot(dir).verifiedDepthMilestones.includes("M001"));
391
+ assert.equal(acquireSyncLock(dir, 0, WRITE_GATE_LOCK_NAME).acquired, true, "lock released after mutation");
392
+ releaseSyncLock(dir, WRITE_GATE_LOCK_NAME);
393
+ });
394
+
395
+ test("seam: gate mutation fails OPEN when a live peer holds the lock (never blocks/refuses)", (t) => {
396
+ const dir = makeTempDir("lock-fail-open");
397
+ t.after(() => cleanup(dir));
398
+
399
+ // A live peer holds the lock (its own PID → never stolen as stale).
400
+ assert.equal(acquireSyncLock(dir, 0, WRITE_GATE_LOCK_NAME).acquired, true);
401
+ try {
402
+ // Host arms a gate while contended: fail-open means it proceeds anyway.
403
+ const armed = setPendingGate(GATE, dir);
404
+ assert.equal(armed, true, "arm must succeed (fail-open) even though the lock is held");
405
+ assert.equal(getPendingGate(dir), GATE);
406
+ assert.equal(readDiskRaw(dir).pendingGateId, GATE, "fail-open still persists the mutation");
407
+ } finally {
408
+ releaseSyncLock(dir, WRITE_GATE_LOCK_NAME);
409
+ }
410
+ });
@@ -29,10 +29,22 @@ import {
29
29
  deleteVerificationEvidence,
30
30
  saveGateResult,
31
31
  getPendingGatesForTurn,
32
+ getUnresolvedBlockingReworkFindingsForTask,
33
+ getBlockingReworkFindingsForTask,
34
+ applyReworkResolutions,
35
+ type ReworkFindingStatus,
32
36
  } from "../gsd-db.js";
33
37
  import { getWorkflowDatabasePath, ensureWorkflowDbAtPath } from "../db-workspace.js";
34
38
  import { getGatesForTurn } from "../gate-registry.js";
35
- import { gsdProjectionRoot, clearPathCache, resolveMilestonePath, resolveSlicePath } from "../paths.js";
39
+ import {
40
+ buildFlatTaskFileName,
41
+ buildTaskFileName,
42
+ gsdProjectionRoot,
43
+ clearPathCache,
44
+ legacyMilestonesDir,
45
+ resolveMilestonePath,
46
+ resolveSlicePath,
47
+ } from "../paths.js";
36
48
  import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
37
49
  import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
38
50
  import { saveFile, clearParseCache } from "../files.js";
@@ -85,13 +97,20 @@ function taskSummaryPath(
85
97
  // a legacy layout and breaks all subsequent path resolution for the session.
86
98
  const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
87
99
  const phaseDir = resolveMilestonePath(basePath, milestoneId);
88
- if (slicePath && phaseDir && slicePath !== phaseDir) {
89
- // Legacy layout: the slice has its own slices/SID/ subdir → tasks/ subdir
90
- return join(slicePath, "tasks", `${taskId}-SUMMARY.md`);
100
+ const legacyBase = legacyMilestonesDir(basePath);
101
+ const isLegacy = phaseDir
102
+ ? phaseDir.startsWith(legacyBase + "/") || phaseDir.startsWith(legacyBase + "\\")
103
+ : false;
104
+ if (isLegacy && phaseDir) {
105
+ // Legacy layout: the slice has its own slices/SID/ subdir → tasks/ subdir.
106
+ const legacySlicePath = slicePath && slicePath !== phaseDir
107
+ ? slicePath
108
+ : join(phaseDir, "slices", sliceId);
109
+ return join(legacySlicePath, "tasks", buildTaskFileName(taskId, "SUMMARY"));
91
110
  }
92
111
  if (phaseDir) {
93
112
  // Flat-phase: task summaries go in the phase dir (no tasks/ subdir)
94
- return join(phaseDir, `${taskId}-SUMMARY.md`);
113
+ return join(phaseDir, buildFlatTaskFileName(sliceId, taskId, "SUMMARY"));
95
114
  }
96
115
  // Fallback: legacy hardcoded path (milestone/slice dir not on disk yet)
97
116
  return join(
@@ -185,6 +204,70 @@ export function normalizeListParam(value: unknown): string[] {
185
204
  * Build a TaskRow-shaped object from CompleteTaskParams so the unified
186
205
  * renderSummaryContent() can be used at completion time (#2720).
187
206
  */
207
+
208
+ function normalizeReworkResolution(params: CompleteTaskParams): Array<{
209
+ milestoneId: string;
210
+ sliceId: string;
211
+ taskId: string;
212
+ findingId: string;
213
+ status: "resolved" | "deferred-with-override";
214
+ evidence: string;
215
+ decisionRef?: string;
216
+ }> {
217
+ return (params.reworkResolution ?? []).map((resolution) => ({
218
+ milestoneId: params.milestoneId,
219
+ sliceId: params.sliceId,
220
+ taskId: params.taskId,
221
+ findingId: resolution.findingId,
222
+ status: resolution.status,
223
+ evidence: resolution.evidence,
224
+ decisionRef: resolution.decisionRef,
225
+ }));
226
+ }
227
+
228
+ function unresolvedReworkError(missingFindingIds: string[]): string {
229
+ const plural = missingFindingIds.length === 1 ? "finding" : "findings";
230
+ return `unresolved blocking rework ${plural}: ${missingFindingIds.join(", ")} — provide reworkResolution entries with status resolved and evidence, or status deferred-with-override with evidence and decisionRef, before completing the task`;
231
+ }
232
+
233
+ function satisfiesBlockingReworkFinding(resolution: ReturnType<typeof normalizeReworkResolution>[number]): boolean {
234
+ if (resolution.evidence.trim().length === 0) return false;
235
+ if (resolution.status === "resolved") return true;
236
+ return (resolution.decisionRef ?? "").trim().length > 0;
237
+ }
238
+
239
+ /**
240
+ * Snapshot of a rework finding's status/evidence as it existed *before* this
241
+ * completion applied its reworkResolution. Captured inside the completion
242
+ * transaction so the compensating rollback paths can restore the exact prior
243
+ * state.
244
+ */
245
+ type ReworkFindingSnapshot = {
246
+ milestoneId: string;
247
+ sliceId: string;
248
+ taskId: string;
249
+ findingId: string;
250
+ status: ReworkFindingStatus;
251
+ evidence: string;
252
+ decisionRef?: string;
253
+ };
254
+
255
+ /**
256
+ * Restore rework findings to their pre-completion state.
257
+ *
258
+ * The completion transaction flips blocking findings to resolved/
259
+ * deferred-with-override via applyReworkResolutions. When a later projection
260
+ * or escalation write fails and we compensate by reverting the task to
261
+ * `pending`, we must also revert those findings. Otherwise a retry sees no
262
+ * unresolved blocking findings (getUnresolvedBlockingReworkFindingsForTask
263
+ * only returns `pending` rows) and completes the task with the blocking gate
264
+ * silently skipped.
265
+ */
266
+ function revertAppliedReworkResolutions(snapshot: ReworkFindingSnapshot[]): void {
267
+ if (snapshot.length === 0) return;
268
+ applyReworkResolutions(snapshot);
269
+ }
270
+
188
271
  function paramsToTaskRow(params: CompleteTaskParams, completedAt: string): TaskRow {
189
272
  return {
190
273
  milestone_id: params.milestoneId,
@@ -271,6 +354,7 @@ export async function handleCompleteTask(
271
354
  let guardError: string | null = null;
272
355
  let summaryMd = "";
273
356
  let repairTaskSummaryRow: TaskRow | null = null;
357
+ let appliedReworkSnapshot: ReworkFindingSnapshot[] = [];
274
358
  const rollbackDbPath = getWorkflowDatabasePath();
275
359
 
276
360
  // ── ADR-011 Phase 2: validate escalation payload BEFORE any side effects ─
@@ -282,6 +366,8 @@ export async function handleCompleteTask(
282
366
  // no escalation recorded, and the loop would silently advance past it.
283
367
  // The filesystem write happens later (after side effects) because that's
284
368
  // the cheapest ordering and validation is where 99% of failures live.
369
+ const reworkResolutions = normalizeReworkResolution(params);
370
+
285
371
  let validatedEscalationArtifact: ReturnType<typeof buildEscalationArtifact> | null = null;
286
372
  let escalationWriteEnabled = false;
287
373
  if (params.escalation) {
@@ -323,6 +409,20 @@ export async function handleCompleteTask(
323
409
  }
324
410
 
325
411
  const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
412
+ const unresolvedRework = getUnresolvedBlockingReworkFindingsForTask(params.milestoneId, params.sliceId, params.taskId);
413
+ const resolvedFindingIds = new Set(
414
+ reworkResolutions
415
+ .filter(satisfiesBlockingReworkFinding)
416
+ .map((resolution) => resolution.findingId),
417
+ );
418
+ const missingFindingIds = unresolvedRework
419
+ .filter((finding) => !resolvedFindingIds.has(finding.finding_id))
420
+ .map((finding) => finding.finding_id);
421
+ if (missingFindingIds.length > 0) {
422
+ guardError = unresolvedReworkError(missingFindingIds);
423
+ return;
424
+ }
425
+
326
426
  if (existingTask && isClosedStatus(existingTask.status)) {
327
427
  // Stale-turn path: a timed-out turn that was superseded by recovery
328
428
  // can still reach this code when its LLM call eventually returns and
@@ -378,6 +478,38 @@ export async function handleCompleteTask(
378
478
  fullSummaryMd: summaryMd,
379
479
  });
380
480
 
481
+ // Only persist resolutions that actually satisfy the evidence
482
+ // requirement. The guard above admits a finding as long as ONE satisfying
483
+ // entry exists, but applyReworkResolutions writes by findingId and lets the
484
+ // last entry win. Persisting every entry would let a later non-satisfying
485
+ // duplicate (empty evidence, or deferred-with-override without decisionRef)
486
+ // overwrite a valid resolution and leave the finding non-pending without
487
+ // acceptable evidence. Filtering with the same predicate the guard uses
488
+ // keeps the applied set and the gate consistent.
489
+ const resolutionsToApply = reworkResolutions.filter(satisfiesBlockingReworkFinding);
490
+ if (resolutionsToApply.length > 0) {
491
+ // Snapshot the pre-resolution state of the findings we're about to
492
+ // change so a compensating rollback can restore them exactly (see
493
+ // revertAppliedReworkResolutions).
494
+ const resolvedFindingIdsForSnapshot = new Set(resolutionsToApply.map((r) => r.findingId));
495
+ appliedReworkSnapshot = getBlockingReworkFindingsForTask(
496
+ params.milestoneId,
497
+ params.sliceId,
498
+ params.taskId,
499
+ )
500
+ .filter((finding) => resolvedFindingIdsForSnapshot.has(finding.finding_id))
501
+ .map((finding) => ({
502
+ milestoneId: params.milestoneId,
503
+ sliceId: params.sliceId,
504
+ taskId: params.taskId,
505
+ findingId: finding.finding_id,
506
+ status: finding.status,
507
+ evidence: finding.evidence,
508
+ decisionRef: finding.decision_ref,
509
+ }));
510
+ applyReworkResolutions(resolutionsToApply);
511
+ }
512
+
381
513
  for (const evidence of (params.verificationEvidence ?? [])) {
382
514
  insertVerificationEvidence({
383
515
  taskId: params.taskId,
@@ -459,6 +591,7 @@ export async function handleCompleteTask(
459
591
  ensureWorkflowDbAtPath(rollbackDbPath);
460
592
  deleteVerificationEvidence(params.milestoneId, params.sliceId, params.taskId);
461
593
  updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, "pending");
594
+ revertAppliedReworkResolutions(appliedReworkSnapshot);
462
595
  invalidateStateCache();
463
596
  rollbackSucceeded = true;
464
597
  } catch (rollbackErr) {
@@ -559,6 +692,7 @@ export async function handleCompleteTask(
559
692
  try {
560
693
  deleteVerificationEvidence(params.milestoneId, params.sliceId, params.taskId);
561
694
  updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, 'pending');
695
+ revertAppliedReworkResolutions(appliedReworkSnapshot);
562
696
  invalidateStateCache();
563
697
  logWarning(
564
698
  "tool",
@@ -580,6 +714,7 @@ export async function handleCompleteTask(
580
714
  try {
581
715
  deleteVerificationEvidence(params.milestoneId, params.sliceId, params.taskId);
582
716
  updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, 'pending');
717
+ revertAppliedReworkResolutions(appliedReworkSnapshot);
583
718
  invalidateStateCache();
584
719
  logWarning(
585
720
  "tool",
@@ -5,7 +5,7 @@ import { getGateIdsForTurn } from "../gate-registry.js";
5
5
  import { transaction, getSlice, getTask, insertTask, upsertTaskPlanning, insertGateRow, setSliceSketchFlag } from "../gsd-db.js";
6
6
  import { invalidateStateCache } from "../state.js";
7
7
  import { renderTaskPlanFromDb, renderPlanFromDb } from "../markdown-renderer.js";
8
- import { resolveTasksDir } from "../paths.js";
8
+ import { resolveMilestonePath, resolveSlicePath } from "../paths.js";
9
9
  import { flushWorkflowProjections } from "../projection-flush.js";
10
10
  import { writeManifest } from "../workflow-manifest.js";
11
11
  import { appendEvent } from "../workflow-events.js";
@@ -255,21 +255,19 @@ export async function handlePlanTask(
255
255
  }
256
256
 
257
257
  try {
258
- const renderResult = await renderTaskPlanFromDb(basePath, params.milestoneId, params.sliceId, params.taskId);
259
-
260
- // Flat-phase: tasks live as checkboxes in the slice plan's <tasks> block,
261
- // not as standalone TID-PLAN.md files. Re-render the slice plan so the
262
- // new/updated task appears in the plan file that gsd-core reads.
263
- // Guard: resolveTasksDir is null in flat-phase (no tasks/ subdir exists).
258
+ const milestonePath = resolveMilestonePath(basePath, params.milestoneId);
259
+ const slicePath = resolveSlicePath(basePath, params.milestoneId, params.sliceId);
260
+ const isLegacySliceLayout = Boolean(milestonePath && slicePath && slicePath !== milestonePath);
261
+ let renderedPath: string;
264
262
  let slicePlanSynced = false;
265
- try {
266
- const tDir = resolveTasksDir(basePath, params.milestoneId, params.sliceId);
267
- if (!tDir) {
268
- await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
269
- slicePlanSynced = true;
270
- }
271
- } catch (syncErr) {
272
- logWarning("tool", `plan-task: slice-plan sync failed: ${(syncErr as Error).message}`);
263
+
264
+ if (isLegacySliceLayout) {
265
+ const renderResult = await renderTaskPlanFromDb(basePath, params.milestoneId, params.sliceId, params.taskId);
266
+ renderedPath = renderResult.taskPlanPath;
267
+ } else {
268
+ const renderResult = await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
269
+ renderedPath = renderResult.planPath;
270
+ slicePlanSynced = true;
273
271
  }
274
272
 
275
273
  if (slicePlanSynced) {
@@ -299,7 +297,7 @@ export async function handlePlanTask(
299
297
  milestoneId: params.milestoneId,
300
298
  sliceId: params.sliceId,
301
299
  taskId: params.taskId,
302
- taskPlanPath: renderResult.taskPlanPath,
300
+ taskPlanPath: renderedPath,
303
301
  };
304
302
  } catch (err) {
305
303
  return { error: `render failed: ${(err as Error).message}` };