@opengsd/gsd-pi 1.5.0 → 1.6.0

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 (499) hide show
  1. package/README.md +10 -10
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/ask-user-questions.js +1 -1
  4. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +114 -36
  5. package/dist/resources/extensions/gsd/activity-log.js +1 -1
  6. package/dist/resources/extensions/gsd/auto/closeout.js +97 -5
  7. package/dist/resources/extensions/gsd/auto/orchestrator.js +20 -13
  8. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
  9. package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
  10. package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -5
  11. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +69 -17
  13. package/dist/resources/extensions/gsd/auto-model-selection.js +28 -1
  14. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
  15. package/dist/resources/extensions/gsd/auto-prompts.js +29 -117
  16. package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
  17. package/dist/resources/extensions/gsd/auto-start.js +57 -33
  18. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +12 -2
  19. package/dist/resources/extensions/gsd/auto-timers.js +9 -2
  20. package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
  21. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
  22. package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
  23. package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
  24. package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
  25. package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
  26. package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
  27. package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
  28. package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
  30. package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
  31. package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
  32. package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
  33. package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
  34. package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
  35. package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
  36. package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
  37. package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
  38. package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
  39. package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
  40. package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
  41. package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
  42. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
  43. package/dist/resources/extensions/gsd/auto-worktree.js +20 -2073
  44. package/dist/resources/extensions/gsd/auto.js +106 -34
  45. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
  46. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +20 -2
  47. package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
  48. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +185 -27
  49. package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
  50. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  51. package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
  52. package/dist/resources/extensions/gsd/compat/compat-marker.js +44 -0
  53. package/dist/resources/extensions/gsd/config-overlay.js +7 -2
  54. package/dist/resources/extensions/gsd/db/engine.js +33 -0
  55. package/dist/resources/extensions/gsd/db/queries.js +9 -9
  56. package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
  57. package/dist/resources/extensions/gsd/db-adapter.js +30 -3
  58. package/dist/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  59. package/dist/resources/extensions/gsd/doctor-engine-checks.js +93 -11
  60. package/dist/resources/extensions/gsd/flat-phase-migration.js +32 -3
  61. package/dist/resources/extensions/gsd/forensics.js +1 -1
  62. package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
  63. package/dist/resources/extensions/gsd/git-service.js +45 -0
  64. package/dist/resources/extensions/gsd/gsd-db.js +23 -11
  65. package/dist/resources/extensions/gsd/guided-flow.js +22 -17
  66. package/dist/resources/extensions/gsd/journal.js +1 -1
  67. package/dist/resources/extensions/gsd/markdown-renderer.js +34 -79
  68. package/dist/resources/extensions/gsd/md-importer.js +89 -23
  69. package/dist/resources/extensions/gsd/metrics.js +2 -2
  70. package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
  71. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +11 -0
  72. package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
  73. package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
  74. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
  75. package/dist/resources/extensions/gsd/paths.js +87 -52
  76. package/dist/resources/extensions/gsd/post-unit-hooks.js +27 -0
  77. package/dist/resources/extensions/gsd/preferences-models.js +66 -15
  78. package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
  79. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  80. package/dist/resources/extensions/gsd/preferences-validation.js +148 -10
  81. package/dist/resources/extensions/gsd/preferences.js +20 -0
  82. package/dist/resources/extensions/gsd/prompts/system.md +6 -6
  83. package/dist/resources/extensions/gsd/quick.js +12 -3
  84. package/dist/resources/extensions/gsd/rule-registry.js +106 -10
  85. package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
  86. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
  87. package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
  88. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +1 -10
  89. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +3 -24
  90. package/dist/resources/extensions/gsd/state-reconciliation/index.js +10 -0
  91. package/dist/resources/extensions/gsd/tool-contract.js +14 -0
  92. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -5
  93. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +16 -10
  94. package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
  95. package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
  96. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -8
  97. package/dist/resources/extensions/gsd/uat-dispatch.js +94 -0
  98. package/dist/resources/extensions/gsd/unit-registry.js +12 -2
  99. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
  100. package/dist/resources/extensions/gsd/uok/audit-toggle.js +31 -2
  101. package/dist/resources/extensions/gsd/uok/audit.js +3 -0
  102. package/dist/resources/extensions/gsd/uok/gate-runner.js +22 -30
  103. package/dist/resources/extensions/gsd/uok/gitops.js +18 -15
  104. package/dist/resources/extensions/gsd/uok/kernel.js +120 -46
  105. package/dist/resources/extensions/gsd/uok/model-policy.js +17 -14
  106. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
  107. package/dist/resources/extensions/gsd/workflow-event-ledger.js +1 -1
  108. package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
  109. package/dist/resources/extensions/gsd/workflow-projections.js +9 -26
  110. package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
  111. package/dist/resources/extensions/gsd/workspace.js +5 -14
  112. package/dist/resources/extensions/gsd/worktree-command.js +1 -1
  113. package/dist/resources/extensions/gsd/worktree-lifecycle.js +14 -9
  114. package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
  115. package/dist/resources/extensions/shared/gsd-browser-cli.js +29 -0
  116. package/dist/resources/extensions/shared/interview-ui.js +62 -9
  117. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  118. package/dist/web/standalone/.next/BUILD_ID +1 -1
  119. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  120. package/dist/web/standalone/.next/build-manifest.json +2 -2
  121. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  122. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  142. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  146. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  158. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  170. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/index.html +1 -1
  173. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  174. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  180. package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
  181. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  182. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  184. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  185. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  186. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  187. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  188. package/dist/worktree-cli-create.d.ts +10 -0
  189. package/dist/worktree-cli-create.js +11 -0
  190. package/dist/worktree-cli-format.d.ts +12 -0
  191. package/dist/worktree-cli-format.js +38 -0
  192. package/dist/worktree-cli-plan.d.ts +16 -0
  193. package/dist/worktree-cli-plan.js +19 -0
  194. package/dist/worktree-cli-session.d.ts +13 -0
  195. package/dist/worktree-cli-session.js +18 -0
  196. package/dist/worktree-cli-status.d.ts +35 -0
  197. package/dist/worktree-cli-status.js +54 -0
  198. package/dist/worktree-cli.d.ts +1 -16
  199. package/dist/worktree-cli.js +28 -122
  200. package/integrations/hermes/open_gsd_hermes/gsd_client.py +25 -36
  201. package/integrations/hermes/pyproject.toml +1 -1
  202. package/integrations/hermes/tests/test_gsd_client_timeout.py +4 -4
  203. package/package.json +6 -6
  204. package/packages/cloud-mcp-gateway/package.json +2 -2
  205. package/packages/contracts/package.json +1 -1
  206. package/packages/daemon/dist/orchestrator-agent.d.ts +21 -0
  207. package/packages/daemon/dist/orchestrator-agent.d.ts.map +1 -0
  208. package/packages/daemon/dist/orchestrator-agent.js +113 -0
  209. package/packages/daemon/dist/orchestrator-agent.js.map +1 -0
  210. package/packages/daemon/dist/orchestrator-tools.d.ts +12 -0
  211. package/packages/daemon/dist/orchestrator-tools.d.ts.map +1 -0
  212. package/packages/daemon/dist/orchestrator-tools.js +137 -0
  213. package/packages/daemon/dist/orchestrator-tools.js.map +1 -0
  214. package/packages/daemon/dist/orchestrator.d.ts +4 -56
  215. package/packages/daemon/dist/orchestrator.d.ts.map +1 -1
  216. package/packages/daemon/dist/orchestrator.js +13 -303
  217. package/packages/daemon/dist/orchestrator.js.map +1 -1
  218. package/packages/daemon/dist/orchestrator.test.js +11 -1
  219. package/packages/daemon/dist/orchestrator.test.js.map +1 -1
  220. package/packages/daemon/package.json +4 -4
  221. package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
  222. package/packages/gsd-agent-core/package.json +5 -5
  223. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  224. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
  225. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  226. package/packages/gsd-agent-modes/package.json +7 -7
  227. package/packages/mcp-server/package.json +4 -4
  228. package/packages/native/package.json +1 -1
  229. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  230. package/packages/pi-agent-core/dist/agent-loop.js +14 -9
  231. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  232. package/packages/pi-agent-core/package.json +1 -1
  233. package/packages/pi-ai/dist/index.d.ts +1 -0
  234. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  235. package/packages/pi-ai/dist/index.js +1 -0
  236. package/packages/pi-ai/dist/index.js.map +1 -1
  237. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  238. package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
  239. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  240. package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
  241. package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
  242. package/packages/pi-ai/dist/tool-result-content.js +62 -0
  243. package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
  244. package/packages/pi-ai/dist/types.d.ts +8 -20
  245. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  246. package/packages/pi-ai/dist/types.js.map +1 -1
  247. package/packages/pi-ai/package.json +1 -1
  248. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
  249. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
  251. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  252. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
  253. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  254. package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
  255. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
  257. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
  258. package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
  259. package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
  260. package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
  261. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  262. package/packages/pi-coding-agent/dist/core/skills.js +4 -1
  263. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  264. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  265. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/index.js +1 -0
  267. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  268. package/packages/pi-coding-agent/package.json +7 -7
  269. package/packages/pi-tui/package.json +2 -2
  270. package/packages/rpc-client/package.json +2 -2
  271. package/pkg/dist/core/export-html/template.js +53 -4
  272. package/pkg/package.json +1 -1
  273. package/src/resources/extensions/ask-user-questions.ts +1 -1
  274. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +146 -33
  275. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +25 -0
  276. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +93 -0
  277. package/src/resources/extensions/gsd/activity-log.ts +1 -1
  278. package/src/resources/extensions/gsd/auto/closeout.ts +114 -7
  279. package/src/resources/extensions/gsd/auto/orchestrator.ts +21 -14
  280. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
  281. package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
  282. package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -4
  283. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
  284. package/src/resources/extensions/gsd/auto-dispatch.ts +77 -16
  285. package/src/resources/extensions/gsd/auto-model-selection.ts +33 -1
  286. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -2
  287. package/src/resources/extensions/gsd/auto-prompts.ts +53 -113
  288. package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
  289. package/src/resources/extensions/gsd/auto-start.ts +62 -31
  290. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -2
  291. package/src/resources/extensions/gsd/auto-timers.ts +9 -2
  292. package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
  293. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
  294. package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
  295. package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
  296. package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
  297. package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
  298. package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
  299. package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
  300. package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
  301. package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
  302. package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
  303. package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
  304. package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
  305. package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
  306. package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
  307. package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
  308. package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
  309. package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
  310. package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
  311. package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
  312. package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
  313. package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
  314. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
  315. package/src/resources/extensions/gsd/auto-worktree.ts +69 -2429
  316. package/src/resources/extensions/gsd/auto.ts +114 -47
  317. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
  318. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +20 -2
  319. package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
  320. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +218 -27
  321. package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
  322. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  323. package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
  324. package/src/resources/extensions/gsd/compat/compat-marker.ts +47 -0
  325. package/src/resources/extensions/gsd/config-overlay.ts +7 -1
  326. package/src/resources/extensions/gsd/db/engine.ts +36 -0
  327. package/src/resources/extensions/gsd/db/queries.ts +9 -9
  328. package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
  329. package/src/resources/extensions/gsd/db-adapter.ts +29 -3
  330. package/src/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  331. package/src/resources/extensions/gsd/doctor-engine-checks.ts +109 -10
  332. package/src/resources/extensions/gsd/flat-phase-migration.ts +34 -3
  333. package/src/resources/extensions/gsd/forensics.ts +1 -1
  334. package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
  335. package/src/resources/extensions/gsd/git-service.ts +53 -0
  336. package/src/resources/extensions/gsd/gsd-db.ts +33 -11
  337. package/src/resources/extensions/gsd/guided-flow.ts +26 -18
  338. package/src/resources/extensions/gsd/journal.ts +1 -1
  339. package/src/resources/extensions/gsd/markdown-renderer.ts +52 -91
  340. package/src/resources/extensions/gsd/md-importer.ts +93 -22
  341. package/src/resources/extensions/gsd/metrics.ts +2 -2
  342. package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
  343. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +15 -0
  344. package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
  345. package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
  346. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
  347. package/src/resources/extensions/gsd/paths.ts +108 -51
  348. package/src/resources/extensions/gsd/post-unit-hooks.ts +32 -0
  349. package/src/resources/extensions/gsd/preferences-models.ts +74 -20
  350. package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
  351. package/src/resources/extensions/gsd/preferences-types.ts +54 -1
  352. package/src/resources/extensions/gsd/preferences-validation.ts +146 -9
  353. package/src/resources/extensions/gsd/preferences.ts +20 -0
  354. package/src/resources/extensions/gsd/prompts/system.md +6 -6
  355. package/src/resources/extensions/gsd/quick.ts +11 -3
  356. package/src/resources/extensions/gsd/rule-registry.ts +111 -9
  357. package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
  358. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
  359. package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
  360. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +1 -9
  361. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +2 -22
  362. package/src/resources/extensions/gsd/state-reconciliation/index.ts +14 -0
  363. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
  364. package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
  365. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +41 -2
  366. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +48 -1
  367. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +57 -0
  368. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
  369. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +29 -1
  370. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-supervisor-inflight-guard.test.ts +159 -0
  371. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +2 -1
  372. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
  373. package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
  374. package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
  375. package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
  376. package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
  377. package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
  378. package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
  379. package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
  380. package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
  381. package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
  382. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
  383. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
  384. package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
  385. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
  386. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  387. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +3 -1
  388. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +85 -0
  389. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +45 -0
  390. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
  391. package/src/resources/extensions/gsd/tests/db-adapter.test.ts +39 -0
  392. package/src/resources/extensions/gsd/tests/db-writable-probe.test.ts +66 -0
  393. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
  394. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +174 -0
  395. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
  396. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +71 -1
  397. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +46 -1
  398. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
  399. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
  400. package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
  401. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
  402. package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
  403. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
  404. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
  405. package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
  406. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
  407. package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
  408. package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
  409. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
  410. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
  411. package/src/resources/extensions/gsd/tests/integration/paths.test.ts +88 -1
  412. package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
  413. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
  414. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
  415. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
  416. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
  417. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
  418. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +2 -1
  419. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +439 -0
  420. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +24 -0
  421. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
  422. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
  423. package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
  424. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +0 -1
  425. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +269 -0
  426. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +8 -1
  427. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
  428. package/src/resources/extensions/gsd/tests/preferences.test.ts +19 -0
  429. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +5 -0
  430. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +54 -0
  431. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +49 -1
  432. package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
  433. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +95 -1
  434. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
  435. package/src/resources/extensions/gsd/tests/sibling-model-fallbacks.test.ts +189 -0
  436. package/src/resources/extensions/gsd/tests/single-field-model-thinking.test.ts +156 -0
  437. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
  438. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +6 -1
  439. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
  440. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +32 -0
  441. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
  442. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
  443. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
  444. package/src/resources/extensions/gsd/tests/supervisor-model-swap-inflight-guard.test.ts +181 -0
  445. package/src/resources/extensions/gsd/tests/supervisor-model-swap-thinking-clamp.test.ts +122 -0
  446. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
  447. package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
  448. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
  449. package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
  450. package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
  451. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +196 -0
  452. package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
  453. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
  454. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +26 -1
  455. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +39 -0
  456. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +226 -2
  457. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +6 -0
  458. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +213 -2
  459. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
  460. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
  461. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
  462. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
  463. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
  464. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
  465. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
  466. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
  467. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +5 -2
  468. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
  469. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
  470. package/src/resources/extensions/gsd/tool-contract.ts +29 -0
  471. package/src/resources/extensions/gsd/tools/complete-milestone.ts +9 -5
  472. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +19 -8
  473. package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
  474. package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
  475. package/src/resources/extensions/gsd/tools/validate-milestone.ts +13 -9
  476. package/src/resources/extensions/gsd/types.ts +23 -4
  477. package/src/resources/extensions/gsd/uat-dispatch.ts +176 -0
  478. package/src/resources/extensions/gsd/unit-registry.ts +16 -2
  479. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
  480. package/src/resources/extensions/gsd/uok/audit-toggle.ts +32 -2
  481. package/src/resources/extensions/gsd/uok/audit.ts +2 -0
  482. package/src/resources/extensions/gsd/uok/gate-runner.ts +26 -36
  483. package/src/resources/extensions/gsd/uok/gitops.ts +21 -18
  484. package/src/resources/extensions/gsd/uok/kernel.ts +169 -48
  485. package/src/resources/extensions/gsd/uok/model-policy.ts +20 -17
  486. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
  487. package/src/resources/extensions/gsd/workflow-event-ledger.ts +1 -1
  488. package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
  489. package/src/resources/extensions/gsd/workflow-projections.ts +9 -24
  490. package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
  491. package/src/resources/extensions/gsd/workspace.ts +5 -21
  492. package/src/resources/extensions/gsd/worktree-command.ts +1 -1
  493. package/src/resources/extensions/gsd/worktree-lifecycle.ts +19 -15
  494. package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
  495. package/src/resources/extensions/shared/gsd-browser-cli.ts +29 -0
  496. package/src/resources/extensions/shared/interview-ui.ts +58 -11
  497. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
  498. /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → 6xYMOzxVhsQgryneJ5KRc}/_buildManifest.js +0 -0
  499. /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → 6xYMOzxVhsQgryneJ5KRc}/_ssgManifest.js +0 -0
