@opengsd/gsd-pi 1.3.0-dev.65546769 → 1.3.0-dev.72e3af2a

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 (357) hide show
  1. package/dist/resources/.managed-resources-content-hash +1 -1
  2. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +11 -2
  3. package/dist/resources/extensions/google-cli/stream-adapter.js +82 -15
  4. package/dist/resources/extensions/gsd/artifact-verification.js +427 -0
  5. package/dist/resources/extensions/gsd/auto/orchestrator.js +12 -3
  6. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  7. package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
  8. package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
  9. package/dist/resources/extensions/gsd/auto-prompts.js +26 -11
  10. package/dist/resources/extensions/gsd/auto-recovery.js +6 -507
  11. package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
  12. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +3 -3
  13. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -13
  14. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +38 -0
  15. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +6 -1
  16. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -0
  17. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +10 -19
  18. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -19
  19. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +68 -10
  20. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
  21. package/dist/resources/extensions/gsd/commands-context.js +19 -1
  22. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +16 -10
  23. package/dist/resources/extensions/gsd/commands-worktree.js +12 -10
  24. package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -3
  25. package/dist/resources/extensions/gsd/db/queries.js +60 -0
  26. package/dist/resources/extensions/gsd/db-workspace.js +55 -3
  27. package/dist/resources/extensions/gsd/doctor-providers.js +92 -8
  28. package/dist/resources/extensions/gsd/exec-sandbox.js +45 -9
  29. package/dist/resources/extensions/gsd/forensics.js +2 -32
  30. package/dist/resources/extensions/gsd/git-service.js +4 -4
  31. package/dist/resources/extensions/gsd/guided-flow-queue.js +66 -5
  32. package/dist/resources/extensions/gsd/health-widget.js +55 -29
  33. package/dist/resources/extensions/gsd/layout-policy.js +3 -1
  34. package/dist/resources/extensions/gsd/markdown-renderer.js +8 -9
  35. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +44 -21
  36. package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
  37. package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
  38. package/dist/resources/extensions/gsd/milestone-implementation-evidence.js +26 -20
  39. package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
  40. package/dist/resources/extensions/gsd/quick.js +45 -2
  41. package/dist/resources/extensions/gsd/session-forensics.js +11 -1
  42. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  43. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  44. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  45. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  46. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  47. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  48. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +45 -2
  49. package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
  50. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
  51. package/dist/resources/extensions/gsd/state.js +12 -611
  52. package/dist/resources/extensions/gsd/tools/complete-slice.js +2 -2
  53. package/dist/resources/extensions/gsd/tools/complete-task.js +43 -14
  54. package/dist/resources/extensions/gsd/tools/exec-tool.js +7 -2
  55. package/dist/resources/extensions/gsd/unit-context-composer.js +23 -7
  56. package/dist/resources/extensions/gsd/unit-registry.js +32 -4
  57. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +33 -3
  58. package/dist/resources/extensions/gsd/validation-block-guard.js +9 -4
  59. package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
  60. package/dist/resources/extensions/gsd/workspace-git-preflight.js +30 -1
  61. package/dist/resources/extensions/gsd/worktree-manager.js +44 -2
  62. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  63. package/dist/web/standalone/.next/BUILD_ID +1 -1
  64. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  65. package/dist/web/standalone/.next/build-manifest.json +3 -3
  66. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  67. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  68. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  70. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  79. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  87. package/dist/web/standalone/.next/server/app/index.html +1 -1
  88. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  89. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  90. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  91. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  96. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  99. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  100. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  101. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  102. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  103. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  104. package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
  105. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  106. package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
  107. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  108. package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
  109. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  110. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  111. package/package.json +1 -1
  112. package/packages/cloud-mcp-gateway/package.json +2 -2
  113. package/packages/contracts/dist/workflow.d.ts +1 -0
  114. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  115. package/packages/contracts/dist/workflow.js +2 -0
  116. package/packages/contracts/dist/workflow.js.map +1 -1
  117. package/packages/contracts/package.json +1 -1
  118. package/packages/daemon/package.json +4 -4
  119. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  120. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  121. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  122. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  123. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  124. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  125. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  126. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  127. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  128. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  129. package/packages/gsd-agent-core/dist/index.js +2 -0
  130. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  131. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  132. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  133. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  134. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  135. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  136. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  137. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  138. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  139. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  140. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  141. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  142. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  143. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  144. package/packages/gsd-agent-core/package.json +5 -5
  145. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  146. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  147. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  148. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  149. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  150. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  151. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  152. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  153. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  154. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  155. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -829
  156. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  157. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  158. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  159. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  160. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  161. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  162. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  163. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  164. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  165. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  166. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  167. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +258 -0
  168. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  169. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  170. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  171. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  172. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  173. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  174. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  175. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  176. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  177. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  178. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  179. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  180. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  181. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  182. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  186. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  187. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  188. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  189. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  190. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  191. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  192. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  193. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  194. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  195. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  196. package/packages/gsd-agent-modes/package.json +7 -7
  197. package/packages/mcp-server/README.md +1 -1
  198. package/packages/mcp-server/dist/server.d.ts +1 -1
  199. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  200. package/packages/mcp-server/dist/server.js +3 -3
  201. package/packages/mcp-server/dist/server.js.map +1 -1
  202. package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
  203. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  204. package/packages/mcp-server/dist/workflow-tools.js +34 -20
  205. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  206. package/packages/mcp-server/package.json +4 -4
  207. package/packages/native/package.json +1 -1
  208. package/packages/pi-agent-core/package.json +1 -1
  209. package/packages/pi-ai/package.json +1 -1
  210. package/packages/pi-coding-agent/README.md +3 -2
  211. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  212. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  213. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  214. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  215. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  216. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  217. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  218. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  219. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  220. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  221. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  222. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  223. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  224. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  225. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  226. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  227. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  228. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  229. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  230. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  231. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  232. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  233. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  234. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  235. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  237. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  238. package/packages/pi-coding-agent/package.json +7 -7
  239. package/packages/pi-tui/package.json +2 -2
  240. package/packages/rpc-client/package.json +2 -2
  241. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  242. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  243. package/pkg/dist/theme/theme-schema.js +1 -1
  244. package/pkg/dist/theme/theme-schema.js.map +1 -1
  245. package/pkg/dist/theme/theme.d.ts.map +1 -1
  246. package/pkg/dist/theme/theme.js +11 -7
  247. package/pkg/dist/theme/theme.js.map +1 -1
  248. package/pkg/package.json +1 -1
  249. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +20 -2
  250. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +80 -0
  251. package/src/resources/extensions/google-cli/stream-adapter.ts +106 -19
  252. package/src/resources/extensions/gsd/artifact-verification.ts +464 -0
  253. package/src/resources/extensions/gsd/auto/orchestrator.ts +25 -11
  254. package/src/resources/extensions/gsd/auto/session.ts +5 -0
  255. package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
  256. package/src/resources/extensions/gsd/auto-dispatch.ts +21 -23
  257. package/src/resources/extensions/gsd/auto-prompts.ts +38 -12
  258. package/src/resources/extensions/gsd/auto-recovery.ts +10 -508
  259. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
  260. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +3 -2
  261. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +125 -12
  262. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +43 -0
  263. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +6 -1
  264. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -0
  265. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +11 -19
  266. package/src/resources/extensions/gsd/bootstrap/system-context.ts +52 -18
  267. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +74 -10
  268. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
  269. package/src/resources/extensions/gsd/commands-context.ts +18 -1
  270. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +14 -9
  271. package/src/resources/extensions/gsd/commands-worktree.ts +12 -10
  272. package/src/resources/extensions/gsd/dashboard-overlay.ts +32 -3
  273. package/src/resources/extensions/gsd/db/queries.ts +79 -0
  274. package/src/resources/extensions/gsd/db-workspace.ts +61 -3
  275. package/src/resources/extensions/gsd/doctor-providers.ts +103 -9
  276. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  277. package/src/resources/extensions/gsd/forensics.ts +2 -33
  278. package/src/resources/extensions/gsd/git-service.ts +5 -5
  279. package/src/resources/extensions/gsd/guided-flow-queue.ts +89 -4
  280. package/src/resources/extensions/gsd/health-widget.ts +69 -32
  281. package/src/resources/extensions/gsd/layout-policy.ts +2 -1
  282. package/src/resources/extensions/gsd/markdown-renderer.ts +8 -11
  283. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +51 -19
  284. package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
  285. package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
  286. package/src/resources/extensions/gsd/milestone-implementation-evidence.ts +35 -21
  287. package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
  288. package/src/resources/extensions/gsd/quick.ts +43 -2
  289. package/src/resources/extensions/gsd/session-forensics.ts +11 -1
  290. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  291. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  292. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  293. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  294. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  295. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  296. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +81 -7
  297. package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
  298. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
  299. package/src/resources/extensions/gsd/state.ts +32 -732
  300. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
  301. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +111 -1
  302. package/src/resources/extensions/gsd/tests/commands-context.test.ts +26 -0
  303. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
  304. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +80 -0
  305. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +11 -0
  306. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +48 -8
  307. package/src/resources/extensions/gsd/tests/complete-task.test.ts +75 -0
  308. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +55 -2
  309. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +26 -1
  310. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +70 -2
  311. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +107 -0
  312. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +38 -0
  313. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +45 -1
  314. package/src/resources/extensions/gsd/tests/forensics-error-filter.test.ts +88 -0
  315. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +42 -0
  316. package/src/resources/extensions/gsd/tests/health-widget.test.ts +268 -3
  317. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +119 -1
  318. package/src/resources/extensions/gsd/tests/integration/queue-active-milestone-context-budget.test.ts +93 -0
  319. package/src/resources/extensions/gsd/tests/integration/quick-branch-lifecycle.test.ts +56 -9
  320. package/src/resources/extensions/gsd/tests/knowledge-cold-start.test.ts +14 -0
  321. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +78 -0
  322. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  323. package/src/resources/extensions/gsd/tests/orchestrator-logs.test.ts +43 -1
  324. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +26 -0
  325. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +2 -1
  326. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +1 -1
  327. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +54 -1
  328. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  329. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +195 -1
  330. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +185 -0
  331. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +87 -0
  332. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +7 -0
  333. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +56 -0
  334. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  335. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +151 -0
  336. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +26 -0
  337. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +193 -14
  338. package/src/resources/extensions/gsd/tests/unmerged-milestone-guard.test.ts +25 -0
  339. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +79 -0
  340. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +66 -0
  341. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +151 -2
  342. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
  343. package/src/resources/extensions/gsd/tools/complete-slice.ts +2 -2
  344. package/src/resources/extensions/gsd/tools/complete-task.ts +53 -15
  345. package/src/resources/extensions/gsd/tools/exec-tool.ts +7 -3
  346. package/src/resources/extensions/gsd/unit-context-composer.ts +33 -7
  347. package/src/resources/extensions/gsd/unit-registry.ts +32 -4
  348. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +41 -5
  349. package/src/resources/extensions/gsd/validation-block-guard.ts +13 -7
  350. package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
  351. package/src/resources/extensions/gsd/workspace-git-preflight.ts +31 -0
  352. package/src/resources/extensions/gsd/worktree-manager.ts +41 -1
  353. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  354. package/dist/web/standalone/.next/static/chunks/796.e0bdc932325d7e03.js +0 -10
  355. package/dist/web/standalone/.next/static/chunks/webpack-f46ea08200a0227e.js +0 -1
  356. /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → O7xDYXO0r4zFhIzY1hrWV}/_buildManifest.js +0 -0
  357. /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → O7xDYXO0r4zFhIzY1hrWV}/_ssgManifest.js +0 -0
