@opengsd/gsd-pi 1.3.0-dev.eed73bea → 1.4.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 (505) hide show
  1. package/README.md +10 -10
  2. package/dist/cli.js +17 -4
  3. package/dist/headless-answers.js +1 -1
  4. package/dist/headless-ui.d.ts +1 -1
  5. package/dist/headless-ui.js +1 -1
  6. package/dist/headless.js +1 -1
  7. package/dist/resources/.managed-resources-content-hash +1 -1
  8. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  9. package/dist/resources/extensions/gsd/artifact-verification.js +427 -0
  10. package/dist/resources/extensions/gsd/auto/session.js +11 -0
  11. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
  12. package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
  13. package/dist/resources/extensions/gsd/auto-budget.js +5 -1
  14. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -6
  15. package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
  16. package/dist/resources/extensions/gsd/auto-prompts.js +8 -24
  17. package/dist/resources/extensions/gsd/auto-recovery.js +9 -517
  18. package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
  19. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +3 -3
  20. package/dist/resources/extensions/gsd/auto-verification.js +5 -2
  21. package/dist/resources/extensions/gsd/auto.js +19 -10
  22. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
  23. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +5 -4
  24. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
  26. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +48 -36
  27. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +15 -4
  28. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
  29. package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
  30. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  31. package/dist/resources/extensions/gsd/commands-usage.js +1 -1
  32. package/dist/resources/extensions/gsd/db/engine.js +4 -1
  33. package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
  34. package/dist/resources/extensions/gsd/db-workspace.js +55 -3
  35. package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
  36. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  37. package/dist/resources/extensions/gsd/doctor-engine-checks.js +192 -4
  38. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
  39. package/dist/resources/extensions/gsd/exec-sandbox.js +8 -2
  40. package/dist/resources/extensions/gsd/flat-phase-migration.js +45 -0
  41. package/dist/resources/extensions/gsd/git-service.js +57 -0
  42. package/dist/resources/extensions/gsd/gitignore.js +4 -1
  43. package/dist/resources/extensions/gsd/guided-flow-queue.js +20 -13
  44. package/dist/resources/extensions/gsd/json-persistence.js +20 -0
  45. package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
  46. package/dist/resources/extensions/gsd/layout-policy.js +3 -1
  47. package/dist/resources/extensions/gsd/markdown-renderer.js +2 -7
  48. package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
  49. package/dist/resources/extensions/gsd/metrics.js +4 -4
  50. package/dist/resources/extensions/gsd/migrate-external.js +11 -2
  51. package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
  52. package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
  53. package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
  54. package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
  55. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  56. package/dist/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  57. package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
  58. package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
  59. package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
  60. package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
  61. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  62. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  63. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  64. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  65. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  66. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  67. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +27 -33
  68. package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
  69. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
  70. package/dist/resources/extensions/gsd/state.js +12 -611
  71. package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
  72. package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -34
  73. package/dist/resources/extensions/gsd/tools/complete-task.js +8 -41
  74. package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
  75. package/dist/resources/extensions/gsd/tools/plan-task.js +28 -5
  76. package/dist/resources/extensions/gsd/undo.js +43 -6
  77. package/dist/resources/extensions/gsd/unit-registry.js +11 -3
  78. package/dist/resources/extensions/gsd/verification-gate.js +7 -0
  79. package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
  80. package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
  81. package/dist/resources/extensions/gsd/worktree-manager.js +44 -2
  82. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  83. package/dist/web/standalone/.next/BUILD_ID +1 -1
  84. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  85. package/dist/web/standalone/.next/build-manifest.json +4 -4
  86. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  87. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  88. package/dist/web/standalone/.next/required-server-files.json +3 -3
  89. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  90. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  100. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  128. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  150. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  160. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  166. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  186. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/index.html +1 -1
  196. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  197. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  198. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  199. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  200. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  201. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/page.js +2 -2
  203. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  205. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  206. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  207. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/middleware.js +3 -3
  210. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  211. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  212. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  213. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  214. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  215. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  216. package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
  217. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  218. package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
  219. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  220. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/app/{layout-4ae2d68984392bbf.js → layout-b35cbfff38aaf4cf.js} +1 -1
  222. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +1 -0
  223. package/dist/web/standalone/.next/static/chunks/{main-app-90d1d8d5e5d2dc6b.js → main-app-590a74400e35f685.js} +1 -1
  224. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  226. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  227. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  228. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  229. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  230. package/dist/web/standalone/server.js +1 -1
  231. package/package.json +6 -6
  232. package/packages/cloud-mcp-gateway/package.json +2 -2
  233. package/packages/contracts/package.json +1 -1
  234. package/packages/daemon/package.json +4 -4
  235. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  236. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  237. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  238. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  239. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  240. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  241. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  242. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  243. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  244. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  245. package/packages/gsd-agent-core/dist/index.js +2 -0
  246. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  247. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  248. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  249. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  250. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  251. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  252. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  253. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  254. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  255. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  256. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  257. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  258. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  259. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  260. package/packages/gsd-agent-core/package.json +5 -5
  261. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  262. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  263. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  264. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  265. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  266. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  267. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  268. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  269. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  270. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  271. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -841
  272. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  273. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  274. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  275. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  276. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  277. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  278. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  279. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  280. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  281. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  282. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  283. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +258 -0
  284. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  285. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  286. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  287. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  288. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  289. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  290. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  291. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  292. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  293. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  294. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  295. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  296. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  297. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  298. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  299. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  300. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  301. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  302. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  303. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  304. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  305. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  306. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  307. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  308. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  309. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
  310. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  311. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +23 -5
  312. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  313. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  314. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  315. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  316. package/packages/gsd-agent-modes/package.json +7 -7
  317. package/packages/mcp-server/dist/workflow-tools.js +1 -1
  318. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  319. package/packages/mcp-server/package.json +4 -4
  320. package/packages/native/package.json +1 -1
  321. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  322. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  323. package/packages/pi-agent-core/package.json +1 -1
  324. package/packages/pi-ai/dist/models.generated.d.ts +46 -0
  325. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  326. package/packages/pi-ai/dist/models.generated.js +38 -0
  327. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  328. package/packages/pi-ai/package.json +1 -1
  329. package/packages/pi-coding-agent/README.md +3 -2
  330. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  331. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  332. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  333. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  334. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  335. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  336. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  337. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  338. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  339. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  341. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  342. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  343. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  344. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  345. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  346. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  347. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  348. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  349. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  351. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  352. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  353. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  354. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  355. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  356. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  357. package/packages/pi-coding-agent/package.json +7 -7
  358. package/packages/pi-tui/package.json +2 -2
  359. package/packages/rpc-client/package.json +2 -2
  360. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  361. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  362. package/pkg/dist/theme/theme-schema.js +1 -1
  363. package/pkg/dist/theme/theme-schema.js.map +1 -1
  364. package/pkg/dist/theme/theme.d.ts.map +1 -1
  365. package/pkg/dist/theme/theme.js +11 -7
  366. package/pkg/dist/theme/theme.js.map +1 -1
  367. package/pkg/package.json +1 -1
  368. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  369. package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
  370. package/src/resources/extensions/gsd/artifact-verification.ts +464 -0
  371. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  372. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  373. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
  374. package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
  375. package/src/resources/extensions/gsd/auto-budget.ts +12 -1
  376. package/src/resources/extensions/gsd/auto-dispatch.ts +17 -7
  377. package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
  378. package/src/resources/extensions/gsd/auto-prompts.ts +7 -23
  379. package/src/resources/extensions/gsd/auto-recovery.ts +13 -518
  380. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
  381. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +3 -2
  382. package/src/resources/extensions/gsd/auto-verification.ts +5 -1
  383. package/src/resources/extensions/gsd/auto.ts +23 -8
  384. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
  385. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +5 -4
  386. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  387. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +43 -18
  388. package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
  389. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +50 -37
  390. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +16 -4
  391. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
  392. package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
  393. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  394. package/src/resources/extensions/gsd/commands-usage.ts +1 -1
  395. package/src/resources/extensions/gsd/db/engine.ts +8 -1
  396. package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
  397. package/src/resources/extensions/gsd/db-workspace.ts +61 -3
  398. package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
  399. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  400. package/src/resources/extensions/gsd/doctor-engine-checks.ts +233 -5
  401. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
  402. package/src/resources/extensions/gsd/doctor-types.ts +3 -0
  403. package/src/resources/extensions/gsd/exec-sandbox.ts +7 -2
  404. package/src/resources/extensions/gsd/flat-phase-migration.ts +44 -0
  405. package/src/resources/extensions/gsd/git-service.ts +64 -0
  406. package/src/resources/extensions/gsd/gitignore.ts +4 -1
  407. package/src/resources/extensions/gsd/guided-flow-queue.ts +20 -13
  408. package/src/resources/extensions/gsd/json-persistence.ts +20 -0
  409. package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
  410. package/src/resources/extensions/gsd/layout-policy.ts +2 -1
  411. package/src/resources/extensions/gsd/markdown-renderer.ts +2 -10
  412. package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
  413. package/src/resources/extensions/gsd/metrics.ts +4 -4
  414. package/src/resources/extensions/gsd/migrate-external.ts +8 -2
  415. package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
  416. package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
  417. package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
  418. package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
  419. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  420. package/src/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  421. package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
  422. package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
  423. package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
  424. package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
  425. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  426. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  427. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  428. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  429. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  430. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  431. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +36 -30
  432. package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
  433. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
  434. package/src/resources/extensions/gsd/state.ts +32 -732
  435. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
  436. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
  437. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
  438. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
  439. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
  440. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +35 -0
  441. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
  442. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
  443. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
  444. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
  445. package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
  446. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
  447. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
  448. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
  449. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +239 -2
  450. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
  451. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
  452. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +37 -2
  453. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
  454. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +11 -2
  455. package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
  456. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
  457. package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
  458. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
  459. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
  460. package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
  461. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
  462. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  463. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
  464. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
  465. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +10 -0
  466. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
  467. package/src/resources/extensions/gsd/tests/plan-task.test.ts +44 -1
  468. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
  469. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  470. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
  471. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
  472. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +103 -0
  473. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
  474. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
  475. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +56 -0
  476. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +115 -0
  477. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +140 -0
  478. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +6 -3
  479. package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
  480. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +38 -0
  481. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
  482. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
  483. package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
  484. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
  485. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +6 -5
  486. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
  487. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  488. package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -30
  489. package/src/resources/extensions/gsd/tools/complete-task.ts +7 -39
  490. package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
  491. package/src/resources/extensions/gsd/tools/plan-task.ts +30 -5
  492. package/src/resources/extensions/gsd/undo.ts +47 -6
  493. package/src/resources/extensions/gsd/unit-registry.ts +11 -3
  494. package/src/resources/extensions/gsd/verification-gate.ts +8 -0
  495. package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
  496. package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
  497. package/src/resources/extensions/gsd/worktree-manager.ts +41 -1
  498. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  499. package/dist/web/standalone/.next/static/chunks/796.3976108148518f7d.js +0 -10
  500. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +0 -1
  501. package/dist/web/standalone/.next/static/chunks/app/page-6644fc6ee8ca1247.js +0 -1
  502. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +0 -1
  503. package/dist/web/standalone/.next/static/chunks/webpack-7c1d97e39be2da11.js +0 -1
  504. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → zQLcXm0Za8lexoXtgDpMG}/_buildManifest.js +0 -0
  505. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → zQLcXm0Za8lexoXtgDpMG}/_ssgManifest.js +0 -0