@@ -3,6 +3,10 @@
3
3
 
4
4
  import test from "node:test";
5
5
  import assert from "node:assert/strict";
6
+ import { execFileSync } from "node:child_process";
7
+ import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
8
+ import { tmpdir } from "node:os";
9
+ import { join } from "node:path";
6
10
 
7
11
  import {
8
12
  _runMilestoneMergeOnceWithStashRestore,
@@ -10,6 +14,9 @@ import {
10
14
  } from "../auto/closeout.js";
11
15
  import type { IterationContext } from "../auto/types.js";
12
16
  import { MergeConflictError } from "../git-service.js";
17
+ import { closeDatabase, insertDecision, insertMilestone, insertSlice, insertTask, openDatabase } from "../gsd-db.js";
18
+ import { renderAllFromDb } from "../markdown-renderer.js";
19
+ import { resolveMilestoneFile } from "../paths.js";
13
20
  import type {
14
21
  PostflightResult,
15
22
  PreflightResult,
@@ -234,6 +241,70 @@ const PREFLIGHT_UNMERGED_EVAL_FAILED: PreflightResult = {
234
241
  summary: "Unable to fully evaluate unresolved Git conflicts before milestone M002 merge.",
235
242
  };
236
243
 
244
+ function git(basePath: string, args: string[], stdio: "ignore" | "pipe" = "pipe"): void {
245
+ execFileSync("git", args, { cwd: basePath, stdio });
246
+ }
247
+
248
+ async function withProjectionBackedProject<T>(
249
+ fn: (basePath: string, roadmapPath: string) => Promise<T>,
250
+ options: { gitInit?: boolean } = {},
251
+ ): Promise<T> {
252
+ const basePath = mkdtempSync(join(tmpdir(), "gsd-postflight-projection-"));
253
+ try {
254
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
255
+ openDatabase(join(basePath, ".gsd", "gsd.db"));
256
+ insertMilestone({
257
+ id: "M002",
258
+ title: "Postflight Guard",
259
+ status: "active",
260
+ });
261
+ insertSlice({
262
+ id: "S01",
263
+ milestoneId: "M002",
264
+ title: "Slice",
265
+ status: "pending",
266
+ risk: "medium",
267
+ depends: [],
268
+ demo: "demo",
269
+ sequence: 1,
270
+ });
271
+ insertTask({
272
+ id: "T01",
273
+ sliceId: "S01",
274
+ milestoneId: "M002",
275
+ title: "Task",
276
+ status: "pending",
277
+ });
278
+ await renderAllFromDb(basePath);
279
+ if (options.gitInit !== false) {
280
+ git(basePath, ["init"], "ignore");
281
+ git(basePath, ["config", "user.email", "test@example.invalid"]);
282
+ git(basePath, ["config", "user.name", "Test"]);
283
+ git(basePath, ["add", ".gsd"]);
284
+ git(basePath, ["commit", "-m", "initial projections"], "ignore");
285
+ }
286
+ const roadmapPath = resolveMilestoneFile(basePath, "M002", "ROADMAP");
287
+ assert.ok(roadmapPath, "expected rendered M002 roadmap path");
288
+ return await fn(basePath, roadmapPath);
289
+ } finally {
290
+ closeDatabase();
291
+ rmSync(basePath, { recursive: true, force: true });
292
+ }
293
+ }
294
+
295
+ function insertFreshDbSlice(): void {
296
+ insertSlice({
297
+ id: "S02",
298
+ milestoneId: "M002",
299
+ title: "Fresh DB Slice",
300
+ status: "pending",
301
+ risk: "medium",
302
+ depends: [],
303
+ demo: "demo",
304
+ sequence: 2,
305
+ });
306
+ }
307
+
237
308
  const POP_OK: PostflightResult = {
238
309
  restored: true,
239
310
  needsManualRecovery: false,
@@ -469,6 +540,374 @@ test("already-merged milestone skips guarded merge to terminate duplicate closeo
469
540
  );
470
541
  });
471
542
 
543
+
544
+ test("postflight-restored projection edits survive successful merge rebuild", async () => {
545
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
546
+ const { ic } = buildIc({
547
+ preflightResult: STASH_PUSHED,
548
+ mergeBehavior: "succeed",
549
+ postflightResult: POP_OK,
550
+ });
551
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
552
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
553
+ (ic.deps as unknown as { postflightPopStash: () => PostflightResult }).postflightPopStash = () => {
554
+ writeFileSync(roadmapPath, "# local projection edit restored from stash\n", "utf8");
555
+ return POP_OK;
556
+ };
557
+
558
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
559
+
560
+ assert.equal(result, null);
561
+ assert.equal(
562
+ readFileSync(roadmapPath, "utf8"),
563
+ "# local projection edit restored from stash\n",
564
+ "projection rebuild must not overwrite user edits restored by postflight stash pop",
565
+ );
566
+ });
567
+ });
568
+
569
+ test("untracked markdown under a new generated .gsd projection directory suppresses successful merge rebuild", async () => {
570
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
571
+ insertFreshDbSlice();
572
+
573
+ const { ic } = buildIc({
574
+ preflightResult: STASH_PUSHED,
575
+ mergeBehavior: "succeed",
576
+ postflightResult: POP_OK,
577
+ });
578
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
579
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
580
+ (ic.deps as unknown as { postflightPopStash: () => PostflightResult }).postflightPopStash = () => {
581
+ const restoredDir = join(basePath, ".gsd", "milestones", "M002", "slices", "S99");
582
+ mkdirSync(restoredDir, { recursive: true });
583
+ writeFileSync(join(restoredDir, "S99-SUMMARY.md"), "# restored local markdown\n", "utf8");
584
+ return POP_OK;
585
+ };
586
+
587
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
588
+
589
+ assert.equal(result, null);
590
+ assert.doesNotMatch(
591
+ readFileSync(roadmapPath, "utf8"),
592
+ /Fresh DB Slice/,
593
+ "untracked markdown projections inside generated .gsd directories must suppress rebuild",
594
+ );
595
+ });
596
+ });
597
+
598
+ test("ignored untracked markdown under .gsd suppresses successful merge rebuild", async () => {
599
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
600
+ writeFileSync(join(basePath, ".gitignore"), ".gsd\n", "utf8");
601
+ git(basePath, ["add", ".gitignore"]);
602
+ git(basePath, ["commit", "-m", "ignore gsd projections"], "ignore");
603
+ insertFreshDbSlice();
604
+
605
+ const { ic } = buildIc({
606
+ preflightResult: STASH_PUSHED,
607
+ mergeBehavior: "succeed",
608
+ postflightResult: POP_OK,
609
+ });
610
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
611
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
612
+ (ic.deps as unknown as { postflightPopStash: () => PostflightResult }).postflightPopStash = () => {
613
+ const restoredDir = join(basePath, ".gsd", "milestones", "M002", "ignored-restored-projections");
614
+ mkdirSync(restoredDir, { recursive: true });
615
+ writeFileSync(join(restoredDir, "S99-SUMMARY.md"), "# ignored restored local markdown\n", "utf8");
616
+ return POP_OK;
617
+ };
618
+
619
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
620
+
621
+ assert.equal(result, null);
622
+ assert.doesNotMatch(
623
+ readFileSync(roadmapPath, "utf8"),
624
+ /Fresh DB Slice/,
625
+ "ignored .gsd markdown projections restored by postflight must suppress rebuild",
626
+ );
627
+ });
628
+ });
629
+
630
+ test("preexisting ignored markdown under .gsd does not suppress successful merge rebuild", async () => {
631
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
632
+ writeFileSync(join(basePath, ".gitignore"), ".gsd\n", "utf8");
633
+ git(basePath, ["add", ".gitignore"]);
634
+ git(basePath, ["commit", "-m", "ignore gsd projections"], "ignore");
635
+ mkdirSync(join(basePath, ".gsd", "milestones", "M002", "ignored-existing-projections"), { recursive: true });
636
+ writeFileSync(
637
+ join(basePath, ".gsd", "milestones", "M002", "ignored-existing-projections", "S99-SUMMARY.md"),
638
+ "# already ignored local markdown\n",
639
+ "utf8",
640
+ );
641
+ insertFreshDbSlice();
642
+
643
+ const { ic } = buildIc({
644
+ preflightResult: STASH_PUSHED,
645
+ mergeBehavior: "succeed",
646
+ postflightResult: POP_OK,
647
+ });
648
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
649
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
650
+
651
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
652
+
653
+ assert.equal(result, null);
654
+ assert.match(
655
+ readFileSync(roadmapPath, "utf8"),
656
+ /Fresh DB Slice/,
657
+ "stable preexisting ignored .gsd markdown must not block the required projection rebuild",
658
+ );
659
+ });
660
+ });
661
+
662
+ test("failed pre-merge ignored snapshot still suppresses rebuild over restored ignored markdown", async () => {
663
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
664
+ insertFreshDbSlice();
665
+
666
+ const { ic } = buildIc({
667
+ preflightResult: STASH_PUSHED,
668
+ mergeBehavior: "succeed",
669
+ postflightResult: POP_OK,
670
+ });
671
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
672
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
673
+ (ic.deps as unknown as { postflightPopStash: () => PostflightResult }).postflightPopStash = () => {
674
+ // Git only becomes available AFTER the pre-merge ignored-markdown
675
+ // snapshot was attempted, so `before` is null. Postflight then restores
676
+ // ignored `.gsd` markdown that plain `git status` cannot see. With no
677
+ // baseline to diff against, the guard must fail closed and refuse to
678
+ // rebuild over the restored edit.
679
+ git(basePath, ["init"], "ignore");
680
+ git(basePath, ["config", "user.email", "test@example.invalid"]);
681
+ git(basePath, ["config", "user.name", "Test"]);
682
+ writeFileSync(join(basePath, ".gitignore"), ".gsd\n", "utf8");
683
+ git(basePath, ["add", ".gitignore"]);
684
+ git(basePath, ["commit", "-m", "ignore gsd projections"], "ignore");
685
+ writeFileSync(roadmapPath, "# ignored projection edit restored from stash\n", "utf8");
686
+ return POP_OK;
687
+ };
688
+
689
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
690
+
691
+ assert.equal(result, null);
692
+ assert.equal(
693
+ readFileSync(roadmapPath, "utf8"),
694
+ "# ignored projection edit restored from stash\n",
695
+ "a null pre-merge ignored snapshot must fail closed and preserve restored ignored .gsd markdown",
696
+ );
697
+ }, { gitInit: false });
698
+ });
699
+
700
+ test("non-projection .gsd markdown does not suppress successful merge rebuild", async () => {
701
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
702
+ insertFreshDbSlice();
703
+
704
+ const { ic } = buildIc({
705
+ preflightResult: STASH_PUSHED,
706
+ mergeBehavior: "succeed",
707
+ postflightResult: POP_OK,
708
+ });
709
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
710
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
711
+ (ic.deps as unknown as { postflightPopStash: () => PostflightResult }).postflightPopStash = () => {
712
+ writeFileSync(join(basePath, ".gsd", "PREFERENCES.md"), "# local preferences note\n", "utf8");
713
+ mkdirSync(join(basePath, ".gsd", "milestones", "M002"), { recursive: true });
714
+ writeFileSync(join(basePath, ".gsd", "milestones", "M002", "NOTES.md"), "# local milestone note\n", "utf8");
715
+ return POP_OK;
716
+ };
717
+
718
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
719
+
720
+ assert.equal(result, null);
721
+ assert.match(
722
+ readFileSync(roadmapPath, "utf8"),
723
+ /Fresh DB Slice/,
724
+ "non-generated .gsd markdown must not block the required projection rebuild",
725
+ );
726
+ });
727
+ });
728
+
729
+ test("three-digit flat-phase projection restored by postflight suppresses successful merge rebuild", async () => {
730
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
731
+ insertFreshDbSlice();
732
+
733
+ const { ic } = buildIc({
734
+ preflightResult: STASH_PUSHED,
735
+ mergeBehavior: "succeed",
736
+ postflightResult: POP_OK,
737
+ });
738
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
739
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
740
+ (ic.deps as unknown as { postflightPopStash: () => PostflightResult }).postflightPopStash = () => {
741
+ const restoredDir = join(basePath, ".gsd", "phases", "999-db-backed-planning");
742
+ mkdirSync(restoredDir, { recursive: true });
743
+ writeFileSync(join(restoredDir, "999-ROADMAP.md"), "# restored 3-digit projection\n", "utf8");
744
+ return POP_OK;
745
+ };
746
+
747
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
748
+
749
+ assert.equal(result, null);
750
+ assert.doesNotMatch(
751
+ readFileSync(roadmapPath, "utf8"),
752
+ /Fresh DB Slice/,
753
+ "three-digit flat-phase projections restored by postflight must suppress rebuild",
754
+ );
755
+ });
756
+ });
757
+
758
+ test("root DECISIONS projection restored by postflight suppresses successful merge rebuild", async () => {
759
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
760
+ insertFreshDbSlice();
761
+ insertDecision({
762
+ id: "D001",
763
+ when_context: "closeout",
764
+ scope: "global",
765
+ decision: "Regenerate decisions from DB",
766
+ choice: "Use database projection",
767
+ rationale: "Exercise root decision projection rebuild",
768
+ revisable: "Yes",
769
+ made_by: "agent",
770
+ superseded_by: null,
771
+ });
772
+
773
+ const { ic } = buildIc({
774
+ preflightResult: STASH_PUSHED,
775
+ mergeBehavior: "succeed",
776
+ postflightResult: POP_OK,
777
+ });
778
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
779
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
780
+ (ic.deps as unknown as { postflightPopStash: () => PostflightResult }).postflightPopStash = () => {
781
+ writeFileSync(
782
+ join(basePath, ".gsd", "DECISIONS.md"),
783
+ "# local decisions edit restored from stash\n",
784
+ "utf8",
785
+ );
786
+ return POP_OK;
787
+ };
788
+
789
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
790
+
791
+ assert.equal(result, null);
792
+ assert.doesNotMatch(
793
+ readFileSync(roadmapPath, "utf8"),
794
+ /Fresh DB Slice/,
795
+ "root generated DECISIONS.md restored by postflight must suppress rebuild",
796
+ );
797
+ assert.equal(
798
+ readFileSync(join(basePath, ".gsd", "DECISIONS.md"), "utf8"),
799
+ "# local decisions edit restored from stash\n",
800
+ "rebuild must not overwrite restored root DECISIONS.md edits",
801
+ );
802
+ });
803
+ });
804
+
805
+ test("non-projection .gsd dirt does not suppress successful merge rebuild", async () => {
806
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
807
+ insertFreshDbSlice();
808
+ mkdirSync(join(basePath, ".gsd", "runtime"), { recursive: true });
809
+
810
+ const { ic } = buildIc({
811
+ preflightResult: STASH_PUSHED,
812
+ mergeBehavior: "succeed",
813
+ postflightResult: POP_OK,
814
+ });
815
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
816
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
817
+ (ic.deps as unknown as { postflightPopStash: () => PostflightResult }).postflightPopStash = () => {
818
+ writeFileSync(join(basePath, ".gsd", "runtime", "restored.json"), "{}\n", "utf8");
819
+ return POP_OK;
820
+ };
821
+
822
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
823
+
824
+ assert.equal(result, null);
825
+ assert.match(
826
+ readFileSync(roadmapPath, "utf8"),
827
+ /Fresh DB Slice/,
828
+ "non-projection .gsd dirt must not block the required projection rebuild",
829
+ );
830
+ });
831
+ });
832
+
833
+ test("guarded merge stash restore and rebuild target the same canonical project root", async () => {
834
+ await withProjectionBackedProject(async (realRoot, roadmapPath) => {
835
+ insertFreshDbSlice();
836
+ let postflightProjectRoot: string | undefined;
837
+
838
+ const { ic } = buildIc({
839
+ preflightResult: STASH_PUSHED,
840
+ mergeBehavior: "succeed",
841
+ postflightResult: POP_OK,
842
+ });
843
+ // originalBasePath empty + basePath diverging from canonicalProjectRoot is
844
+ // the exact condition where the guard (snapshot / dirty check / rebuild)
845
+ // could run against a different tree than the postflight stash restore.
846
+ // The postflight restore must land on the same canonical root the guard
847
+ // inspects and the rebuild writes, otherwise restored edits are missed.
848
+ (ic.s as unknown as {
849
+ basePath: string;
850
+ originalBasePath: string;
851
+ canonicalProjectRoot: string;
852
+ }).basePath = "/tmp/gsd-decoy-basepath-not-the-project-root";
853
+ (ic.s as unknown as { originalBasePath: string }).originalBasePath = "";
854
+ (ic.s as unknown as { canonicalProjectRoot: string }).canonicalProjectRoot = realRoot;
855
+ (ic.deps as unknown as { postflightPopStash: (projectRoot: string) => PostflightResult }).postflightPopStash =
856
+ (projectRoot: string) => {
857
+ postflightProjectRoot = projectRoot;
858
+ writeFileSync(roadmapPath, "# projection edit restored from stash\n", "utf8");
859
+ return POP_OK;
860
+ };
861
+
862
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
863
+
864
+ assert.equal(result, null);
865
+ assert.equal(
866
+ postflightProjectRoot,
867
+ realRoot,
868
+ "postflight stash restore must run at the canonical project root the guard and rebuild use",
869
+ );
870
+ assert.equal(
871
+ readFileSync(roadmapPath, "utf8"),
872
+ "# projection edit restored from stash\n",
873
+ "restored projection edits on the canonical root must suppress the rebuild",
874
+ );
875
+ });
876
+ });
877
+
878
+ test("git-quoted special-character .gsd markdown paths still suppress rebuild", async () => {
879
+ await withProjectionBackedProject(async (basePath, roadmapPath) => {
880
+ insertFreshDbSlice();
881
+
882
+ const { ic } = buildIc({
883
+ preflightResult: STASH_PUSHED,
884
+ mergeBehavior: "succeed",
885
+ postflightResult: POP_OK,
886
+ });
887
+ (ic.s as { basePath: string; originalBasePath: string }).basePath = basePath;
888
+ (ic.s as { basePath: string; originalBasePath: string }).originalBasePath = basePath;
889
+ (ic.deps as unknown as { postflightPopStash: () => PostflightResult }).postflightPopStash = () => {
890
+ const restoredDir = join(basePath, ".gsd", "milestones", "M002", "restoréd");
891
+ mkdirSync(restoredDir, { recursive: true });
892
+ // A non-ASCII generated projection path that `git status --porcelain`
893
+ // C-quotes without -z; a naive line.endsWith(".md") check would miss the
894
+ // quoted path. NUL-delimited (-z) parsing sees the raw path and still
895
+ // detects it as generated projection dirt.
896
+ writeFileSync(join(restoredDir, "S99-SUMMARY.md"), "# restored local markdown\n", "utf8");
897
+ return POP_OK;
898
+ };
899
+
900
+ const result = await _runMilestoneMergeWithStashRestore(ic, "M002");
901
+
902
+ assert.equal(result, null);
903
+ assert.doesNotMatch(
904
+ readFileSync(roadmapPath, "utf8"),
905
+ /Fresh DB Slice/,
906
+ "special-character generated .gsd markdown restored by postflight must suppress the rebuild",
907
+ );
908
+ });
909
+ });
910
+
472
911
  test("merge succeeds but stash pop needs manual recovery -> postflight-stash-restore-failed break", async () => {
473
912
  const { ic, log } = buildIc({
474
913
  preflightResult: STASH_PUSHED,
@@ -5,6 +5,7 @@ import test from "node:test";
5
5
  import assert from "node:assert/strict";
6
6
 
7
7
  import {
8
+ createDefaultMilestoneMergeTransaction,
8
9
  createMilestoneMergeTransaction,
9
10
  runMilestoneMergeTransaction,
10
11
  } from "../milestone-merge-transaction.js";
@@ -44,3 +45,26 @@ test("createMilestoneMergeTransaction returns a lifecycle-compatible runner", ()
44
45
  codeFilesChanged: false,
45
46
  });
46
47
  });
48
+
49
+ test("createDefaultMilestoneMergeTransaction hides the legacy merge adapter behind the transaction seam", () => {
50
+ const calls: unknown[][] = [];
51
+ const runner = createDefaultMilestoneMergeTransaction(
52
+ (basePath, milestoneId, roadmapContent) => {
53
+ calls.push([basePath, milestoneId, roadmapContent]);
54
+ return {
55
+ pushed: false,
56
+ codeFilesChanged: true,
57
+ commitMessage: "merge M003",
58
+ prCreated: false,
59
+ };
60
+ },
61
+ );
62
+
63
+ assert.deepEqual(runner("/repo", "M003", "# M003"), {
64
+ pushed: false,
65
+ codeFilesChanged: true,
66
+ commitMessage: "merge M003",
67
+ prCreated: false,
68
+ });
69
+ assert.deepEqual(calls, [["/repo", "M003", "# M003"]]);
70
+ });
@@ -18,7 +18,7 @@ import { execFileSync } from "node:child_process";
18
18
 
19
19
  import { shouldUseWorktreeIsolation } from "../auto.ts";
20
20
  import { getIsolationMode } from "../preferences.ts";
21
- import { getActiveAutoWorktreeContext } from "../auto-worktree.ts";
21
+ import { getActiveAutoWorktreeContext } from "../auto-worktree-session-registry.ts";
22
22
  import { invalidateAllCaches } from "../cache.ts";
23
23
  import { describe, test, beforeEach, afterEach } from 'node:test';
24
24
  import assert from 'node:assert/strict';
@@ -26,12 +26,12 @@ import { join } from "node:path";
26
26
  import { tmpdir } from "node:os";
27
27
  import { execFileSync } from "node:child_process";
28
28
 
29
+ import { createAutoWorktree } from "../auto-worktree-creation.ts";
29
30
  import {
30
31
  getAutoWorktreeOriginalBase,
31
32
  _resetAutoWorktreeOriginalBaseForTests,
32
- createAutoWorktree,
33
- teardownAutoWorktree,
34
- } from "../auto-worktree.ts";
33
+ } from "../auto-worktree-session-registry.ts";
34
+ import { teardownAutoWorktree } from "../auto-worktree-teardown.ts";
35
35
  import { normalizeWorktreePathForCompare } from "../worktree-root.ts";
36
36
 
37
37
  // ─── Helpers ──────────────────────────────────────────────────────────────────
@@ -32,7 +32,7 @@ import { gsdRoot } from "../paths.ts";
32
32
  import {
33
33
  syncProjectRootToWorktree,
34
34
  syncStateToProjectRoot,
35
- } from "../auto-worktree.ts";
35
+ } from "../auto-worktree-sync.ts";
36
36
  import { writeLock, readCrashLock, clearLock } from "../crash-recovery.ts";
37
37
  import { describe, test, beforeEach, afterEach } from "node:test";
38
38
  import assert from "node:assert/strict";
@@ -65,7 +65,6 @@ const ALLOWED_IMPORTERS = new Set([
65
65
  "gsd/visualizer-data.ts",
66
66
  // prompt context text (display strings injected into unit prompts)
67
67
  "gsd/auto-prompts.ts",
68
- // cold-path maintenance command (branch cleanup messaging)
69
68
  "gsd/commands-maintenance.ts",
70
69
  // display-only GitHub issue/PR body sync
71
70
  "github-sync/sync.ts",