@@ -9,62 +9,25 @@
9
9
  * globals or AutoContext dependency.
10
10
  */
11
11
  import { parseUnitId } from "./unit-id.js";
12
- import { MILESTONE_ID_RE } from "./milestone-ids.js";
13
12
  import { appendEvent } from "./workflow-events.js";
14
13
  import { atomicWriteSync } from "./atomic-write.js";
15
14
  import { clearParseCache } from "./files.js";
16
- import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
17
- import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGatesForTurn, updateTaskStatus, updateSliceStatus, insertSlice, getMilestone, updateMilestoneStatus, transaction, } from "./gsd-db.js";
15
+ import { isDbAvailable, getTask, updateTaskStatus, updateSliceStatus, insertSlice, getMilestone, updateMilestoneStatus, transaction, } from "./gsd-db.js";
18
16
  import { refreshWorkflowDatabaseFromDisk } from "./db-workspace.js";
19
- import { isValidationTerminal } from "./state.js";
20
17
  import { getErrorMessage } from "./error-utils.js";
21
- import { logWarning, logError } from "./workflow-logger.js";
18
+ import { logWarning } from "./workflow-logger.js";
22
19
  import { isClosedStatus } from "./status-guards.js";
23
- import { resolveSlicePath, resolveSliceFile, resolveTasksDir, resolveTaskFiles, relMilestoneFile, relSliceFile, resolveMilestoneFile, clearPathCache, resolveGsdRootFile, } from "./paths.js";
20
+ import { resolveSlicePath, resolveTasksDir, resolveTaskFiles, relMilestoneFile, relSliceFile, clearPathCache, } from "./paths.js";
24
21
  import { existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
25
- import { execFileSync } from "node:child_process";
26
- import { LAYOUT_SEGMENTS } from "./layout-policy.js";
27
- import { dirname, join, resolve } from "node:path";
22
+ import { dirname } from "node:path";
28
23
  import { resolveExpectedArtifactPath, diagnoseExpectedArtifact, } from "./auto-artifact-paths.js";
29
- import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
30
- import { hasVerdict } from "./verdict-parser.js";
31
- import { validateArtifact } from "./schemas/validate.js";
32
- import { getProjectResearchStatus } from "./project-research-policy.js";
33
- import { isGsdWorktreePath } from "./worktree-root.js";
34
- import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
35
- import { resolveWorktreeProjectRoot } from "./worktree-root.js";
36
- import { hasImplementationArtifacts } from "./milestone-implementation-evidence.js";
37
- import { loadAllCaptures, loadPendingCaptures } from "./captures.js";
24
+ import { resolveArtifactVerificationBase, } from "./artifact-verification.js";
38
25
  import { proveMilestoneCloseout, } from "./milestone-closeout-proof.js";
39
26
  // Re-export so existing consumers of auto-recovery.ts keep working.
40
27
  export { resolveExpectedArtifactPath, diagnoseExpectedArtifact };
41
28
  export { classifyMilestoneSummaryContent, } from "./milestone-summary-classifier.js";
42
29
  export { hasImplementationArtifacts } from "./milestone-implementation-evidence.js";
43
- /**
44
- * Optional override for the legacy roadmap parser used by verifyExpectedArtifact.
45
- * Production leaves this null so the real parseLegacyRoadmap runs; tests inject
46
- * a throwing function to deterministically exercise the parse-failure catches
47
- * (auto-recovery.ts:515 plan-milestone and :622 complete-slice). Those catches
48
- * are otherwise unreachable because parseLegacyRoadmap is internally defensive
49
- * against every malformed input.
50
- * @internal
51
- */
52
- let _roadmapParserFn = null;
53
- /**
54
- * Inject an override for the legacy roadmap parser, returning a function that
55
- * restores the default (real parser) behavior. No production caller.
56
- * @internal
57
- */
58
- export function _setRoadmapParserFnForTests(fn) {
59
- const previous = _roadmapParserFn;
60
- _roadmapParserFn = fn;
61
- return () => { _roadmapParserFn = previous; };
62
- }
63
- function parseRoadmapForRecovery(content) {
64
- if (_roadmapParserFn)
65
- return _roadmapParserFn(content);
66
- return parseLegacyRoadmap(content);
67
- }
30
+ export { verifyExpectedArtifact, diagnoseWorktreeIntegrityFailure, resolveArtifactVerificationBase, _setRoadmapParserFnForTests, } from "./artifact-verification.js";
68
31
  /**
69
32
  * Optional override for the detached GitHub milestone finalize invoked after DB
70
33
  * closeout in refreshRecoveryDbForArtifact. Production leaves this null so the
@@ -79,35 +42,6 @@ export function _setGithubFinalizeFnForTests(fn) {
79
42
  _githubFinalizeFn = fn;
80
43
  return () => { _githubFinalizeFn = previous; };
81
44
  }
82
- // ─── Artifact Resolution & Verification ───────────────────────────────────────
83
- export function diagnoseWorktreeIntegrityFailure(basePath) {
84
- if (!isGsdWorktreePath(basePath))
85
- return null;
86
- if (!existsSync(basePath)) {
87
- return `Worktree integrity failure: ${basePath} does not exist. Repair or recreate the worktree before retrying.`;
88
- }
89
- const gitPath = join(basePath, ".git");
90
- if (!existsSync(gitPath)) {
91
- return `Worktree integrity failure: ${basePath} is not a valid git worktree (.git missing). Repair or recreate the worktree before retrying.`;
92
- }
93
- try {
94
- execFileSync("git", ["rev-parse", "--git-dir"], {
95
- cwd: basePath,
96
- stdio: ["ignore", "pipe", "pipe"],
97
- encoding: "utf-8",
98
- });
99
- return null;
100
- }
101
- catch (err) {
102
- return `Worktree integrity failure: ${basePath} is not a valid git worktree (git rev-parse failed: ${getErrorMessage(err).split("\n")[0]}). Repair or recreate the worktree before retrying.`;
103
- }
104
- }
105
- function resolveArtifactVerificationBase(unitId, base) {
106
- const { milestone } = parseUnitId(unitId);
107
- if (!MILESTONE_ID_RE.test(milestone))
108
- return base;
109
- return resolveCanonicalMilestoneRoot(base, milestone);
110
- }
111
45
  function closeoutProofRecoveryReason(reason) {
112
46
  switch (reason) {
113
47
  case "slice-missing":
@@ -224,441 +158,6 @@ export function refreshRecoveryDbForArtifact(unitType, unitId, basePath) {
224
158
  }
225
159
  return { ok: true };
226
160
  }
227
- function hasCapturedWorkflowPrefs(base) {
228
- const prefsPath = resolveExpectedArtifactPath("workflow-preferences", "WORKFLOW-PREFS", base);
229
- if (!prefsPath || !existsSync(prefsPath))
230
- return false;
231
- const content = readFileSync(prefsPath, "utf-8");
232
- const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
233
- return !!match && /^workflow_prefs_captured:\s*true\s*$/m.test(match[1]);
234
- }
235
- function hasValidResearchDecision(base) {
236
- const decisionPath = resolveExpectedArtifactPath("research-decision", "RESEARCH-DECISION", base);
237
- if (!decisionPath || !existsSync(decisionPath))
238
- return false;
239
- try {
240
- const cfg = JSON.parse(readFileSync(decisionPath, "utf-8"));
241
- return cfg.decision === "research" || cfg.decision === "skip";
242
- }
243
- catch {
244
- return false;
245
- }
246
- }
247
- function hasCompleteProjectResearch(base) {
248
- return getProjectResearchStatus(base).complete;
249
- }
250
- function escapeRegExp(value) {
251
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
252
- }
253
- function hasCheckedTaskCompletionOnDisk(base, mid, sid, tid) {
254
- const slicePath = resolveSlicePath(base, mid, sid);
255
- if (!slicePath)
256
- return false;
257
- const planAbs = resolveSliceFile(base, mid, sid, "PLAN");
258
- if (!planAbs || !existsSync(planAbs))
259
- return false;
260
- const planContent = readFileSync(planAbs, "utf-8");
261
- // Match legacy (`**T01: Title**`) and flat-phase (`**T01**: Title`) checkbox lines.
262
- const cbRe = new RegExp(`^\\s*-\\s+\\[[xX]\\]\\s+\\*\\*${escapeRegExp(tid)}(?:\\*\\*)?:`, "m");
263
- return cbRe.test(planContent);
264
- }
265
- /**
266
- * Check whether the expected artifact(s) for a unit exist on disk.
267
- * Returns true if all required artifacts exist, or if the unit type has no
268
- * single verifiable artifact (e.g., replan-slice).
269
- *
270
- * complete-slice requires both SUMMARY and UAT files — verifying only
271
- * the summary allowed the unit to be marked complete when the LLM
272
- * skipped writing the UAT file (see #176).
273
- */
274
- export function verifyExpectedArtifact(unitType, unitId, base) {
275
- // Hook units have no standard artifact — always pass. Their lifecycle
276
- // is managed by the hook engine, not the artifact verification system.
277
- if (unitType.startsWith("hook/"))
278
- return true;
279
- // Clear stale directory listing cache AND parse cache so artifact checks see
280
- // fresh disk state (#431). The parse cache must also be cleared because
281
- // cacheKey() uses length + first/last 100 chars — when a checkbox changes
282
- // from [ ] to [x], the key collides with the pre-edit version, returning
283
- // stale parsed results (e.g., slice.done = false when it's actually true).
284
- clearPathCache();
285
- clearParseCache();
286
- if (unitType === "rewrite-docs") {
287
- const overridesPath = resolveGsdRootFile(base, "OVERRIDES");
288
- if (!existsSync(overridesPath))
289
- return true;
290
- const content = readFileSync(overridesPath, "utf-8");
291
- return !content.includes("**Scope:** active");
292
- }
293
- if (unitType === "workflow-preferences") {
294
- return hasCapturedWorkflowPrefs(base);
295
- }
296
- if (unitType === "triage-captures") {
297
- const pending = loadPendingCaptures(base);
298
- if (pending.length === 0)
299
- return true;
300
- logWarning("recovery", `verify-fail triage-captures ${unitId}: ${pending.length} pending capture(s) remain in CAPTURES.md`);
301
- return false;
302
- }
303
- if (unitType === "quick-task") {
304
- const { slice: captureId } = parseUnitId(unitId);
305
- const capture = captureId ? loadAllCaptures(base).find((entry) => entry.id === captureId) : undefined;
306
- if (capture?.executed === true)
307
- return true;
308
- logWarning("recovery", `verify-fail quick-task ${unitId}: capture ${captureId ?? "(missing capture id)"} not found or not marked executed`);
309
- return false;
310
- }
311
- if (unitType === "discuss-project") {
312
- const projectPath = resolveExpectedArtifactPath(unitType, unitId, base);
313
- return !!projectPath && existsSync(projectPath) && validateArtifact(projectPath, "project").ok;
314
- }
315
- if (unitType === "discuss-requirements") {
316
- const requirementsPath = resolveExpectedArtifactPath(unitType, unitId, base);
317
- return !!requirementsPath && existsSync(requirementsPath) && validateArtifact(requirementsPath, "requirements").ok;
318
- }
319
- if (unitType === "research-decision") {
320
- return hasValidResearchDecision(base);
321
- }
322
- if (unitType === "research-project") {
323
- return hasCompleteProjectResearch(base);
324
- }
325
- // Reactive-execute: verify that each dispatched task's summary exists.
326
- // The unitId encodes the batch: "{mid}/{sid}/reactive+T02,T03"
327
- if (unitType === "reactive-execute") {
328
- const { milestone: mid, slice: sid, task: batchPart } = parseUnitId(unitId);
329
- if (!mid || !sid || !batchPart)
330
- return false;
331
- const blockerPath = resolveExpectedArtifactPath(unitType, unitId, base);
332
- if (blockerPath && existsSync(blockerPath)) {
333
- return true;
334
- }
335
- const slicePath = resolveSlicePath(base, mid, sid);
336
- if (!slicePath)
337
- return false;
338
- const plusIdx = batchPart.indexOf("+");
339
- if (plusIdx === -1) {
340
- // Legacy format "reactive" without batch IDs — fall back to "any summary"
341
- const tDir = resolveTasksDir(base, mid, sid) ?? slicePath;
342
- const summaryFiles = resolveTaskFiles(tDir, "SUMMARY");
343
- return summaryFiles.length > 0;
344
- }
345
- const batchIds = batchPart.slice(plusIdx + 1).split(",").filter(Boolean);
346
- if (batchIds.length === 0)
347
- return false;
348
- const tDir = resolveTasksDir(base, mid, sid) ?? slicePath;
349
- const existingSummaries = new Set(resolveTaskFiles(tDir, "SUMMARY").map((f) => f.replace(/-SUMMARY\.md$/i, "").toUpperCase()));
350
- // Every dispatched task must have a summary file
351
- for (const tid of batchIds) {
352
- if (!existingSummaries.has(tid.toUpperCase()))
353
- return false;
354
- }
355
- return true;
356
- }
357
- // Gate-evaluate: verify that each dispatched gate has been resolved in the DB.
358
- // The unitId encodes the batch: "{mid}/{sid}/gates+Q3,Q4"
359
- if (unitType === "gate-evaluate") {
360
- const { milestone: mid, slice: sid, task: batchPart } = parseUnitId(unitId);
361
- if (!mid || !sid || !batchPart)
362
- return false;
363
- const plusIdx = batchPart.indexOf("+");
364
- if (plusIdx === -1)
365
- return true; // no specific gates encoded — pass
366
- const gateIds = batchPart.slice(plusIdx + 1).split(",").filter(Boolean);
367
- if (gateIds.length === 0)
368
- return true;
369
- try {
370
- if (!isDbAvailable())
371
- return false;
372
- const pending = getPendingGatesForTurn(mid, sid, "gate-evaluate");
373
- const pendingIds = new Set(pending.map((g) => g.gate_id));
374
- // All dispatched gates must no longer be pending
375
- for (const gid of gateIds) {
376
- if (pendingIds.has(gid))
377
- return false;
378
- }
379
- }
380
- catch (err) {
381
- // DB unavailable — treat as verified to avoid blocking
382
- logWarning("recovery", `gate-evaluate DB check failed: ${err instanceof Error ? err.message : String(err)}`);
383
- }
384
- return true;
385
- }
386
- // #4414: research-slice parallel-research sentinel. The unitId
387
- // `{mid}/parallel-research` is not a real slice — it triggers a single agent
388
- // that fans out research across multiple slices. Verify success by checking
389
- // that every slice which was "research-ready" in the roadmap now has a
390
- // RESEARCH file. Without this, resolveExpectedArtifactPath returns null and
391
- // the retry/escalation machinery silently re-dispatches forever.
392
- //
393
- // #4068: Also treat a PARALLEL-BLOCKER placeholder as a terminal completion
394
- // so that timeout-recovery can write the blocker, have verifyExpectedArtifact
395
- // return true, and let the dispatch loop advance past this unit. Without
396
- // this, the blocker is written but verification still returns false, the unit
397
- // is never cleared from unitDispatchCount, and on the next iteration the
398
- // dispatch rule (which correctly skips parallel-research when PARALLEL-BLOCKER
399
- // exists) returns null — leaving the loop stuck re-deriving indefinitely.
400
- //
401
- // NOTE: this predicate mirrors the dispatch rule at
402
- // auto-dispatch.ts parallel-research-slices — keep the two in sync.
403
- if (unitType === "research-slice" && unitId.endsWith("/parallel-research")) {
404
- const { milestone: mid } = parseUnitId(unitId);
405
- if (!mid)
406
- return false;
407
- // #4068: PARALLEL-BLOCKER written by timeout-recovery is a terminal state.
408
- const blockerPath = resolveExpectedArtifactPath(unitType, unitId, base);
409
- if (blockerPath && existsSync(blockerPath)) {
410
- return true;
411
- }
412
- const roadmapFile = resolveExpectedArtifactPath("plan-milestone", mid, base);
413
- if (!roadmapFile || !existsSync(roadmapFile)) {
414
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap missing`);
415
- return false;
416
- }
417
- try {
418
- const roadmap = parseRoadmapForRecovery(readFileSync(roadmapFile, "utf-8"));
419
- const milestoneResearchFile = resolveExpectedArtifactPath("research-milestone", mid, base);
420
- const hasMilestoneResearch = !!milestoneResearchFile && existsSync(milestoneResearchFile);
421
- for (const slice of roadmap.slices) {
422
- if (slice.done)
423
- continue;
424
- if (hasMilestoneResearch && slice.id === "S01")
425
- continue;
426
- const depsComplete = (slice.depends ?? []).every((depId) => {
427
- const summaryPath = resolveExpectedArtifactPath("complete-slice", `${mid}/${depId}`, base);
428
- return !!summaryPath && existsSync(summaryPath);
429
- });
430
- if (!depsComplete)
431
- continue;
432
- const researchPath = resolveExpectedArtifactPath("research-slice", `${mid}/${slice.id}`, base);
433
- if (!researchPath || !existsSync(researchPath)) {
434
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: slice ${slice.id} missing RESEARCH`);
435
- return false;
436
- }
437
- }
438
- return true;
439
- }
440
- catch (err) {
441
- logWarning("recovery", `parallel-research verification failed: ${err instanceof Error ? err.message : String(err)}`);
442
- return false;
443
- }
444
- }
445
- const artifactBase = resolveArtifactVerificationBase(unitId, base);
446
- let absPath = resolveExpectedArtifactPath(unitType, unitId, artifactBase);
447
- // Worktree→project-root fallback: a milestone running in a worktree may not
448
- // have its CONTEXT/ROADMAP/SUMMARY projected into the worktree yet (the
449
- // worktree only has the META dir until planning writes its projections).
450
- // When the worktree base yields null or a non-existent path, fall back to the
451
- // project root — where the artifact genuinely lives. Without this, a
452
- // discuss-milestone unit with CONTEXT at phases/NN-slug/ in the project root
453
- // but not in the worktree resolves to null → "resolveExpectedArtifactPath
454
- // returned null" → finalize-retry loop (#852).
455
- if (artifactBase !== base) {
456
- const projectRoot = resolve(resolveWorktreeProjectRoot(artifactBase));
457
- if (projectRoot && projectRoot !== artifactBase) {
458
- if (!absPath || !existsSync(absPath)) {
459
- const projectPath = resolveExpectedArtifactPath(unitType, unitId, projectRoot);
460
- if (projectPath && existsSync(projectPath)) {
461
- absPath = projectPath;
462
- }
463
- }
464
- }
465
- }
466
- // For unit types with no registered artifact contract (null path), treat the
467
- // completion state as stale so the key gets evicted (#313).
468
- if (!absPath) {
469
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: resolveExpectedArtifactPath returned null (no artifact contract registered for this unit type)`);
470
- return false;
471
- }
472
- if (!existsSync(absPath)) {
473
- const worktreeFailure = diagnoseWorktreeIntegrityFailure(artifactBase);
474
- if (worktreeFailure) {
475
- logError("recovery", `${worktreeFailure} Unit: ${unitType} ${unitId}.`);
476
- return false;
477
- }
478
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: existsSync false for ${absPath}`);
479
- return false;
480
- }
481
- if (unitType === "validate-milestone") {
482
- const validationContent = readFileSync(absPath, "utf-8");
483
- if (!isValidationTerminal(validationContent)) {
484
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: validation not terminal (len=${validationContent.length}) at ${absPath}`);
485
- return false;
486
- }
487
- }
488
- if (unitType === "run-uat") {
489
- const assessmentContent = readFileSync(absPath, "utf-8");
490
- if (!hasVerdict(assessmentContent)) {
491
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: assessment missing verdict at ${absPath}`);
492
- return false;
493
- }
494
- }
495
- if (unitType === "plan-milestone") {
496
- try {
497
- const roadmap = parseRoadmapForRecovery(readFileSync(absPath, "utf-8"));
498
- if (roadmap.slices.length === 0) {
499
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap has zero slices at ${absPath}`);
500
- return false;
501
- }
502
- }
503
- catch (err) {
504
- logWarning("recovery", `plan-milestone roadmap verification failed: ${err instanceof Error ? err.message : String(err)}`);
505
- return false;
506
- }
507
- }
508
- // plan-slice verification is DB-primary. The slice plan is a projection, so
509
- // DB task rows prove the slice was planned even if the rendered markdown no
510
- // longer uses legacy checkbox/heading syntax.
511
- if (unitType === "plan-slice") {
512
- const { milestone: mid, slice: sid } = parseUnitId(unitId);
513
- if (mid && sid) {
514
- try {
515
- let taskIds = null;
516
- let dbPrimary = false;
517
- if (isDbAvailable()) {
518
- const refreshed = refreshWorkflowDatabaseFromDisk();
519
- if (refreshed) {
520
- const tasks = getSliceTasks(mid, sid);
521
- if (tasks.length > 0) {
522
- taskIds = tasks.map(t => t.id);
523
- dbPrimary = true;
524
- }
525
- }
526
- }
527
- if (!taskIds) {
528
- // LEGACY: DB unavailable or no tasks in DB. Require actual task
529
- // entries so an empty scaffold cannot advance the pipeline (#699).
530
- const planContent = readFileSync(absPath, "utf-8");
531
- const hasCheckboxTask = /^\s*- \[[xX ]\] \*\*T\d+/m.test(planContent);
532
- const hasHeadingTask = /^\s*#{2,4}\s+T\d+\s*(?:--|—|:)/m.test(planContent);
533
- if (!hasCheckboxTask && !hasHeadingTask) {
534
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: plan has no task checkbox/heading (len=${planContent.length}) at ${absPath}`);
535
- return false;
536
- }
537
- const plan = parseLegacyPlan(planContent);
538
- if (plan.tasks.length > 0)
539
- taskIds = plan.tasks.map((t) => t.id);
540
- }
541
- // Per-task plan file check: applies when a tasks/ directory is present on
542
- // disk (legacy layout), regardless of whether DB is primary. Flat-phase
543
- // projects have no tasks/ dir, so the check is naturally skipped there.
544
- // When DB is NOT primary and there is no tasks/ dir either, the missing
545
- // dir itself is evidence of an incomplete plan (non-flat-phase projects must
546
- // have a tasks/ dir).
547
- if (taskIds && taskIds.length > 0) {
548
- const tasksDir = join(dirname(absPath), "tasks");
549
- if (existsSync(tasksDir)) {
550
- for (const tid of taskIds) {
551
- const taskPlanFile = join(tasksDir, `${tid}-PLAN.md`);
552
- if (!existsSync(taskPlanFile)) {
553
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: task plan missing ${taskPlanFile}`);
554
- return false;
555
- }
556
- }
557
- }
558
- else if (!dbPrimary && !absPath.replace(/\\/g, "/").includes(`.gsd/${LAYOUT_SEGMENTS.level1}`)) {
559
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: tasks dir missing at ${tasksDir}`);
560
- return false;
561
- }
562
- }
563
- }
564
- catch (err) {
565
- // Parse failure — don't block; slice plan may have non-standard format
566
- logWarning("recovery", `plan-slice task plan verification failed: ${err instanceof Error ? err.message : String(err)}`);
567
- }
568
- }
569
- }
570
- // execute-task: DB status is authoritative. Fall back to checked-checkbox
571
- // detection when the DB is unavailable (unmigrated projects), or when the
572
- // disk artifacts already reflect completion but the DB replay is one beat
573
- // behind the completion write.
574
- if (unitType === "execute-task") {
575
- const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
576
- if (mid && sid && tid) {
577
- const dbTask = getTask(mid, sid, tid);
578
- if (dbTask) {
579
- if (dbTask.status !== "complete" && dbTask.status !== "done" && !hasCheckedTaskCompletionOnDisk(base, mid, sid, tid)) {
580
- return false;
581
- }
582
- }
583
- else if (!isDbAvailable()) {
584
- // LEGACY: Pre-migration fallback for projects without DB.
585
- // Require a CHECKED checkbox — a bare heading or unchecked checkbox
586
- // does not prove gsd_complete_task ran. Summary file on disk alone
587
- // is not sufficient evidence (could be a rogue write) (#3607).
588
- if (!hasCheckedTaskCompletionOnDisk(base, mid, sid, tid))
589
- return false;
590
- }
591
- else {
592
- // DB available but task row not found — completion tool never ran (#3607)
593
- return false;
594
- }
595
- }
596
- }
597
- // complete-slice: DB status is authoritative for whether the slice is done.
598
- // Fall back to file-based check (roadmap [x]) when DB is unavailable.
599
- if (unitType === "complete-slice") {
600
- const { milestone: mid, slice: sid } = parseUnitId(unitId);
601
- if (mid && sid) {
602
- // resolveSliceFile only finds existing files; UAT may not exist yet.
603
- // Fall back to the canonical expected location so a missing UAT always
604
- // returns false (not a silent pass when resolveSliceFile returns null).
605
- const uatPath = resolveSliceFile(base, mid, sid, "UAT")
606
- ?? join(base, relSliceFile(base, mid, sid, "UAT"));
607
- if (!existsSync(uatPath))
608
- return false;
609
- const dbSlice = getSlice(mid, sid);
610
- if (dbSlice) {
611
- // DB available — trust it
612
- if (dbSlice.status !== "complete")
613
- return false;
614
- }
615
- else if (!isDbAvailable()) {
616
- // LEGACY: Pre-migration fallback for projects without DB.
617
- // Fall back to roadmap checkbox check via parsers-legacy
618
- const roadmapFile = resolveMilestoneFile(base, mid, "ROADMAP");
619
- if (roadmapFile && existsSync(roadmapFile)) {
620
- try {
621
- const roadmapContent = readFileSync(roadmapFile, "utf-8");
622
- const roadmap = parseRoadmapForRecovery(roadmapContent);
623
- const slice = roadmap.slices.find((s) => s.id === sid);
624
- if (slice && !slice.done)
625
- return false;
626
- }
627
- catch (e) {
628
- logWarning("recovery", `roadmap parse failed: ${e.message}`);
629
- return false;
630
- }
631
- }
632
- }
633
- // else: DB available but slice not found — summary + UAT exist,
634
- // treat as verified (slice may not be imported yet)
635
- }
636
- }
637
- // complete-milestone must have produced implementation artifacts (#1703).
638
- // A milestone with only .gsd/ plan files and zero implementation code is
639
- // not genuinely complete — the LLM wrote plan files but skipped actual work.
640
- if (unitType === "complete-milestone") {
641
- const { milestone: mid } = parseUnitId(unitId);
642
- if (!mid)
643
- return false;
644
- const closeoutProof = proveMilestoneCloseout(mid, {
645
- refreshFromDisk: true,
646
- summaryArtifactBasePath: artifactBase,
647
- implementationEvidence: {
648
- basePath: base,
649
- requirement: "not-absent",
650
- },
651
- });
652
- if (!closeoutProof.ok) {
653
- if (!isDbAvailable() && closeoutProof.reason === "db-unavailable") {
654
- const summaryOutcome = classifyMilestoneSummaryContent(readFileSync(absPath, "utf-8"));
655
- return summaryOutcome !== "failure" && hasImplementationArtifacts(base, mid) !== "absent";
656
- }
657
- return false;
658
- }
659
- }
660
- return true;
661
- }
662
161
  /**
663
162
  * Terminal recovery for a failed reactive-execute batch.
664
163
  *
@@ -7,7 +7,6 @@ import { isDeterministicPolicyError, isQueuedUserMessageSkip, isToolInvocationEr
7
7
  export { isInteractiveElicitationInFlight } from "./auto-tool-tracking.js";
8
8
  import { createToolSurfaceSnapshot, } from "./tool-surface-snapshot.js";
9
9
  export const autoSession = new AutoSession();
10
- let currentToolSurfaceSnapshot = null;
11
10
  export function getAutoRuntimeSnapshot() {
12
11
  const orchestrationStatus = autoSession.orchestration?.getStatus();
13
12
  return {
@@ -18,15 +17,15 @@ export function getAutoRuntimeSnapshot() {
18
17
  orchestrationPhase: orchestrationStatus?.phase,
19
18
  orchestrationTransitionCount: orchestrationStatus?.transitionCount,
20
19
  orchestrationLastTransitionAt: orchestrationStatus?.lastTransitionAt,
21
- toolSurface: autoSession.active || autoSession.paused ? currentToolSurfaceSnapshot : null,
20
+ toolSurface: autoSession.active || autoSession.paused ? autoSession.toolSurfaceSnapshot : null,
22
21
  };
23
22
  }
24
23
  export function recordAutoToolSurfaceSnapshot(input) {
25
- currentToolSurfaceSnapshot = createToolSurfaceSnapshot(input);
26
- return currentToolSurfaceSnapshot;
24
+ autoSession.toolSurfaceSnapshot = createToolSurfaceSnapshot(input);
25
+ return autoSession.toolSurfaceSnapshot;
27
26
  }
28
27
  export function clearAutoToolSurfaceSnapshot() {
29
- currentToolSurfaceSnapshot = null;
28
+ autoSession.toolSurfaceSnapshot = null;
30
29
  }
31
30
  export function isAutoActive() {
32
31
  return autoSession.active;
@@ -4,7 +4,7 @@
4
4
  * and blocker placeholder generation.
5
5
  */
