@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
@@ -26,6 +26,7 @@ import {
26
26
  buildPlanMilestonePrompt,
27
27
  buildPlanSlicePrompt,
28
28
  buildSkillActivationBlock,
29
+ capPreamble,
29
30
  } from "./auto-prompts.js";
30
31
  import { deriveState, isGhostMilestone } from "./state.js";
31
32
  import { invalidateAllCaches } from "./cache.js";
@@ -864,6 +865,13 @@ export function getDiscussableFutureMilestones<T extends { id: string; status: s
864
865
  );
865
866
  }
866
867
 
868
+ function findDiscussTargetMilestone(
869
+ registry: GSDState["registry"],
870
+ milestoneId: string,
871
+ ): GSDState["registry"][number] | undefined {
872
+ return registry.find((m) => m.id === milestoneId || m.id.startsWith(`${milestoneId}-`));
873
+ }
874
+
867
875
  function getStructuredQuestionsAvailability(
868
876
  pi: ExtensionAPI,
869
877
  ctx: ExtensionContext | undefined,
@@ -1192,7 +1200,9 @@ function resolveDiscussSliceBasePath(basePath: string, milestoneId: string): str
1192
1200
  * slice summaries so the agent can ask grounded UX/behaviour questions
1193
1201
  * without wasting a turn reading files.
1194
1202
  */
1195
- async function buildDiscussSlicePrompt(
1203
+ // Exported for tests (`prompt-budget-enforcement.test.ts`) — verifies the
1204
+ // inlined-context cap. Not part of the public flow surface otherwise.
1205
+ export async function buildDiscussSlicePrompt(
1196
1206
  mid: string,
1197
1207
  sid: string,
1198
1208
  sTitle: string,
@@ -1255,8 +1265,12 @@ async function buildDiscussSlicePrompt(
1255
1265
  }
1256
1266
  }
1257
1267
 
1268
+ // Cap the inlined block: it grows unbounded with each completed slice's full
1269
+ // SUMMARY. `capPreamble` truncates at `### ` section boundaries — roadmap and
1270
+ // milestone context come first (survive), completed-slice summaries come last
1271
+ // (dropped first) when the executor's window can't hold everything.
1258
1272
  const inlinedContext = inlined.length > 0
1259
- ? `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`
1273
+ ? capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`)
1260
1274
  : `## Inlined Context\n\n_(no context files found yet — go in blind and ask broad questions)_`;
1261
1275
 
1262
1276
  const sliceDirPath = `.gsd/milestones/${mid}/slices/${sid}`;
@@ -1268,7 +1282,7 @@ async function buildDiscussSlicePrompt(
1268
1282
  : "";
1269
1283
 
1270
1284
  const inlinedTemplates = inlineTemplate("slice-context", "Slice Context");
1271
- return loadPrompt("guided-discuss-slice", {
1285
+ return prependLanguageDirective(base, loadPrompt("guided-discuss-slice", {
1272
1286
  milestoneId: mid,
1273
1287
  sliceId: sid,
1274
1288
  sliceTitle: sTitle,
@@ -1279,7 +1293,7 @@ async function buildDiscussSlicePrompt(
1279
1293
  inlinedTemplates,
1280
1294
  structuredQuestionsAvailable: options?.structuredQuestionsAvailable ?? "false",
1281
1295
  commitInstruction: buildDocsCommitInstruction(`docs(${mid}/${sid}): slice context from discuss`),
1282
- });
1296
+ }));
1283
1297
  }
1284
1298
 
1285
1299
  /**
@@ -1333,12 +1347,23 @@ export async function showDiscuss(
1333
1347
  if (slash > 0) {
1334
1348
  const mid = target.slice(0, slash);
1335
1349
  const sid = target.slice(slash + 1);
1336
- const targetMilestone = state.registry.find((m) => m.id === mid);
1337
- if (!targetMilestone || targetMilestone.status === "complete" || targetMilestone.status === "parked") {
1338
- ctx.ui.notify(`Milestone ${mid} is not discussable.`, "warning");
1350
+ const targetMilestone = findDiscussTargetMilestone(state.registry, mid);
1351
+ if (!targetMilestone) {
1352
+ ctx.ui.notify(
1353
+ `Milestone ${mid} was not found in the roadmap. Use /gsd new-milestone to add it, or /gsd status to see available milestones.`,
1354
+ "warning",
1355
+ );
1356
+ return;
1357
+ }
1358
+ if (targetMilestone.status === "complete") {
1359
+ ctx.ui.notify(`Milestone ${targetMilestone.id} is already complete.`, "info");
1360
+ return;
1361
+ }
1362
+ if (targetMilestone.status === "parked") {
1363
+ ctx.ui.notify(`Milestone ${targetMilestone.id} is parked. Run /gsd unpark ${targetMilestone.id} to reactivate.`, "warning");
1339
1364
  return;
1340
1365
  }
1341
- const slices = await loadDiscussNormSlices(basePath, mid);
1366
+ const slices = await loadDiscussNormSlices(basePath, targetMilestone.id);
1342
1367
  const chosen = slices.find((s) => s.id.toUpperCase() === sid.toUpperCase());
1343
1368
  if (!chosen) {
1344
1369
  ctx.ui.notify(`Slice ${target} was not found in discussable slices.`, "warning");
@@ -1348,10 +1373,10 @@ export async function showDiscuss(
1348
1373
  ctx.ui.notify(`Slice ${target} is already complete; nothing to discuss.`, "info");
1349
1374
  return;
1350
1375
  }
1351
- const discussBasePath = resolveDiscussSliceBasePath(basePath, mid);
1352
- const contextFile = resolveSliceFile(discussBasePath, mid, sid, "CONTEXT");
1376
+ const discussBasePath = resolveDiscussSliceBasePath(basePath, targetMilestone.id);
1377
+ const contextFile = resolveSliceFile(discussBasePath, targetMilestone.id, sid, "CONTEXT");
1353
1378
  const sqAvail = getStructuredQuestionsAvailability(pi, ctx);
1354
- const prompt = await buildDiscussSlicePrompt(mid, sid, chosen.title, discussBasePath, {
1379
+ const prompt = await buildDiscussSlicePrompt(targetMilestone.id, sid, chosen.title, discussBasePath, {
1355
1380
  rediscuss: !!contextFile,
1356
1381
  structuredQuestionsAvailable: sqAvail,
1357
1382
  });
@@ -1359,9 +1384,20 @@ export async function showDiscuss(
1359
1384
  return;
1360
1385
  }
1361
1386
 
1362
- const targetMilestone = state.registry.find((m) => m.id === target);
1363
- if (!targetMilestone || targetMilestone.status === "complete" || targetMilestone.status === "parked") {
1364
- ctx.ui.notify(`Milestone ${target} is not discussable.`, "warning");
1387
+ const targetMilestone = findDiscussTargetMilestone(state.registry, target);
1388
+ if (!targetMilestone) {
1389
+ ctx.ui.notify(
1390
+ `Milestone ${target} was not found in the roadmap. Use /gsd new-milestone to add it, or /gsd status to see available milestones.`,
1391
+ "warning",
1392
+ );
1393
+ return;
1394
+ }
1395
+ if (targetMilestone.status === "complete") {
1396
+ ctx.ui.notify(`Milestone ${targetMilestone.id} is already complete.`, "info");
1397
+ return;
1398
+ }
1399
+ if (targetMilestone.status === "parked") {
1400
+ ctx.ui.notify(`Milestone ${targetMilestone.id} is parked. Run /gsd unpark ${targetMilestone.id} to reactivate.`, "warning");
1365
1401
  return;
1366
1402
  }
1367
1403
  await dispatchDiscussForMilestone(ctx, pi, basePath, targetMilestone.id, targetMilestone.title, {});
@@ -12,7 +12,7 @@
12
12
  import { readFileSync, existsSync, mkdirSync, statSync, unlinkSync } from "node:fs";
13
13
  import { logWarning } from "./workflow-logger.js";
14
14
  import { isClosedStatus } from "./status-guards.js";
15
- import { dirname, join, relative } from "node:path";
15
+ import { dirname, join } from "node:path";
16
16
  import {
17
17
  getAllMilestones,
18
18
  getMilestone,
@@ -40,6 +40,7 @@ import {
40
40
  resolveTasksDir,
41
41
  targetMilestoneFile,
42
42
  targetSliceFile,
43
+ targetTaskFile,
43
44
  gsdProjectionRoot,
44
45
  gsdRoot,
45
46
  buildTaskFileName,
@@ -49,7 +50,7 @@ import { saveFile, clearParseCache, registerCacheClearCallback } from "./files.j
49
50
  import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
50
51
  import { invalidateStateCache } from "./state.js";
51
52
  import { clearPathCache, milestonesDir, legacyMilestonesDir, isLegacyMilestonesLayout, resolveMilestonePath, relSliceFile, canonicalPhaseDirName } from "./paths.js";
52
- import { readCompatMarker, writeCompatMarker, computeProjectionSha } from "./compat/compat-marker.js";
53
+ import { readCompatMarker, writeCompatMarker, computeProjectionSha, deriveCompatProjectionKey } from "./compat/compat-marker.js";
53
54
  import type { RiskLevel } from "./types.js";
54
55
  import {
55
56
  phaseDirName,
@@ -108,13 +109,7 @@ function flushProjectionWritesToMarker(): void {
108
109
  */
109
110
  function toArtifactPath(absPath: string, basePath: string): string {
110
111
  const projectionRoot = gsdProjectionRoot(basePath);
111
- const projectionRel = relative(projectionRoot, absPath);
112
- const root = projectionRel && !projectionRel.startsWith("..") && !projectionRel.startsWith("/")
113
- ? projectionRoot
114
- : gsdRoot(basePath);
115
- const rel = relative(root, absPath);
116
- // Normalize to forward slashes for consistent DB keys
117
- return rel.replace(/\\/g, "/");
112
+ return deriveCompatProjectionKey(absPath, [projectionRoot, gsdRoot(basePath)]);
118
113
  }
119
114
 
120
115
  /**
@@ -756,20 +751,7 @@ export async function renderTaskSummary(
756
751
  return false; // No summary to render — skip silently
757
752
  }
758
753
 
759
- // Resolve the tasks directory, creating path if needed
760
- const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
761
- if (!slicePath) {
762
- process.stderr.write(
763
- `markdown-renderer: cannot resolve slice path for ${milestoneId}/${sliceId}\n`,
764
- );
765
- return false;
766
- }
767
-
768
- // Use the tasks/ subdir when it exists (legacy layout), otherwise use the
769
- // slice path directly (flat-phase: task summaries live alongside plan files).
770
- const tasksDir = resolveTasksDir(basePath, milestoneId, sliceId) ?? slicePath;
771
- const fileName = buildTaskFileName(taskId, "SUMMARY");
772
- const absPath = join(tasksDir, fileName);
754
+ const absPath = targetTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY", getMilestone(milestoneId)?.title);
773
755
  const artifactPath = toArtifactPath(absPath, basePath);
774
756
 
775
757
  await writeAndStore(absPath, artifactPath, task.full_summary_md, {
@@ -1208,6 +1190,21 @@ export interface AssessmentData {
1208
1190
  completedSliceId?: string;
1209
1191
  }
1210
1192
 
1193
+ function existingLegacySliceAssessmentPath(
1194
+ basePath: string,
1195
+ milestoneId: string,
1196
+ sliceId: string,
1197
+ ): string | null {
1198
+ if (!isLegacyMilestonesLayout(basePath)) return null;
1199
+ const legacyBase = legacyMilestonesDir(basePath);
1200
+ const milestoneDirName = resolveDir(legacyBase, milestoneId);
1201
+ if (!milestoneDirName) return null;
1202
+ const slicesDir = join(legacyBase, milestoneDirName, "slices");
1203
+ const sliceDirName = resolveDir(slicesDir, sliceId);
1204
+ if (!sliceDirName) return null;
1205
+ return join(slicesDir, sliceDirName, `${sliceId}-ASSESSMENT.md`);
1206
+ }
1207
+
1211
1208
  export async function renderReplanFromDb(
1212
1209
  basePath: string,
1213
1210
  milestoneId: string,
@@ -1258,13 +1255,14 @@ export async function renderAssessmentFromDb(
1258
1255
  sliceId: string,
1259
1256
  assessmentData: AssessmentData,
1260
1257
  ): Promise<{ assessmentPath: string; content: string }> {
1261
- const absPath = targetSliceFile(
1262
- basePath,
1263
- milestoneId,
1264
- sliceId,
1265
- "ASSESSMENT",
1266
- getMilestone(milestoneId)?.title,
1267
- );
1258
+ const absPath = existingLegacySliceAssessmentPath(basePath, milestoneId, sliceId)
1259
+ ?? targetSliceFile(
1260
+ basePath,
1261
+ milestoneId,
1262
+ sliceId,
1263
+ "ASSESSMENT",
1264
+ getMilestone(milestoneId)?.title,
1265
+ );
1268
1266
  mkdirSync(dirname(absPath), { recursive: true });
1269
1267
  const artifactPath = toArtifactPath(absPath, basePath);
1270
1268
 
@@ -17,6 +17,8 @@ import {
17
17
  transaction,
18
18
  updateMilestoneStatus,
19
19
  updateSliceStatus,
20
+ getMilestoneSlices,
21
+ getSliceTasks,
20
22
  _getAdapter,
21
23
  } from './gsd-db.js';
22
24
  import { openWorkflowDatabasePath } from './db-workspace.js';
@@ -29,6 +31,7 @@ import {
29
31
  legacyMilestonesDir,
30
32
  gsdRoot,
31
33
  resolveTaskFiles,
34
+ resolveTaskFile,
32
35
  resolveMilestonePath,
33
36
  } from './paths.js';
34
37
  import { findMilestoneIds } from './guided-flow.js';
@@ -43,6 +46,26 @@ const VALID_MADE_BY = new Set(['human', 'agent', 'collaborative']);
43
46
 
44
47
  const IMPORT_COMPLETE_STATUSES = new Set(['complete', 'done']);
45
48
 
49
+ /**
50
+ * Derive the set of milestone ids a projection entry's `entities` touch. Marker
51
+ * entity ids are fully-qualified DB ids (`M001`, `M001/S01`, `M001/S01/T01`), so
52
+ * the milestone id is always the first `/`-segment — independent of the on-disk
53
+ * layout (legacy `milestones/<MID>/…` vs flat `phases/NN-slug/…`). The
54
+ * external-edit drift repairs (#027) feed this into
55
+ * `migrateHierarchyToDb(..., { statusAuthoritativeMilestones })` to scope status
56
+ * authority to exactly the milestone(s) a drifted file projects. Empty/blank
57
+ * entries are dropped, so an entity-less entry yields an empty set (repair then
58
+ * preserves DB status everywhere — fail toward the DB, not markdown).
59
+ */
60
+ export function milestoneIdsFromEntities(entities: readonly string[]): Set<string> {
61
+ const ids = new Set<string>();
62
+ for (const e of entities) {
63
+ const milestoneId = e.split('/')[0];
64
+ if (milestoneId) ids.add(milestoneId);
65
+ }
66
+ return ids;
67
+ }
68
+
46
69
  /**
47
70
  * Completion timestamp for an entity imported as complete: the SUMMARY.md mtime
48
71
  * when one exists (deterministic, matches the completion drift handler), else
@@ -676,15 +699,35 @@ function findFileByPrefixAndSuffix(dir: string, idPrefix: string, suffix: string
676
699
  * Uses INSERT OR IGNORE for idempotency. Insert order: milestones → slices → tasks.
677
700
  * Ghost milestones (dirs with no CONTEXT, ROADMAP, or SUMMARY) are skipped.
678
701
  *
702
+ * `opts.statusAuthoritativeMilestones` narrows *status* authority. It exists for
703
+ * the scoped external-edit drift repair: detection knows exactly which
704
+ * projection file drifted, but this import walks the whole tree. Without scoping,
705
+ * an unrelated file that is stale from gsd-pi's own miss (a forgotten render)
706
+ * rides along with markdown authority it was never granted and its stale checked
707
+ * checkbox silently reverts a reopened slice/milestone in the DB (#027).
708
+ *
709
+ * - opts absent → full markdown authority for every milestone (initial migration,
710
+ * gsd-core full import, /gsd recover rebuild). Behavior is identical to before.
711
+ * - opts present → for a milestone NOT in the set whose DB row *already exists*,
712
+ * the existing DB status is preserved: the slice upsert is fed the current DB
713
+ * status (so a stale `complete` checkbox can't overwrite a reopened `pending`),
714
+ * and the complete-status backfills are skipped. Milestone rows are already
715
+ * protected by INSERT OR IGNORE. Rows that do not exist yet are inserted with
716
+ * the parsed status regardless of scope (new content is new content).
717
+ *
679
718
  * Returns count of inserted hierarchy items.
680
719
  */
681
- export function migrateHierarchyToDb(basePath: string): {
720
+ export function migrateHierarchyToDb(
721
+ basePath: string,
722
+ opts?: { statusAuthoritativeMilestones?: ReadonlySet<string> },
723
+ ): {
682
724
  milestones: number;
683
725
  slices: number;
684
726
  tasks: number;
685
727
  } {
686
728
  const counts = { milestones: 0, slices: 0, tasks: 0 };
687
729
  const milestoneIds = findMilestoneIds(basePath);
730
+ const statusScope = opts?.statusAuthoritativeMilestones;
688
731
 
689
732
  for (const milestoneId of milestoneIds) {
690
733
  // Check for ghost milestones — skip dirs with no meaningful content
@@ -745,8 +788,30 @@ export function migrateHierarchyToDb(basePath: string): {
745
788
  }
746
789
  }
747
790
 
748
- // Insert milestone (FK parent must come first)
749
- insertMilestone({
791
+ // #027: when a status scope is supplied, a milestone outside it keeps DB
792
+ // status authority for rows that already exist — only the drifted file's
793
+ // milestone(s) may drive status closes from checkboxes. Absent scope, every
794
+ // milestone is authoritative (unchanged full-import behavior).
795
+ const milestoneStatusAuthoritative = !statusScope || statusScope.has(milestoneId);
796
+ // Snapshot existing slice statuses once (only needed when preserving DB
797
+ // authority for this milestone) so the upsert can echo them back instead of
798
+ // flipping an open slice closed from a stale checkbox.
799
+ const existingSliceStatus = new Map<string, string>();
800
+ const existingTaskStatus = new Map<string, string>();
801
+ if (!milestoneStatusAuthoritative) {
802
+ for (const s of getMilestoneSlices(milestoneId)) {
803
+ existingSliceStatus.set(s.id, s.status);
804
+ for (const t of getSliceTasks(milestoneId, s.id)) {
805
+ existingTaskStatus.set(`${s.id}/${t.id}`, t.status);
806
+ }
807
+ }
808
+ }
809
+
810
+ // Insert milestone (FK parent — must come first). INSERT OR IGNORE: an
811
+ // existing milestone row is never overwritten, so DB status is already
812
+ // preserved for out-of-scope milestones. `inserted` tells us whether this
813
+ // row is new (parsed status applies) vs pre-existing (backfill gated below).
814
+ const milestoneInserted = insertMilestone({
750
815
  id: milestoneId,
751
816
  title: milestoneTitle,
752
817
  status: milestoneStatus,
@@ -760,10 +825,14 @@ export function migrateHierarchyToDb(basePath: string): {
760
825
  // insertMilestone never sets completed_at; backfill it now for milestones
761
826
  // imported as complete so the DB is internally coherent immediately after
762
827
  // import (rather than relying on a later reconciliation pass that can't even
763
- // see the drift when no SUMMARY file exists).
764
- if (IMPORT_COMPLETE_STATUSES.has(milestoneStatus)) {
828
+ // see the drift when no SUMMARY file exists). #027: skip the backfill for an
829
+ // out-of-scope milestone that already existed — its DB status is authoritative.
830
+ if (IMPORT_COMPLETE_STATUSES.has(milestoneStatus) && (milestoneStatusAuthoritative || milestoneInserted)) {
765
831
  const summaryPath = resolveMilestoneFile(basePath, milestoneId, 'SUMMARY');
766
- updateMilestoneStatus(milestoneId, milestoneStatus, importCompletionTimestamp(summaryPath));
832
+ // #1291: preserve an existing completion timestamp so a re-import backfills
833
+ // only rows that lack one, never re-stamping an already-complete milestone
834
+ // with the current import time. Same guard as the task path below.
835
+ updateMilestoneStatus(milestoneId, milestoneStatus, importCompletionTimestamp(summaryPath), true);
767
836
  }
768
837
  counts.milestones++;
769
838
 
@@ -783,11 +852,22 @@ export function migrateHierarchyToDb(basePath: string): {
783
852
  plan = parsePlan(planContent);
784
853
  }
785
854
 
855
+ // #027: for an out-of-scope milestone, echo the existing DB status of a
856
+ // slice that already exists so the upsert's `ELSE excluded.status` branch
857
+ // becomes a no-op instead of flipping a reopened `pending` slice back to
858
+ // `complete` from a stale checkbox. New slices (not yet in the DB) take the
859
+ // parsed status regardless of scope.
860
+ const sliceRowExists = existingSliceStatus.has(sliceEntry.id);
861
+ const sliceStatusAuthoritative = milestoneStatusAuthoritative || !sliceRowExists;
862
+ const effectiveSliceStatus = sliceStatusAuthoritative
863
+ ? sliceStatus
864
+ : existingSliceStatus.get(sliceEntry.id)!;
865
+
786
866
  insertSlice({
787
867
  id: sliceEntry.id,
788
868
  milestoneId: milestoneId,
789
869
  title: sliceEntry.title,
790
- status: sliceStatus,
870
+ status: effectiveSliceStatus,
791
871
  risk: sliceEntry.risk,
792
872
  depends: (sliceEntry.depends ?? []).map(d => d.replace(/^\[|\]$/g, '')).filter(d => /^[A-Za-z0-9][A-Za-z0-9-]*$/.test(d)),
793
873
  demo: sliceEntry.demo,
@@ -798,14 +878,19 @@ export function migrateHierarchyToDb(basePath: string): {
798
878
  },
799
879
  });
800
880
  // insertSlice never sets completed_at; backfill it for slices imported as
801
- // complete (same rationale as milestones above).
802
- if (IMPORT_COMPLETE_STATUSES.has(sliceStatus)) {
881
+ // complete (same rationale as milestones above). #027: skip when preserving
882
+ // an out-of-scope slice's existing DB status.
883
+ if (IMPORT_COMPLETE_STATUSES.has(sliceStatus) && sliceStatusAuthoritative) {
803
884
  const sliceSummary = resolveSliceFile(basePath, milestoneId, sliceEntry.id, 'SUMMARY');
885
+ // #1291: preserve an existing completion timestamp so a re-import backfills
886
+ // only slices that lack one, never re-stamping an already-complete slice
887
+ // with the current import time. Same guard as the task path below.
804
888
  updateSliceStatus(
805
889
  milestoneId,
806
890
  sliceEntry.id,
807
891
  sliceStatus,
808
892
  importCompletionTimestamp(sliceSummary),
893
+ true,
809
894
  );
810
895
  }
811
896
  counts.slices++;
@@ -841,8 +926,7 @@ export function migrateHierarchyToDb(basePath: string): {
841
926
  legacyTasksDir = isLegacySlice
842
927
  ? resolveTasksDir(basePath, milestoneId, sliceEntry.id)
843
928
  : null;
844
- const summaryDir = legacyTasksDir ?? slicePath;
845
- taskSummaryFile = join(summaryDir, `${taskEntry.id}-SUMMARY.md`);
929
+ taskSummaryFile = resolveTaskFile(basePath, milestoneId, sliceEntry.id, taskEntry.id, 'SUMMARY');
846
930
  }
847
931
  const hasTaskSummary = taskSummaryFile !== null && existsSync(taskSummaryFile);
848
932
 
@@ -866,9 +950,9 @@ export function migrateHierarchyToDb(basePath: string): {
866
950
  // first execute-task. The surviving SUMMARY wins over a stale checkbox.
867
951
  // reopen-task removes the SUMMARY, so this never re-completes an
868
952
  // intentionally reopened task.
869
- // Flat-phase summaries are phase-scoped (T01-SUMMARY.md); when a milestone
870
- // has multiple slices, require the summary parent frontmatter to match so
871
- // one slice's completion does not attest a sibling's same-named task.
953
+ // Flat-phase summaries are phase-scoped; when a milestone has multiple
954
+ // slices, require the summary parent frontmatter to match so one slice's
955
+ // completion does not attest a sibling's same-named task.
872
956
  let summaryAttestsCompletion = hasTaskSummary;
873
957
  if (summaryAttestsCompletion && !isLegacySlice && roadmap.slices.length > 1 && taskSummaryFile) {
874
958
  try {
@@ -885,12 +969,20 @@ export function migrateHierarchyToDb(basePath: string): {
885
969
  );
886
970
  }
887
971
 
972
+ // #027: same scope guard as slices — out-of-scope milestones echo existing
973
+ // DB task status so stale plan checkboxes cannot re-complete reopened tasks.
974
+ const taskRowExists = existingTaskStatus.has(`${sliceEntry.id}/${taskEntry.id}`);
975
+ const taskStatusAuthoritative = milestoneStatusAuthoritative || !taskRowExists;
976
+ const effectiveTaskStatus = taskStatusAuthoritative
977
+ ? taskStatus
978
+ : existingTaskStatus.get(`${sliceEntry.id}/${taskEntry.id}`)!;
979
+
888
980
  insertTask({
889
981
  id: taskEntry.id,
890
982
  sliceId: sliceEntry.id,
891
983
  milestoneId: milestoneId,
892
984
  title: taskEntry.title,
893
- status: taskStatus,
985
+ status: effectiveTaskStatus,
894
986
  planning: {
895
987
  files: taskEntry.files ?? [],
896
988
  verify: taskEntry.verify ?? '',
@@ -940,13 +1032,19 @@ export function migrateHierarchyToDb(basePath: string): {
940
1032
  // checkbox (#1222); flat-phase checkboxes are authoritative without summary.
941
1033
  return summaryAttestsCompletion || (t.done && !isLegacySliceLayout);
942
1034
  });
943
- if (allTasksDone && hasSliceSummary) {
1035
+ // #027: the same close guard as the backfill above — a stale slice
1036
+ // SUMMARY under an out-of-scope milestone must not upgrade a reopened
1037
+ // slice to complete. New slices stay authoritative.
1038
+ if (allTasksDone && hasSliceSummary && sliceStatusAuthoritative) {
944
1039
  if (_getAdapter()) {
1040
+ // #1291: preserve an existing completion timestamp — this consistency
1041
+ // upgrade sets a completion time only when the row lacks one.
945
1042
  updateSliceStatus(
946
1043
  milestoneId,
947
1044
  sliceEntry.id,
948
1045
  'complete',
949
1046
  importCompletionTimestamp(sliceSummaryPath),
1047
+ true,
950
1048
  );
951
1049
  process.stderr.write(
952
1050
  `gsd-migrate: ${milestoneId}/${sliceEntry.id} all tasks + slice summary complete — upgrading slice to complete\n`,