@@ -18,6 +18,7 @@ import { join } from "node:path";
18
18
  import { execSync } from "node:child_process";
19
19
  import { GIT_NO_PROMPT_ENV } from "../git-constants.ts";
20
20
  import { handleTurnGitActionError, runTurnGitAction } from "../git-service.ts";
21
+ import { _resetLogs, drainLogs } from "../workflow-logger.ts";
21
22
 
22
23
  function run(cmd: string, cwd: string): string {
23
24
  return execSync(cmd, { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
@@ -111,6 +112,43 @@ workspace:
111
112
  }
112
113
  });
113
114
 
115
+ test("uok gitops turn action status-only reports dirty undeclared nested git repositories", () => {
116
+ const root = mkdtempSync(join(tmpdir(), "gsd-uok-gitops-nested-"));
117
+ try {
118
+ initRepo(root);
119
+ mkdirSync(join(root, "nested"), { recursive: true });
120
+ initRepo(join(root, "nested"));
121
+ writeFileSync(join(root, ".gitignore"), "nested/\n", "utf-8");
122
+ run("git add .gitignore", root);
123
+ run('git commit -m "chore: ignore nested repo"', root);
124
+
125
+ writeFileSync(join(root, "nested", "README.md"), "# Dirty nested\n", "utf-8");
126
+
127
+ _resetLogs();
128
+ const result = runTurnGitAction({
129
+ basePath: root,
130
+ action: "status-only",
131
+ unitType: "execute-task",
132
+ unitId: "M001/S01/T01",
133
+ });
134
+ const warnings = drainLogs();
135
+
136
+ assert.equal(result.status, "ok");
137
+ assert.equal(result.dirty, true);
138
+ assert.deepEqual(result.dirtyRepositories, {
139
+ project: false,
140
+ "nested (undeclared)": true,
141
+ });
142
+ assert.ok(
143
+ warnings.some((entry) => entry.message.includes("undeclared dirty nested git repo nested")),
144
+ "dirty undeclared nested repo should be logged as a warning",
145
+ );
146
+ } finally {
147
+ _resetLogs();
148
+ rmSync(root, { recursive: true, force: true });
149
+ }
150
+ });
151
+
114
152
  test("uok gitops turn action snapshot writes snapshot refs", () => {
115
153
  const repo = makeRepo();
116
154
  try {
@@ -11,6 +11,8 @@ import {
11
11
  verificationRetryKey,
12
12
  VERIFICATION_RETRY_MAX_DELAY_MS,
13
13
  } from "../auto/verification-retry-policy.ts";
14
+ import { formatFailureContext, formatFailureSignature } from "../verification-gate.ts";
15
+ import type { VerificationResult } from "../types.ts";
14
16
 
15
17
  test("verificationRetryDelayMs uses exponential backoff with cap", () => {
16
18
  assert.deepEqual(verificationRetryDelayMs(1, () => 0.5), {
@@ -31,9 +33,22 @@ test("verificationRetryDelayMs uses exponential backoff with cap", () => {
31
33
  });
32
34
  });
33
35
 
34
- test("decideVerificationRetry pauses on duplicate failure context", () => {
36
+ test("decideVerificationRetry pauses on repeated failure context across attempts", () => {
35
37
  const failureContext = "lint failed\n";
36
- const failureHash = hashVerificationFailureContext(failureContext);
38
+ const firstDecision = decideVerificationRetry({
39
+ unitType: "execute-task",
40
+ retryInfo: {
41
+ unitId: "M001/S01/T01",
42
+ failureContext,
43
+ attempt: 1,
44
+ },
45
+ previousFailureHash: undefined,
46
+ random: () => 0.5,
47
+ });
48
+
49
+ assert.equal(firstDecision.action, "delay");
50
+ assert.equal(firstDecision.failureHash, hashVerificationFailureContext(failureContext));
51
+
37
52
  const decision = decideVerificationRetry({
38
53
  unitType: "execute-task",
39
54
  retryInfo: {
@@ -41,7 +56,7 @@ test("decideVerificationRetry pauses on duplicate failure context", () => {
41
56
  failureContext,
42
57
  attempt: 2,
43
58
  },
44
- previousFailureHash: failureHash,
59
+ previousFailureHash: firstDecision.failureHash,
45
60
  random: () => 0.5,
46
61
  });
47
62
 
@@ -49,7 +64,7 @@ test("decideVerificationRetry pauses on duplicate failure context", () => {
49
64
  action: "pause",
50
65
  reason: "duplicate-failure-context",
51
66
  key: verificationRetryKey("execute-task", "M001/S01/T01"),
52
- failureHash,
67
+ failureHash: firstDecision.failureHash,
53
68
  });
54
69
  });
55
70
 
@@ -71,6 +86,56 @@ test("decideVerificationRetry delays changed failure context", () => {
71
86
  assert.equal(decision.baseDelayMs, 4_000);
72
87
  });
73
88
 
89
+ test("decideVerificationRetry pauses duplicate host-check failures with volatile stderr", () => {
90
+ const makeResult = (stderr: string): VerificationResult => ({
91
+ passed: false,
92
+ discoverySource: "package-json",
93
+ timestamp: Date.now(),
94
+ checks: [
95
+ {
96
+ command: "npm test",
97
+ exitCode: 1,
98
+ stdout: "",
99
+ stderr,
100
+ durationMs: 100,
101
+ },
102
+ ],
103
+ });
104
+ const first = makeResult("failed after 120ms in /tmp/gsd-a worker pid 101");
105
+ const second = makeResult("failed after 133ms in /tmp/gsd-b worker pid 202");
106
+ const firstContext = formatFailureContext(first);
107
+ const secondContext = formatFailureContext(second);
108
+
109
+ assert.notEqual(
110
+ hashVerificationFailureContext(firstContext),
111
+ hashVerificationFailureContext(secondContext),
112
+ );
113
+
114
+ const signature = formatFailureSignature(first);
115
+ assert.equal(signature, "npm test#1");
116
+ assert.equal(formatFailureSignature(second), signature);
117
+
118
+ const failureHash = hashVerificationFailureContext(signature);
119
+ const decision = decideVerificationRetry({
120
+ unitType: "execute-task",
121
+ retryInfo: {
122
+ unitId: "M001/S01/T01",
123
+ failureContext: secondContext,
124
+ signature: formatFailureSignature(second),
125
+ attempt: 2,
126
+ },
127
+ previousFailureHash: failureHash,
128
+ random: () => 0.5,
129
+ });
130
+
131
+ assert.deepEqual(decision, {
132
+ action: "pause",
133
+ reason: "duplicate-failure-context",
134
+ key: verificationRetryKey("execute-task", "M001/S01/T01"),
135
+ failureHash,
136
+ });
137
+ });
138
+
74
139
  test("decideVerificationRetry pauses when retry context is missing", () => {
75
140
  assert.deepEqual(
76
141
  decideVerificationRetry({
@@ -24,6 +24,7 @@ import {
24
24
  } from '../gsd-db.ts';
25
25
  import {
26
26
  writeManifest,
27
+ flushManifest,
27
28
  readManifest,
28
29
  snapshotState,
29
30
  bootstrapFromManifest,
@@ -42,6 +43,11 @@ function cleanupDir(dirPath: string): void {
42
43
  try { fs.rmSync(dirPath, { recursive: true, force: true }); } catch { /* best effort */ }
43
44
  }
44
45
 
46
+ async function writeManifestAndFlush(base: string): Promise<void> {
47
+ writeManifest(base);
48
+ await flushManifest(base);
49
+ }
50
+
45
51
  function insertMemoryBackedDecision(id: string): void {
46
52
  const now = '2026-01-01T00:00:00.000Z';
47
53
  insertMemoryRow({
@@ -83,12 +89,14 @@ test('workflow-manifest: readManifest returns null when file does not exist', ()
83
89
 
84
90
  // ─── writeManifest + readManifest round-trip ─────────────────────────────
85
91
 
86
- test('workflow-manifest: writeManifest creates state-manifest.json with version 1', () => {
92
+ test('workflow-manifest: writeManifest creates state-manifest.json with version 1 after flush', async () => {
87
93
  const base = tempDir();
88
94
  openDatabase(tempDbPath(base));
89
95
  try {
90
96
  writeManifest(base);
91
97
  const manifestPath = path.join(base, '.gsd', 'state-manifest.json');
98
+ assert.equal(fs.existsSync(manifestPath), false, 'writeManifest should not synchronously write state-manifest.json');
99
+ await flushManifest(base);
92
100
  assert.ok(fs.existsSync(manifestPath), 'state-manifest.json should exist');
93
101
  const raw = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
94
102
  assert.strictEqual(raw.version, 1);
@@ -98,11 +106,11 @@ test('workflow-manifest: writeManifest creates state-manifest.json with version
98
106
  }
99
107
  });
100
108
 
101
- test('workflow-manifest: readManifest parses manifest written by writeManifest', () => {
109
+ test('workflow-manifest: readManifest parses manifest written by writeManifest', async () => {
102
110
  const base = tempDir();
103
111
  openDatabase(tempDbPath(base));
104
112
  try {
105
- writeManifest(base);
113
+ await writeManifestAndFlush(base);
106
114
  const manifest = readManifest(base);
107
115
  assert.ok(manifest !== null);
108
116
  assert.strictEqual(manifest!.version, 1);
@@ -124,6 +132,25 @@ test('workflow-manifest: readManifest parses manifest written by writeManifest',
124
132
  }
125
133
  });
126
134
 
135
+ test('workflow-manifest: flushManifest writes the latest queued payload', async () => {
136
+ const base = tempDir();
137
+ openDatabase(tempDbPath(base));
138
+ try {
139
+ insertMilestone({ id: 'M001', title: 'First Milestone' });
140
+ writeManifest(base);
141
+ insertMilestone({ id: 'M002', title: 'Latest Milestone' });
142
+ writeManifest(base);
143
+
144
+ await flushManifest(base);
145
+
146
+ const manifest = readManifest(base);
147
+ assert.ok(manifest?.milestones.some((m) => m.id === 'M002'), 'latest queued write should be durable');
148
+ } finally {
149
+ closeDatabase();
150
+ cleanupDir(base);
151
+ }
152
+ });
153
+
127
154
  // ─── snapshotState: captures DB rows ─────────────────────────────────────
128
155
 
129
156
  test('workflow-manifest: snapshotState includes inserted milestone', () => {
@@ -181,7 +208,7 @@ test('workflow-manifest: snapshotState captures memory-backed decisions', () =>
181
208
  }
182
209
  });
183
210
 
184
- test('workflow-manifest: bootstrapFromManifest restores extended correctness rows', () => {
211
+ test('workflow-manifest: bootstrapFromManifest restores extended correctness rows', async () => {
185
212
  const base = tempDir();
186
213
  openDatabase(tempDbPath(base));
187
214
  try {
@@ -256,7 +283,7 @@ test('workflow-manifest: bootstrapFromManifest restores extended correctness row
256
283
  createdAt: '2026-06-05T00:00:00.000Z',
257
284
  });
258
285
 
259
- writeManifest(base);
286
+ await writeManifestAndFlush(base);
260
287
  closeDatabase();
261
288
 
262
289
  const newDbPath = path.join(base, 'new.db');
@@ -306,7 +333,7 @@ test('workflow-manifest: bootstrapFromManifest returns false when no manifest fi
306
333
  }
307
334
  });
308
335
 
309
- test('workflow-manifest: bootstrapFromManifest restores DB from manifest (round-trip)', () => {
336
+ test('workflow-manifest: bootstrapFromManifest restores DB from manifest (round-trip)', async () => {
310
337
  const base = tempDir();
311
338
  openDatabase(tempDbPath(base));
312
339
  try {
@@ -326,7 +353,7 @@ test('workflow-manifest: bootstrapFromManifest restores DB from manifest (round-
326
353
  status: 'complete',
327
354
  planning: { fullPlanMd: '# Full Task Plan\n\nKeep this body.', targetRepositories: ['project'] },
328
355
  });
329
- writeManifest(base);
356
+ await writeManifestAndFlush(base);
330
357
  closeDatabase();
331
358
 
332
359
  // Open a fresh DB and bootstrap from manifest
@@ -356,14 +383,14 @@ test('workflow-manifest: bootstrapFromManifest restores DB from manifest (round-
356
383
  }
357
384
  });
358
385
 
359
- test('workflow-manifest: bootstrapFromManifest preserves target_repositories', () => {
386
+ test('workflow-manifest: bootstrapFromManifest preserves target_repositories', async () => {
360
387
  const base = tempDir();
361
388
  openDatabase(tempDbPath(base));
362
389
  try {
363
390
  insertMilestone({ id: 'M001', title: 'Restored Milestone' });
364
391
  insertSlice({ id: 'S01', milestoneId: 'M001', planning: { targetRepositories: ['frontend'] } });
365
392
  insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', planning: { targetRepositories: ['backend'] } });
366
- writeManifest(base);
393
+ await writeManifestAndFlush(base);
367
394
  closeDatabase();
368
395
 
369
396
  const newDbPath = path.join(base, 'new.db');
@@ -380,14 +407,68 @@ test('workflow-manifest: bootstrapFromManifest preserves target_repositories', (
380
407
  }
381
408
  });
382
409
 
383
- test('workflow-manifest: bootstrapFromManifest preserves optional rows from old manifests', () => {
410
+ test('workflow-manifest: bootstrapFromManifest does not truncate projections when artifact content is empty', async () => {
411
+ const base = tempDir();
412
+ openDatabase(tempDbPath(base));
413
+ try {
414
+ insertMilestone({ id: 'M001', title: 'Projection Milestone' });
415
+ insertArtifact({
416
+ path: '.gsd/milestones/M001/M001-PLAN.md',
417
+ artifact_type: 'PLAN',
418
+ milestone_id: 'M001',
419
+ slice_id: null,
420
+ task_id: null,
421
+ full_content: '# Manifest Plan',
422
+ });
423
+ insertArtifact({
424
+ path: '.gsd/milestones/M001/M001-VALIDATION.md',
425
+ artifact_type: 'VALIDATION',
426
+ milestone_id: 'M001',
427
+ slice_id: null,
428
+ task_id: null,
429
+ full_content: '# Manifest Validation',
430
+ });
431
+ await writeManifestAndFlush(base);
432
+
433
+ const planPath = path.join(base, '.gsd', 'milestones', 'M001', 'M001-PLAN.md');
434
+ const validationPath = path.join(base, '.gsd', 'milestones', 'M001', 'M001-VALIDATION.md');
435
+ fs.mkdirSync(path.dirname(planPath), { recursive: true });
436
+ fs.writeFileSync(planPath, '# Existing Plan\n\nKeep this.');
437
+ fs.writeFileSync(validationPath, '# Existing Validation\n\nKeep this.');
438
+
439
+ const manifestPath = path.join(base, '.gsd', 'state-manifest.json');
440
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as Record<string, unknown>;
441
+ const artifacts = manifest['artifacts'] as Array<Record<string, unknown>>;
442
+ const emptyArtifact = artifacts.find((r) => r['path'] === '.gsd/milestones/M001/M001-PLAN.md');
443
+ const absentArtifact = artifacts.find((r) => r['path'] === '.gsd/milestones/M001/M001-VALIDATION.md');
444
+ assert.ok(emptyArtifact !== undefined);
445
+ assert.ok(absentArtifact !== undefined);
446
+ emptyArtifact['full_content'] = '';
447
+ delete absentArtifact['full_content'];
448
+ fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
449
+ closeDatabase();
450
+
451
+ const newDbPath = path.join(base, 'new.db');
452
+ openDatabase(newDbPath);
453
+ const restored = bootstrapFromManifest(base);
454
+ assert.strictEqual(restored, true);
455
+
456
+ assert.strictEqual(fs.readFileSync(planPath, 'utf-8'), '# Existing Plan\n\nKeep this.');
457
+ assert.strictEqual(fs.readFileSync(validationPath, 'utf-8'), '# Existing Validation\n\nKeep this.');
458
+ } finally {
459
+ closeDatabase();
460
+ cleanupDir(base);
461
+ }
462
+ });
463
+
464
+ test('workflow-manifest: bootstrapFromManifest preserves optional rows from old manifests', async () => {
384
465
  const base = tempDir();
385
466
  openDatabase(tempDbPath(base));
386
467
  try {
387
468
  insertMilestone({ id: 'M001', title: 'Old Manifest Milestone' });
388
469
  insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Old Manifest Slice' });
389
470
  insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', title: 'Old Manifest Task' });
390
- writeManifest(base);
471
+ await writeManifestAndFlush(base);
391
472
 
392
473
  const manifestPath = path.join(base, '.gsd', 'state-manifest.json');
393
474
  const oldManifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as Record<string, unknown>;
@@ -450,12 +531,12 @@ test('workflow-manifest: bootstrapFromManifest preserves optional rows from old
450
531
  }
451
532
  });
452
533
 
453
- test('workflow-manifest: bootstrapFromManifest restores memory-backed decisions', () => {
534
+ test('workflow-manifest: bootstrapFromManifest restores memory-backed decisions', async () => {
454
535
  const base = tempDir();
455
536
  openDatabase(tempDbPath(base));
456
537
  try {
457
538
  insertMemoryBackedDecision('D901');
458
- writeManifest(base);
539
+ await writeManifestAndFlush(base);
459
540
  closeDatabase();
460
541
 
461
542
  const newDbPath = path.join(base, 'new.db');
@@ -472,12 +553,12 @@ test('workflow-manifest: bootstrapFromManifest restores memory-backed decisions'
472
553
  }
473
554
  });
474
555
 
475
- test('workflow-manifest: bootstrapFromManifest replaces stale memory-backed decisions', () => {
556
+ test('workflow-manifest: bootstrapFromManifest replaces stale memory-backed decisions', async () => {
476
557
  const base = tempDir();
477
558
  openDatabase(tempDbPath(base));
478
559
  try {
479
560
  insertMemoryBackedDecision('D902');
480
- writeManifest(base);
561
+ await writeManifestAndFlush(base);
481
562
  closeDatabase();
482
563
 
483
564
  const newDbPath = path.join(base, 'new.db');
@@ -29,6 +29,7 @@ test("preflight uses inline workflow MCP config when no project config is persis
29
29
  `const { StdioServerTransport } = await import(${JSON.stringify(stdioModuleUrl)});`,
30
30
  'const server = new McpServer({ name: "fake", version: "1.0.0" }, { capabilities: { tools: {} } });',
31
31
  'server.tool("gsd_plan_slice", "Plan slice", {}, async () => ({ content: [{ type: "text", text: "ok" }] }));',
32
+ 'server.tool("gsd_plan_task", "Plan task", {}, async () => ({ content: [{ type: "text", text: "ok" }] }));',
32
33
  'server.tool("gsd_reassess_roadmap", "Reassess roadmap", {}, async () => ({ content: [{ type: "text", text: "ok" }] }));',
33
34
  'await server.connect(new StdioServerTransport());',
34
35
  ].join("\n"),
@@ -65,14 +65,18 @@ test("auto execute-task requires canonical task completion tool", () => {
65
65
  assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("execute-task"), expected);
66
66
  });
67
67
 
68
- test("plan-slice requires planning and roadmap reassessment tools", () => {
69
- const expected = ["gsd_plan_slice", "gsd_reassess_roadmap"];
68
+ test("plan-slice requires slice + incremental task planning and roadmap reassessment tools", () => {
69
+ // Incremental planning (#1027): gsd_plan_slice persists metadata, then
70
+ // gsd_plan_task adds tasks one at a time, so both must be on the surface.
71
+ const expected = ["gsd_plan_slice", "gsd_plan_task", "gsd_reassess_roadmap"];
70
72
  assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("plan-slice"), expected);
71
73
  assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("plan-slice"), expected);
72
74
  });
73
75
 
74
- test("plan-milestone requires status, roadmap, and single-slice planning tools", () => {
75
- const expected = ["gsd_milestone_status", "gsd_plan_milestone", "gsd_plan_slice"];
76
+ test("plan-milestone requires status, roadmap, and slice + task planning tools", () => {
77
+ // gsd_plan_task is required alongside gsd_plan_slice for incremental
78
+ // milestone planning (#1027).
79
+ const expected = ["gsd_milestone_status", "gsd_plan_milestone", "gsd_plan_slice", "gsd_plan_task"];
76
80
  assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("plan-milestone"), expected);
77
81
  assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("plan-milestone"), expected);
78
82
  });
@@ -781,22 +781,23 @@ test("executePlanSlice writes task planning state and rendered plan artifacts",
781
781
  }
782
782
  });
783
783
 
784
- test("executePlanSlice marks validation failures with isError", async () => {
784
+ test("executePlanSlice accepts metadata-only incremental planning payloads", async () => {
785
785
  const base = makeTmpBase();
786
786
  try {
787
787
  openTestDb(base);
788
+ await inProjectDir(base, () => executePlanMilestone(validMilestonePlan(), base));
788
789
 
789
790
  const result = await inProjectDir(base, () => executePlanSlice({
790
791
  milestoneId: "M001",
791
792
  sliceId: "S01",
792
- goal: "Trigger validation failure for empty tasks.",
793
+ goal: "Persist slice metadata before tasks.",
793
794
  tasks: [],
794
795
  }, base));
795
796
 
796
- assert.equal(result.isError, true);
797
797
  assert.equal(result.details.operation, "plan_slice");
798
- assert.match(String(result.details.error), /validation failed: tasks must be a non-empty array/);
799
- assert.match(result.content[0].text, /Error planning slice:/);
798
+ assert.equal(result.details.sliceId, "S01");
799
+ assert.equal(result.isError, undefined);
800
+ assert.match(result.content[0].text, /Planned slice S01/);
800
801
  } finally {
801
802
  closeDatabase();
802
803
  cleanup(base);
@@ -13,6 +13,7 @@ import {
13
13
  diffWorktreeNumstat,
14
14
  getWorktreeGSDDiff,
15
15
  getWorktreeLog,
16
+ mergeWorktreeToMain,
16
17
  worktreeBranchName,
17
18
  worktreePath,
18
19
  pruneEphemeralGhostWorktreeDirectories,
@@ -333,6 +334,44 @@ describe("getWorktreeLog", () => {
333
334
  });
334
335
  });
335
336
 
337
+ // ─── mergeWorktreeToMain ─────────────────────────────────────────────────────
338
+
339
+ describe("mergeWorktreeToMain", () => {
340
+ let base: string;
341
+ let wtPath: string;
342
+
343
+ beforeEach(() => {
344
+ base = makeBaseRepo();
345
+ wtPath = worktreePath(base, "M900");
346
+ mkdirSync(join(base, ".gsd-worktrees"), { recursive: true });
347
+ run(`git worktree add -b milestone/M900 "${wtPath}"`, base);
348
+ });
349
+
350
+ afterEach(() => { rmSync(base, { recursive: true, force: true }); });
351
+
352
+ test("cleans failed milestone squash state and deletes orphan branch", () => {
353
+ writeFileSync(join(wtPath, "README.md"), "# Milestone change\n", "utf-8");
354
+ run("git add README.md", wtPath);
355
+ run('git commit -m "feat: milestone change"', wtPath);
356
+
357
+ writeFileSync(join(base, "README.md"), "# Main change\n", "utf-8");
358
+ run("git add README.md", base);
359
+ run('git commit -m "feat: main change"', base);
360
+
361
+ assert.throws(
362
+ () => mergeWorktreeToMain(base, "M900", "feat: merge M900", "milestone/M900"),
363
+ /Merge conflicts detected/,
364
+ );
365
+
366
+ assert.equal(run("git status --porcelain", base), "", "failed squash cleanup should leave main clean");
367
+ assert.ok(!existsSync(wtPath), "failed milestone worktree should be removed");
368
+ assert.ok(
369
+ !run("git branch", base).includes("milestone/M900"),
370
+ "failed milestone branch should be deleted after worktree removal",
371
+ );
372
+ });
373
+ });
374
+
336
375
  // ─── removeWorktree ───────────────────────────────────────────────────────────
337
376
 
338
377
  describe("removeWorktree", () => {
@@ -23,7 +23,7 @@ import {
23
23
  } from "../gsd-db.js";
24
24
  import { gsdProjectionRoot, clearPathCache, relMilestoneFile } from "../paths.js";
25
25
  import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
26
- import { isClosedStatus } from "../status-guards.js";
26
+ import { isClosedStatus, isDeferredStatus } from "../status-guards.js";
27
27
  import { saveFile, clearParseCache } from "../files.js";
28
28
  import { invalidateStateCache } from "../state.js";
29
29
  import { stripIdPrefix } from "../workflow-projections.js";
@@ -180,7 +180,7 @@ export async function handleCompleteMilestone(
180
180
  return;
181
181
  }
182
182
 
183
- const incompleteSlices = slices.filter(s => !isClosedStatus(s.status));
183
+ const incompleteSlices = slices.filter(s => !isClosedStatus(s.status) && !isDeferredStatus(s.status));
184
184
  if (incompleteSlices.length > 0) {
185
185
  const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
186
186
  guardError = `incomplete slices: ${incompleteIds}`;
@@ -189,6 +189,7 @@ export async function handleCompleteMilestone(
189
189
 
190
190
  // Deep check: verify all tasks in all slices are complete
191
191
  for (const slice of slices) {
192
+ if (isDeferredStatus(slice.status)) continue;
192
193
  const tasks = getSliceTasks(params.milestoneId, slice.id);
193
194
  const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
194
195
  if (incompleteTasks.length > 0) {
@@ -30,7 +30,7 @@ import { classifyUatContent, escalatesArtifactUatToBrowser } from "../uat-policy
30
30
  import { invalidateStateCache } from "../state.js";
31
31
  import { renderRoadmapFromDb, roadmapRenderMarksSliceDone } from "../markdown-renderer.js";
32
32
  import { isStaleWrite } from "../auto/turn-epoch.js";
33
- import { renderStateProjection, renderTopLevelQueueFromDb, renderTopLevelRoadmapFromDb } from "../workflow-projections.js";
33
+ import { renderMilestoneShellProjections } from "../workflow-projections.js";
34
34
  import { writeManifest } from "../workflow-manifest.js";
35
35
  import { appendEvent } from "../workflow-events.js";
36
36
  import { logWarning, logError } from "../workflow-logger.js";
@@ -539,37 +539,10 @@ export async function handleCompleteSlice(
539
539
  // ── Post-mutation hook: projections, manifest, event log ───────────────
540
540
  // Separate try/catch per step so a projection failure doesn't prevent
541
541
  // the event log entry (critical for worktree reconciliation).
542
- //
543
- // If the primary summary/UAT/roadmap write block failed (projectionStale),
544
- // retry the milestone-level roadmap here so ROADMAP.md is not left stale
545
- // after a committed slice completion. This restores the recovery that the
546
- // removed flushWorkflowProjections/renderAllProjections provided.
547
- if (projectionStale) {
548
- try {
549
- await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
550
- } catch (projErr) {
551
- logWarning("tool", `complete-slice milestone roadmap retry warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
552
- }
553
- }
554
- try {
555
- await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
556
- } catch (projErr) {
557
- logWarning("tool", `complete-slice milestone roadmap projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
558
- }
559
- try {
560
- renderTopLevelRoadmapFromDb(artifactBasePath);
561
- } catch (projErr) {
562
- logWarning("tool", `complete-slice roadmap projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
563
- }
564
- try {
565
- renderTopLevelQueueFromDb(artifactBasePath);
566
- } catch (projErr) {
567
- logWarning("tool", `complete-slice queue projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
568
- }
569
542
  try {
570
- await renderStateProjection(artifactBasePath);
543
+ await renderMilestoneShellProjections(artifactBasePath, params.milestoneId);
571
544
  } catch (projErr) {
572
- logWarning("tool", `complete-slice state projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
545
+ logWarning("tool", `complete-slice projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
573
546
  }
574
547
  try {
575
548
  writeManifest(artifactBasePath);