6
6
  import { readUnitRuntimeRecord, writeUnitRuntimeRecord, formatExecuteTaskRecoveryStatus, inspectExecuteTaskDurability, } from "./unit-runtime.js";
7
- import { resolveExpectedArtifactPath, diagnoseExpectedArtifact, writeBlockerPlaceholder, } from "./auto-recovery.js";
7
+ import { resolveExpectedArtifactPath, diagnoseExpectedArtifact, verifyExpectedArtifact, writeBlockerPlaceholder, } from "./auto-recovery.js";
8
8
  import { existsSync } from "node:fs";
9
9
  import { bumpAndResolveSynthetic } from "./auto/resolve.js";
10
10
  import { finalizeProjectResearchTimeout } from "./project-research-policy.js";
@@ -128,10 +128,10 @@ export async function recoverTimedOutUnit(ctx, pi, unitType, unitId, reason, rct
128
128
  bumpAndResolveSynthetic(`timeout-recovery:${reason}:${unitType}/${unitId}`);
129
129
  return "recovered";
130
130
  }
131
- // Check if the artifact already exists on disk — agent may have written it
131
+ // Check if the artifact is already valid on disk — agent may have written it
132
132
  // without signaling completion.
133
133
  const artifactPath = resolveExpectedArtifactPath(unitType, unitId, basePath);
134
- if (artifactPath && existsSync(artifactPath)) {
134
+ if (artifactPath && existsSync(artifactPath) && verifyExpectedArtifact(unitType, unitId, basePath)) {
135
135
  writeUnitRuntimeRecord(basePath, unitType, unitId, currentUnitStartedAt, {
136
136
  phase: "finalized",
137
137
  recoveryAttempts: recoveryAttempts + 1,