gsd-pi 2.45.0 → 2.46.0-dev.cc9d310

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 (347) hide show
  1. package/dist/help-text.js +1 -1
  2. package/dist/loader.js +34 -0
  3. package/dist/resources/extensions/gsd/auto/phases.js +27 -42
  4. package/dist/resources/extensions/gsd/auto/run-unit.js +6 -3
  5. package/dist/resources/extensions/gsd/auto/session.js +0 -11
  6. package/dist/resources/extensions/gsd/auto-artifact-paths.js +112 -0
  7. package/dist/resources/extensions/gsd/auto-post-unit.js +25 -96
  8. package/dist/resources/extensions/gsd/auto-start.js +2 -3
  9. package/dist/resources/extensions/gsd/auto-worktree.js +5 -4
  10. package/dist/resources/extensions/gsd/auto.js +12 -57
  11. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +15 -12
  12. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +18 -0
  13. package/dist/resources/extensions/gsd/commands/context.js +0 -4
  14. package/dist/resources/extensions/gsd/commands/handlers/parallel.js +1 -1
  15. package/dist/resources/extensions/gsd/crash-recovery.js +2 -4
  16. package/dist/resources/extensions/gsd/dashboard-overlay.js +0 -44
  17. package/dist/resources/extensions/gsd/db-writer.js +9 -9
  18. package/dist/resources/extensions/gsd/doctor-checks.js +167 -2
  19. package/dist/resources/extensions/gsd/doctor.js +5 -3
  20. package/dist/resources/extensions/gsd/gsd-db.js +16 -3
  21. package/dist/resources/extensions/gsd/guided-flow.js +1 -2
  22. package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
  23. package/dist/resources/extensions/gsd/parallel-orchestrator.js +5 -18
  24. package/dist/resources/extensions/gsd/preferences-types.js +2 -2
  25. package/dist/resources/extensions/gsd/preferences.js +8 -4
  26. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -8
  27. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -23
  28. package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
  29. package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -15
  30. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  31. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  32. package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  33. package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
  34. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  35. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -2
  36. package/dist/resources/extensions/gsd/prompts/queue.md +2 -2
  37. package/dist/resources/extensions/gsd/prompts/quick-task.md +2 -0
  38. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  39. package/dist/resources/extensions/gsd/prompts/research-slice.md +3 -3
  40. package/dist/resources/extensions/gsd/prompts/rethink.md +7 -2
  41. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  42. package/dist/resources/extensions/gsd/session-lock.js +1 -3
  43. package/dist/resources/extensions/gsd/state.js +7 -0
  44. package/dist/resources/extensions/gsd/sync-lock.js +89 -0
  45. package/dist/resources/extensions/gsd/tools/complete-milestone.js +61 -11
  46. package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -11
  47. package/dist/resources/extensions/gsd/tools/complete-task.js +50 -2
  48. package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -1
  49. package/dist/resources/extensions/gsd/tools/plan-slice.js +30 -1
  50. package/dist/resources/extensions/gsd/tools/plan-task.js +27 -1
  51. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +32 -2
  52. package/dist/resources/extensions/gsd/tools/reopen-slice.js +86 -0
  53. package/dist/resources/extensions/gsd/tools/reopen-task.js +90 -0
  54. package/dist/resources/extensions/gsd/tools/replan-slice.js +32 -2
  55. package/dist/resources/extensions/gsd/unit-ownership.js +85 -0
  56. package/dist/resources/extensions/gsd/workflow-events.js +102 -0
  57. package/dist/resources/extensions/gsd/workflow-logger.js +193 -0
  58. package/dist/resources/extensions/gsd/workflow-manifest.js +244 -0
  59. package/dist/resources/extensions/gsd/workflow-migration.js +280 -0
  60. package/dist/resources/extensions/gsd/workflow-projections.js +373 -0
  61. package/dist/resources/extensions/gsd/workflow-reconcile.js +411 -0
  62. package/dist/resources/extensions/gsd/worktree-manager.js +4 -3
  63. package/dist/resources/extensions/gsd/worktree-resolver.js +37 -0
  64. package/dist/resources/extensions/gsd/write-intercept.js +84 -0
  65. package/dist/resources/extensions/voice/index.js +11 -16
  66. package/dist/resources/extensions/voice/linux-ready.js +67 -0
  67. package/dist/web/standalone/.next/BUILD_ID +1 -1
  68. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  69. package/dist/web/standalone/.next/build-manifest.json +3 -3
  70. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  71. package/dist/web/standalone/.next/required-server-files.json +3 -3
  72. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  73. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  75. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  83. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  84. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  86. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  87. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  89. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  99. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  137. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  143. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  157. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  159. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  161. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  163. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/index.html +1 -1
  173. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  174. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  175. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  176. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  178. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app/page.js +2 -2
  180. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  182. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  183. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  184. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/middleware.js +2 -2
  186. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  188. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  189. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  190. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  191. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  192. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  193. package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
  194. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  195. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  196. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  197. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  198. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  199. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  200. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  201. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  202. package/dist/web/standalone/server.js +1 -1
  203. package/package.json +2 -1
  204. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +2 -0
  206. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -1
  208. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +4 -0
  211. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +10 -5
  213. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts +2 -0
  215. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts.map +1 -0
  216. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js +185 -0
  217. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js.map +1 -0
  218. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +239 -10
  219. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  220. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +2 -1
  221. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/model-registry.js +20 -2
  223. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/package-commands.test.js +206 -195
  225. package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -1
  226. package/packages/pi-coding-agent/package.json +1 -1
  227. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +2 -0
  228. package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
  229. package/packages/pi-coding-agent/src/core/lifecycle-hooks.test.ts +227 -0
  230. package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +11 -5
  231. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +297 -11
  232. package/packages/pi-coding-agent/src/core/model-registry.ts +30 -3
  233. package/packages/pi-coding-agent/src/core/package-commands.test.ts +227 -205
  234. package/pkg/package.json +1 -1
  235. package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -19
  236. package/src/resources/extensions/gsd/auto/phases.ts +24 -44
  237. package/src/resources/extensions/gsd/auto/run-unit.ts +6 -3
  238. package/src/resources/extensions/gsd/auto/session.ts +0 -18
  239. package/src/resources/extensions/gsd/auto-artifact-paths.ts +131 -0
  240. package/src/resources/extensions/gsd/auto-dashboard.ts +0 -1
  241. package/src/resources/extensions/gsd/auto-post-unit.ts +25 -106
  242. package/src/resources/extensions/gsd/auto-start.ts +1 -3
  243. package/src/resources/extensions/gsd/auto-worktree.ts +8 -5
  244. package/src/resources/extensions/gsd/auto.ts +7 -83
  245. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -12
  246. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
  247. package/src/resources/extensions/gsd/commands/context.ts +0 -5
  248. package/src/resources/extensions/gsd/commands/handlers/parallel.ts +1 -1
  249. package/src/resources/extensions/gsd/crash-recovery.ts +1 -5
  250. package/src/resources/extensions/gsd/dashboard-overlay.ts +0 -50
  251. package/src/resources/extensions/gsd/db-writer.ts +9 -17
  252. package/src/resources/extensions/gsd/doctor-checks.ts +180 -2
  253. package/src/resources/extensions/gsd/doctor-types.ts +7 -1
  254. package/src/resources/extensions/gsd/doctor.ts +6 -3
  255. package/src/resources/extensions/gsd/gsd-db.ts +16 -3
  256. package/src/resources/extensions/gsd/guided-flow.ts +1 -2
  257. package/src/resources/extensions/gsd/journal.ts +6 -1
  258. package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
  259. package/src/resources/extensions/gsd/parallel-orchestrator.ts +5 -21
  260. package/src/resources/extensions/gsd/preferences-types.ts +2 -2
  261. package/src/resources/extensions/gsd/preferences.ts +7 -3
  262. package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -8
  263. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -23
  264. package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
  265. package/src/resources/extensions/gsd/prompts/execute-task.md +5 -15
  266. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  267. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  268. package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  269. package/src/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
  270. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  271. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -2
  272. package/src/resources/extensions/gsd/prompts/queue.md +2 -2
  273. package/src/resources/extensions/gsd/prompts/quick-task.md +2 -0
  274. package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  275. package/src/resources/extensions/gsd/prompts/research-slice.md +3 -3
  276. package/src/resources/extensions/gsd/prompts/rethink.md +7 -2
  277. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  278. package/src/resources/extensions/gsd/session-lock.ts +0 -4
  279. package/src/resources/extensions/gsd/state.ts +8 -0
  280. package/src/resources/extensions/gsd/sync-lock.ts +94 -0
  281. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +5 -13
  282. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +6 -10
  283. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +96 -0
  284. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +264 -228
  285. package/src/resources/extensions/gsd/tests/complete-task.test.ts +317 -250
  286. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +2 -8
  287. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -3
  288. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  289. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +1 -1
  290. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +15 -24
  291. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
  292. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  293. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  294. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -1
  295. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +8 -9
  296. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +42 -3
  297. package/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +0 -1
  298. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +0 -7
  299. package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +7 -8
  300. package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +20 -24
  301. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +0 -2
  302. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +9 -6
  303. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +171 -0
  304. package/src/resources/extensions/gsd/tests/preferences.test.ts +7 -9
  305. package/src/resources/extensions/gsd/tests/projection-regression.test.ts +174 -0
  306. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +15 -14
  307. package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +155 -0
  308. package/src/resources/extensions/gsd/tests/reopen-task.test.ts +165 -0
  309. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +1 -4
  310. package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +2 -3
  311. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +122 -0
  312. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +175 -0
  313. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +205 -0
  314. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +275 -0
  315. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +186 -0
  316. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +171 -0
  317. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +220 -0
  318. package/src/resources/extensions/gsd/tests/write-intercept.test.ts +76 -0
  319. package/src/resources/extensions/gsd/tools/complete-milestone.ts +74 -11
  320. package/src/resources/extensions/gsd/tools/complete-slice.ts +68 -11
  321. package/src/resources/extensions/gsd/tools/complete-task.ts +63 -1
  322. package/src/resources/extensions/gsd/tools/plan-milestone.ts +45 -0
  323. package/src/resources/extensions/gsd/tools/plan-slice.ts +38 -0
  324. package/src/resources/extensions/gsd/tools/plan-task.ts +35 -1
  325. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +39 -1
  326. package/src/resources/extensions/gsd/tools/reopen-slice.ts +125 -0
  327. package/src/resources/extensions/gsd/tools/reopen-task.ts +129 -0
  328. package/src/resources/extensions/gsd/tools/replan-slice.ts +38 -1
  329. package/src/resources/extensions/gsd/types.ts +8 -0
  330. package/src/resources/extensions/gsd/unit-ownership.ts +104 -0
  331. package/src/resources/extensions/gsd/workflow-events.ts +154 -0
  332. package/src/resources/extensions/gsd/workflow-logger.ts +243 -0
  333. package/src/resources/extensions/gsd/workflow-manifest.ts +334 -0
  334. package/src/resources/extensions/gsd/workflow-migration.ts +345 -0
  335. package/src/resources/extensions/gsd/workflow-projections.ts +425 -0
  336. package/src/resources/extensions/gsd/workflow-reconcile.ts +503 -0
  337. package/src/resources/extensions/gsd/worktree-manager.ts +4 -9
  338. package/src/resources/extensions/gsd/worktree-resolver.ts +37 -0
  339. package/src/resources/extensions/gsd/write-intercept.ts +90 -0
  340. package/src/resources/extensions/voice/index.ts +11 -21
  341. package/src/resources/extensions/voice/linux-ready.ts +87 -0
  342. package/src/resources/extensions/voice/tests/linux-ready.test.ts +124 -0
  343. package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
  344. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  345. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  346. /package/dist/web/standalone/.next/static/{wUzEX1U3CmFcMry2SUDJn → ZIDqryyYDroh_8AnaAOSG}/_buildManifest.js +0 -0
  347. /package/dist/web/standalone/.next/static/{wUzEX1U3CmFcMry2SUDJn → ZIDqryyYDroh_8AnaAOSG}/_ssgManifest.js +0 -0
@@ -19,13 +19,11 @@ import { clearActivityLogState } from "./activity-log.js";
19
19
  import { synthesizeCrashRecovery, getDeepDiagnostic, } from "./session-forensics.js";
20
20
  import { writeLock, clearLock, readCrashLock, isLockProcessAlive, } from "./crash-recovery.js";
21
21
  import { acquireSessionLock, getSessionLockStatus, releaseSessionLock, updateSessionLock, } from "./session-lock.js";
22
- import { clearUnitRuntimeRecord, readUnitRuntimeRecord, writeUnitRuntimeRecord, } from "./unit-runtime.js";
23
22
  import { resolveAutoSupervisorConfig, loadEffectiveGSDPreferences, getIsolationMode, } from "./preferences.js";
24
23
  import { sendDesktopNotification } from "./notifications.js";
25
24
  import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, } from "./auto-budget.js";
26
25
  import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, } from "./auto-tool-tracking.js";
27
26
  import { closeoutUnit } from "./auto-unit-closeout.js";
28
- import { selfHealRuntimeRecords } from "./auto-recovery.js";
29
27
  import { selectAndApplyModel, resolveModelId } from "./auto-model-selection.js";
30
28
  import { syncProjectRootToWorktree, checkResourcesStale, escapeStaleWorktree, } from "./auto-worktree-sync.js";
31
29
  import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
@@ -44,7 +42,7 @@ import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js";
44
42
  import { createAutoWorktree, enterAutoWorktree, teardownAutoWorktree, isInAutoWorktree, getAutoWorktreePath, mergeMilestoneToMain, autoWorktreeBranch, syncWorktreeStateBack, } from "./auto-worktree.js";
45
43
  import { pruneQueueOrder } from "./queue-order.js";
46
44
  import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
47
- import { verifyExpectedArtifact, reconcileMergeState, } from "./auto-recovery.js";
45
+ import { reconcileMergeState, } from "./auto-recovery.js";
48
46
  import { resolveDispatch, DISPATCH_RULES } from "./auto-dispatch.js";
49
47
  import { initRegistry, convertDispatchRules } from "./rule-registry.js";
50
48
  import { emitJournalEvent as _emitJournalEvent } from "./journal.js";
@@ -82,11 +80,10 @@ const s = new AutoSession();
82
80
  const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
83
81
  export function shouldUseWorktreeIsolation() {
84
82
  const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
85
- if (prefs?.isolation === "none")
86
- return false;
87
- if (prefs?.isolation === "branch")
88
- return false;
89
- return true; // default: worktree
83
+ if (prefs?.isolation === "worktree")
84
+ return true;
85
+ // Default is false — worktree isolation requires explicit opt-in
86
+ return false;
90
87
  }
91
88
  /** Crash recovery prompt — set by startAuto, consumed by the main loop */
92
89
  /** Pending verification retry — set when gate fails with retries remaining, consumed by autoLoop */
@@ -146,7 +143,6 @@ export function getAutoDashboardData() {
146
143
  ? (s.autoStartTime > 0 ? Date.now() - s.autoStartTime : 0)
147
144
  : 0,
148
145
  currentUnit: s.currentUnit ? { ...s.currentUnit } : null,
149
- completedUnits: [...s.completedUnits],
150
146
  basePath: s.basePath,
151
147
  totalCost: totals?.cost ?? 0,
152
148
  totalTokens: totals?.tokens.total ?? 0,
@@ -245,7 +241,6 @@ export function checkRemoteAutoSession(projectRoot) {
245
241
  unitType: lock.unitType,
246
242
  unitId: lock.unitId,
247
243
  startedAt: lock.startedAt,
248
- completedUnits: lock.completedUnits,
249
244
  };
250
245
  }
251
246
  export function isStepMode() {
@@ -270,16 +265,12 @@ function clearUnitTimeout() {
270
265
  }
271
266
  clearInFlightTools();
272
267
  }
273
- /** Build snapshot metric opts, enriching with continueHereFired from the runtime record. */
274
- function buildSnapshotOpts(unitType, unitId) {
275
- const runtime = s.currentUnit
276
- ? readUnitRuntimeRecord(s.basePath, unitType, unitId)
277
- : null;
268
+ /** Build snapshot metric opts. */
269
+ function buildSnapshotOpts(_unitType, _unitId) {
278
270
  return {
279
271
  promptCharCount: s.lastPromptCharCount,
280
272
  baselineCharCount: s.lastBaselineCharCount,
281
273
  ...(s.currentUnitRouting ?? {}),
282
- ...(runtime?.continueHereFired ? { continueHereFired: true } : {}),
283
274
  };
284
275
  }
285
276
  function handleLostSessionLock(ctx, lockStatus) {
@@ -587,12 +578,6 @@ export async function pauseAuto(ctx, _pi) {
587
578
  catch {
588
579
  // Non-fatal — best-effort closeout on pause
589
580
  }
590
- try {
591
- clearUnitRuntimeRecord(s.basePath, s.currentUnit.type, s.currentUnit.id);
592
- }
593
- catch {
594
- // Non-fatal
595
- }
596
581
  s.currentUnit = null;
597
582
  }
598
583
  if (lockBase()) {
@@ -711,9 +696,6 @@ function buildLoopDeps() {
711
696
  getMainBranch,
712
697
  // Unit closeout + runtime records
713
698
  closeoutUnit,
714
- verifyExpectedArtifact,
715
- clearUnitRuntimeRecord,
716
- writeUnitRuntimeRecord,
717
699
  recordOutcome,
718
700
  writeLock,
719
701
  captureAvailableSkills,
@@ -862,15 +844,6 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
862
844
  });
863
845
  }
864
846
  invalidateAllCaches();
865
- // Clean stale runtime records left from the paused session
866
- try {
867
- await selfHealRuntimeRecords(s.basePath, ctx);
868
- }
869
- catch (e) {
870
- debugLog("resume-self-heal-runtime-failed", {
871
- error: e instanceof Error ? e.message : String(e),
872
- });
873
- }
874
847
  if (s.pausedSessionFile) {
875
848
  const activityDir = join(gsdRoot(s.basePath), "activity");
876
849
  const recovery = synthesizeCrashRecovery(s.basePath, s.currentUnit?.type ?? "unknown", s.currentUnit?.id ?? "unknown", s.pausedSessionFile ?? undefined, activityDir);
@@ -880,11 +853,9 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
880
853
  }
881
854
  s.pausedSessionFile = null;
882
855
  }
883
- updateSessionLock(lockBase(), "resuming", s.currentMilestoneId ?? "unknown", s.completedUnits.length);
884
- writeLock(lockBase(), "resuming", s.currentMilestoneId ?? "unknown", s.completedUnits.length);
856
+ updateSessionLock(lockBase(), "resuming", s.currentMilestoneId ?? "unknown");
857
+ writeLock(lockBase(), "resuming", s.currentMilestoneId ?? "unknown");
885
858
  logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "progress");
886
- // Clear orphaned runtime records from prior process deaths before entering the loop
887
- await selfHealRuntimeRecords(s.basePath, ctx);
888
859
  await autoLoop(ctx, pi, s, buildLoopDeps());
889
860
  cleanupAfterLoopExit(ctx);
890
861
  return;
@@ -906,8 +877,6 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
906
877
  // Best-effort only — sidebar sync must never block auto-mode startup
907
878
  }
908
879
  logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, requestedStepMode ? "Step-mode started." : "Auto-mode started.", "progress");
909
- // Clear orphaned runtime records from prior process deaths before entering the loop
910
- await selfHealRuntimeRecords(s.basePath, ctx);
911
880
  // Dispatch the first unit
912
881
  await autoLoop(ctx, pi, s, buildLoopDeps());
913
882
  cleanupAfterLoopExit(ctx);
@@ -1006,7 +975,6 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
1006
975
  s.basePath = targetBasePath;
1007
976
  s.autoStartTime = Date.now();
1008
977
  s.currentUnit = null;
1009
- s.completedUnits = [];
1010
978
  s.pendingQuickTasks = [];
1011
979
  }
1012
980
  const hookUnitType = `hook/${hookName}`;
@@ -1026,14 +994,6 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
1026
994
  id: triggerUnitId,
1027
995
  startedAt: hookStartedAt,
1028
996
  };
1029
- writeUnitRuntimeRecord(s.basePath, hookUnitType, triggerUnitId, hookStartedAt, {
1030
- phase: "dispatched",
1031
- wrapupWarningSent: false,
1032
- timeoutAt: null,
1033
- lastProgressAt: hookStartedAt,
1034
- progressCount: 0,
1035
- lastProgressKind: "dispatch",
1036
- });
1037
997
  if (hookModel) {
1038
998
  const availableModels = ctx.modelRegistry.getAvailable();
1039
999
  const match = resolveModelId(hookModel, availableModels, ctx.model?.provider);
@@ -1051,7 +1011,7 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
1051
1011
  }
1052
1012
  }
1053
1013
  const sessionFile = ctx.sessionManager.getSessionFile();
1054
- writeLock(lockBase(), hookUnitType, triggerUnitId, s.completedUnits.length, sessionFile);
1014
+ writeLock(lockBase(), hookUnitType, triggerUnitId, sessionFile);
1055
1015
  clearUnitTimeout();
1056
1016
  const supervisor = resolveAutoSupervisorConfig();
1057
1017
  const hookHardTimeoutMs = (supervisor.hard_timeout_minutes ?? 30) * 60 * 1000;
@@ -1059,12 +1019,6 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
1059
1019
  s.unitTimeoutHandle = null;
1060
1020
  if (!s.active)
1061
1021
  return;
1062
- if (s.currentUnit) {
1063
- writeUnitRuntimeRecord(s.basePath, hookUnitType, triggerUnitId, hookStartedAt, {
1064
- phase: "timeout",
1065
- timeoutAt: Date.now(),
1066
- });
1067
- }
1068
1022
  ctx.ui.notify(`Hook ${hookName} exceeded ${supervisor.hard_timeout_minutes ?? 30}min timeout. Pausing auto-mode.`, "warning");
1069
1023
  resetHookState();
1070
1024
  await pauseAuto(ctx, pi);
@@ -1087,4 +1041,5 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
1087
1041
  // Direct phase dispatch → auto-direct-dispatch.ts
1088
1042
  export { dispatchDirectPhase } from "./auto-direct-dispatch.js";
1089
1043
  // Re-export recovery functions for external consumers
1090
- export { resolveExpectedArtifactPath, verifyExpectedArtifact, writeBlockerPlaceholder, buildLoopRemediationSteps, } from "./auto-recovery.js";
1044
+ export { buildLoopRemediationSteps, } from "./auto-recovery.js";
1045
+ export { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
@@ -4,6 +4,7 @@ import { findMilestoneIds, nextMilestoneId, claimReservedId, getReservedMileston
4
4
  import { loadEffectiveGSDPreferences } from "../preferences.js";
5
5
  import { ensureDbOpen } from "./dynamic-tools.js";
6
6
  import { StringEnum } from "@gsd/pi-ai";
7
+ import { logError } from "../workflow-logger.js";
7
8
  /**
8
9
  * Register an alias tool that shares the same execute function as its canonical counterpart.
9
10
  * The alias description and promptGuidelines direct the LLM to prefer the canonical name.
@@ -45,7 +46,7 @@ export function registerDbTools(pi) {
45
46
  }
46
47
  catch (err) {
47
48
  const msg = err instanceof Error ? err.message : String(err);
48
- process.stderr.write(`gsd-db: gsd_decision_save tool failed: ${msg}\n`);
49
+ logError("tool", `gsd_decision_save tool failed: ${msg}`, { tool: "gsd_decision_save", error: String(err) });
49
50
  return {
50
51
  content: [{ type: "text", text: `Error saving decision: ${msg}` }],
51
52
  details: { operation: "save_decision", error: msg },
@@ -142,7 +143,7 @@ export function registerDbTools(pi) {
142
143
  }
143
144
  catch (err) {
144
145
  const msg = err instanceof Error ? err.message : String(err);
145
- process.stderr.write(`gsd-db: gsd_requirement_update tool failed: ${msg}\n`);
146
+ logError("tool", `gsd_requirement_update tool failed: ${msg}`, { tool: "gsd_requirement_update", error: String(err) });
146
147
  return {
147
148
  content: [{ type: "text", text: `Error updating requirement: ${msg}` }],
148
149
  details: { operation: "update_requirement", id: params.id, error: msg },
@@ -235,7 +236,7 @@ export function registerDbTools(pi) {
235
236
  }
236
237
  catch (err) {
237
238
  const msg = err instanceof Error ? err.message : String(err);
238
- process.stderr.write(`gsd-db: gsd_summary_save tool failed: ${msg}\n`);
239
+ logError("tool", `gsd_summary_save tool failed: ${msg}`, { tool: "gsd_summary_save", error: String(err) });
239
240
  return {
240
241
  content: [{ type: "text", text: `Error saving artifact: ${msg}` }],
241
242
  details: { operation: "save_summary", error: msg },
@@ -394,7 +395,7 @@ export function registerDbTools(pi) {
394
395
  }
395
396
  catch (err) {
396
397
  const msg = err instanceof Error ? err.message : String(err);
397
- process.stderr.write(`gsd-db: plan_milestone tool failed: ${msg}\n`);
398
+ logError("tool", `plan_milestone tool failed: ${msg}`, { tool: "gsd_plan_milestone", error: String(err) });
398
399
  return {
399
400
  content: [{ type: "text", text: `Error planning milestone: ${msg}` }],
400
401
  details: { operation: "plan_milestone", error: msg },
@@ -483,7 +484,7 @@ export function registerDbTools(pi) {
483
484
  }
484
485
  catch (err) {
485
486
  const msg = err instanceof Error ? err.message : String(err);
486
- process.stderr.write(`gsd-db: plan_slice tool failed: ${msg}\n`);
487
+ logError("tool", `plan_slice tool failed: ${msg}`, { tool: "gsd_plan_slice", error: String(err) });
487
488
  return {
488
489
  content: [{ type: "text", text: `Error planning slice: ${msg}` }],
489
490
  details: { operation: "plan_slice", error: msg },
@@ -556,7 +557,7 @@ export function registerDbTools(pi) {
556
557
  }
557
558
  catch (err) {
558
559
  const msg = err instanceof Error ? err.message : String(err);
559
- process.stderr.write(`gsd-db: plan_task tool failed: ${msg}\n`);
560
+ logError("tool", `plan_task tool failed: ${msg}`, { tool: "gsd_plan_task", error: String(err) });
560
561
  return {
561
562
  content: [{ type: "text", text: `Error planning task: ${msg}` }],
562
563
  details: { operation: "plan_task", error: msg },
@@ -622,7 +623,7 @@ export function registerDbTools(pi) {
622
623
  }
623
624
  catch (err) {
624
625
  const msg = err instanceof Error ? err.message : String(err);
625
- process.stderr.write(`gsd-db: complete_task tool failed: ${msg}\n`);
626
+ logError("tool", `complete_task tool failed: ${msg}`, { tool: "gsd_task_complete", error: String(err) });
626
627
  return {
627
628
  content: [{ type: "text", text: `Error completing task: ${msg}` }],
628
629
  details: { operation: "complete_task", error: msg },
@@ -696,7 +697,7 @@ export function registerDbTools(pi) {
696
697
  }
697
698
  catch (err) {
698
699
  const msg = err instanceof Error ? err.message : String(err);
699
- process.stderr.write(`gsd-db: complete_slice tool failed: ${msg}\n`);
700
+ logError("tool", `complete_slice tool failed: ${msg}`, { tool: "gsd_slice_complete", error: String(err) });
700
701
  return {
701
702
  content: [{ type: "text", text: `Error completing slice: ${msg}` }],
702
703
  details: { operation: "complete_slice", error: msg },
@@ -788,7 +789,7 @@ export function registerDbTools(pi) {
788
789
  }
789
790
  catch (err) {
790
791
  const msg = err instanceof Error ? err.message : String(err);
791
- process.stderr.write(`gsd-db: complete_milestone tool failed: ${msg}\n`);
792
+ logError("tool", `complete_milestone tool failed: ${msg}`, { tool: "gsd_complete_milestone", error: String(err) });
792
793
  return {
793
794
  content: [{ type: "text", text: `Error completing milestone: ${msg}` }],
794
795
  details: { operation: "complete_milestone", error: msg },
@@ -804,6 +805,7 @@ export function registerDbTools(pi) {
804
805
  promptGuidelines: [
805
806
  "Use gsd_complete_milestone when all slices in a milestone are finished and the milestone needs to be recorded.",
806
807
  "All slices in the milestone must have status 'complete' — the handler validates this before proceeding.",
808
+ "verificationPassed must be explicitly set to true — the handler rejects completion if verification did not pass.",
807
809
  "On success, returns summaryPath where the MILESTONE-SUMMARY.md was written.",
808
810
  ],
809
811
  parameters: Type.Object({
@@ -819,6 +821,7 @@ export function registerDbTools(pi) {
819
821
  lessonsLearned: Type.Array(Type.String(), { description: "Lessons learned during the milestone" }),
820
822
  followUps: Type.Optional(Type.String({ description: "Follow-up items for future milestones" })),
821
823
  deviations: Type.Optional(Type.String({ description: "Deviations from the original plan" })),
824
+ verificationPassed: Type.Boolean({ description: "Must be true — confirms that code change verification, success criteria, and definition of done checks all passed before completion" }),
822
825
  }),
823
826
  execute: milestoneCompleteExecute,
824
827
  };
@@ -854,7 +857,7 @@ export function registerDbTools(pi) {
854
857
  }
855
858
  catch (err) {
856
859
  const msg = err instanceof Error ? err.message : String(err);
857
- process.stderr.write(`gsd-db: validate_milestone tool failed: ${msg}\n`);
860
+ logError("tool", `validate_milestone tool failed: ${msg}`, { tool: "gsd_validate_milestone", error: String(err) });
858
861
  return {
859
862
  content: [{ type: "text", text: `Error validating milestone: ${msg}` }],
860
863
  details: { operation: "validate_milestone", error: msg },
@@ -919,7 +922,7 @@ export function registerDbTools(pi) {
919
922
  }
920
923
  catch (err) {
921
924
  const msg = err instanceof Error ? err.message : String(err);
922
- process.stderr.write(`gsd-db: replan_slice tool failed: ${msg}\n`);
925
+ logError("tool", `replan_slice tool failed: ${msg}`, { tool: "gsd_replan_slice", error: String(err) });
923
926
  return {
924
927
  content: [{ type: "text", text: `Error replanning slice: ${msg}` }],
925
928
  details: { operation: "replan_slice", error: msg },
@@ -992,7 +995,7 @@ export function registerDbTools(pi) {
992
995
  }
993
996
  catch (err) {
994
997
  const msg = err instanceof Error ? err.message : String(err);
995
- process.stderr.write(`gsd-db: reassess_roadmap tool failed: ${msg}\n`);
998
+ logError("tool", `reassess_roadmap tool failed: ${msg}`, { tool: "gsd_reassess_roadmap", error: String(err) });
996
999
  return {
997
1000
  content: [{ type: "text", text: `Error reassessing roadmap: ${msg}` }],
998
1001
  details: { operation: "reassess_roadmap", error: msg },
@@ -4,6 +4,7 @@ import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolve
4
4
  import { buildBeforeAgentStartResult } from "./system-context.js";
5
5
  import { handleAgentEnd } from "./agent-end-recovery.js";
6
6
  import { isDepthVerified, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite } from "./write-gate.js";
7
+ import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
7
8
  import { getDiscussionMilestoneId } from "../guided-flow.js";
8
9
  import { loadToolApiKeys } from "../commands-config.js";
9
10
  import { loadFile, saveFile, formatContinue } from "../files.js";
@@ -128,6 +129,23 @@ export function registerHooks(pi) {
128
129
  if (loopCheck.block) {
129
130
  return { block: true, reason: loopCheck.reason };
130
131
  }
132
+ // ── Single-writer engine: block direct writes to STATE.md ──────────
133
+ // Covers write, edit, and bash tools to prevent bypass vectors.
134
+ if (isToolCallEventType("write", event)) {
135
+ if (isBlockedStateFile(event.input.path)) {
136
+ return { block: true, reason: BLOCKED_WRITE_ERROR };
137
+ }
138
+ }
139
+ if (isToolCallEventType("edit", event)) {
140
+ if (isBlockedStateFile(event.input.path)) {
141
+ return { block: true, reason: BLOCKED_WRITE_ERROR };
142
+ }
143
+ }
144
+ if (isToolCallEventType("bash", event)) {
145
+ if (isBashWriteToStateFile(event.input.command)) {
146
+ return { block: true, reason: BLOCKED_WRITE_ERROR };
147
+ }
148
+ }
131
149
  if (!isToolCallEventType("write", event))
132
150
  return;
133
151
  const result = shouldBlockContextWrite(event.toolName, event.input.path, getDiscussionMilestoneId(), isDepthVerified(), isQueuePhaseActive());
@@ -30,14 +30,10 @@ export async function guardRemoteSession(ctx, pi) {
30
30
  `Stop it first with /gsd stop, or use /gsd steer to redirect it.`, "warning");
31
31
  return false;
32
32
  }
33
- const unitsMsg = remote.completedUnits != null
34
- ? `${remote.completedUnits} units completed`
35
- : "";
36
33
  const choice = await showNextAction(ctx, {
37
34
  title: `Auto-mode is running in another terminal (PID ${remote.pid})`,
38
35
  summary: [
39
36
  `Currently executing: ${unitLabel}`,
40
- ...(unitsMsg ? [unitsMsg] : []),
41
37
  ...(remote.startedAt ? [`Started: ${remote.startedAt}`] : []),
42
38
  ],
43
39
  actions: [
@@ -44,7 +44,7 @@ export async function handleParallelCommand(trimmed, _ctx, pi) {
44
44
  }
45
45
  const lines = ["# Parallel Workers\n"];
46
46
  for (const worker of workers) {
47
- lines.push(`- **${worker.milestoneId}** (${worker.title}) — ${worker.state} — ${worker.completedUnits} units — $${worker.cost.toFixed(2)}`);
47
+ lines.push(`- **${worker.milestoneId}** (${worker.title}) — ${worker.state} — $${worker.cost.toFixed(2)}`);
48
48
  }
49
49
  const state = getOrchestratorState();
50
50
  if (state) {
@@ -18,7 +18,7 @@ function lockPath(basePath) {
18
18
  return join(gsdRoot(basePath), LOCK_FILE);
19
19
  }
20
20
  /** Write or update the lock file with current auto-mode state. */
21
- export function writeLock(basePath, unitType, unitId, completedUnits, sessionFile) {
21
+ export function writeLock(basePath, unitType, unitId, sessionFile) {
22
22
  try {
23
23
  const data = {
24
24
  pid: process.pid,
@@ -26,7 +26,6 @@ export function writeLock(basePath, unitType, unitId, completedUnits, sessionFil
26
26
  unitType,
27
27
  unitId,
28
28
  unitStartedAt: new Date().toISOString(),
29
- completedUnits,
30
29
  sessionFile,
31
30
  };
32
31
  const lp = lockPath(basePath);
@@ -90,11 +89,10 @@ export function formatCrashInfo(lock) {
90
89
  `Previous auto-mode session was interrupted.`,
91
90
  ` Was executing: ${lock.unitType} (${lock.unitId})`,
92
91
  ` Started at: ${lock.unitStartedAt}`,
93
- ` Units completed before crash: ${lock.completedUnits}`,
94
92
  ` PID: ${lock.pid}`,
95
93
  ];
96
94
  // Add recovery guidance based on what was happening when it crashed
97
- if (lock.unitType === "starting" && lock.unitId === "bootstrap" && lock.completedUnits === 0) {
95
+ if (lock.unitType === "starting" && lock.unitId === "bootstrap") {
98
96
  lines.push(`No work was lost. Run /gsd auto to restart.`);
99
97
  }
100
98
  else if (lock.unitType.includes("research") || lock.unitType.includes("plan")) {
@@ -81,18 +81,11 @@ export class GSDDashboardOverlay {
81
81
  const currentUnit = dashData.currentUnit
82
82
  ? `${dashData.currentUnit.type}:${dashData.currentUnit.id}:${dashData.currentUnit.startedAt}`
83
83
  : "-";
84
- const lastCompleted = dashData.completedUnits.length > 0
85
- ? dashData.completedUnits[dashData.completedUnits.length - 1]
86
- : null;
87
- const completedKey = lastCompleted
88
- ? `${dashData.completedUnits.length}:${lastCompleted.type}:${lastCompleted.id}:${lastCompleted.finishedAt}`
89
- : "0";
90
84
  return [
91
85
  base,
92
86
  dashData.active ? "1" : "0",
93
87
  dashData.paused ? "1" : "0",
94
88
  currentUnit,
95
- completedKey,
96
89
  ].join("|");
97
90
  }
98
91
  async refreshDashboard(initial = false) {
@@ -393,43 +386,6 @@ export class GSDDashboardOverlay {
393
386
  else {
394
387
  lines.push(centered(th.fg("dim", "No active milestone.")));
395
388
  }
396
- if (this.dashData.completedUnits.length > 0) {
397
- lines.push(blank());
398
- lines.push(hr());
399
- lines.push(row(th.fg("text", th.bold("Completed"))));
400
- lines.push(blank());
401
- // Build ledger lookup for budget indicators (last entry wins for retries)
402
- const ledgerLookup = new Map();
403
- const currentLedger = getLedger();
404
- if (currentLedger) {
405
- for (const lu of currentLedger.units) {
406
- ledgerLookup.set(`${lu.type}:${lu.id}`, lu);
407
- }
408
- }
409
- const recent = [...this.dashData.completedUnits].reverse().slice(0, 10);
410
- for (const u of recent) {
411
- // Budget indicators from ledger — use warning glyph for pressured units
412
- const ledgerEntry = ledgerLookup.get(`${u.type}:${u.id}`);
413
- const hadPressure = ledgerEntry?.continueHereFired === true;
414
- const hadTruncation = (ledgerEntry?.truncationSections ?? 0) > 0;
415
- const unitGlyph = hadPressure
416
- ? th.fg(STATUS_COLOR.warning, STATUS_GLYPH.warning)
417
- : th.fg(STATUS_COLOR.done, STATUS_GLYPH.done);
418
- const left = ` ${unitGlyph} ${th.fg("muted", unitLabel(u.type))} ${th.fg("muted", u.id)}`;
419
- let budgetMarkers = "";
420
- if (hadTruncation) {
421
- budgetMarkers += th.fg("warning", ` ▼${ledgerEntry.truncationSections}`);
422
- }
423
- if (hadPressure) {
424
- budgetMarkers += th.fg("error", " → wrap-up");
425
- }
426
- const right = th.fg("dim", formatDuration(u.finishedAt - u.startedAt));
427
- lines.push(row(joinColumns(`${left}${budgetMarkers}`, right, contentWidth)));
428
- }
429
- if (this.dashData.completedUnits.length > 10) {
430
- lines.push(row(th.fg("dim", ` ...and ${this.dashData.completedUnits.length - 10} more`)));
431
- }
432
- }
433
389
  const ledger = getLedger();
434
390
  if (ledger && ledger.units.length > 0) {
435
391
  const totals = getProjectTotals(ledger.units);
@@ -12,6 +12,7 @@ import { readFileSync, existsSync, statSync } from 'node:fs';
12
12
  import { resolveGsdRootFile } from './paths.js';
13
13
  import { saveFile } from './files.js';
14
14
  import { GSDError, GSD_STALE_STATE, GSD_IO_ERROR } from './errors.js';
15
+ import { logWarning, logError } from './workflow-logger.js';
15
16
  import { invalidateStateCache } from './state.js';
16
17
  import { clearPathCache } from './paths.js';
17
18
  import { clearParseCache } from './files.js';
@@ -200,7 +201,7 @@ export async function nextDecisionId() {
200
201
  return `D${String(next).padStart(3, '0')}`;
201
202
  }
202
203
  catch (err) {
203
- process.stderr.write(`gsd-db: nextDecisionId failed: ${err.message}\n`);
204
+ logError('manifest', 'nextDecisionId failed', { fn: 'nextDecisionId', error: String(err.message) });
204
205
  return 'D001';
205
206
  }
206
207
  }
@@ -269,7 +270,7 @@ export async function saveDecisionToDb(fields, basePath) {
269
270
  await saveFile(filePath, md);
270
271
  }
271
272
  catch (diskErr) {
272
- process.stderr.write(`gsd-db: saveDecisionToDb — disk write failed, rolling back DB row: ${diskErr.message}\n`);
273
+ logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveDecisionToDb', error: String(diskErr.message) });
273
274
  adapter?.prepare('DELETE FROM decisions WHERE id = :id').run({ ':id': id });
274
275
  throw diskErr;
275
276
  }
@@ -281,7 +282,7 @@ export async function saveDecisionToDb(fields, basePath) {
281
282
  return { id };
282
283
  }
283
284
  catch (err) {
284
- process.stderr.write(`gsd-db: saveDecisionToDb failed: ${err.message}\n`);
285
+ logError('manifest', 'saveDecisionToDb failed', { fn: 'saveDecisionToDb', error: String(err.message) });
285
286
  throw err;
286
287
  }
287
288
  }
@@ -333,7 +334,7 @@ export async function updateRequirementInDb(id, updates, basePath) {
333
334
  await saveFile(filePath, md);
334
335
  }
335
336
  catch (diskErr) {
336
- process.stderr.write(`gsd-db: updateRequirementInDb — disk write failed, reverting DB row: ${diskErr.message}\n`);
337
+ logError('manifest', 'disk write failed, reverting DB row', { fn: 'updateRequirementInDb', error: String(diskErr.message) });
337
338
  db.upsertRequirement(existing);
338
339
  throw diskErr;
339
340
  }
@@ -344,7 +345,7 @@ export async function updateRequirementInDb(id, updates, basePath) {
344
345
  clearParseCache();
345
346
  }
346
347
  catch (err) {
347
- process.stderr.write(`gsd-db: updateRequirementInDb failed: ${err.message}\n`);
348
+ logError('manifest', 'updateRequirementInDb failed', { fn: 'updateRequirementInDb', error: String(err.message) });
348
349
  throw err;
349
350
  }
350
351
  }
@@ -371,8 +372,7 @@ export async function saveArtifactToDb(opts, basePath) {
371
372
  const existingSize = statSync(fullPath).size;
372
373
  const newSize = Buffer.byteLength(opts.content, 'utf-8');
373
374
  if (existingSize > 0 && newSize < existingSize * 0.5) {
374
- process.stderr.write(`gsd-db: saveArtifactToDb — new content (${newSize}B) is <50% of existing file ` +
375
- `(${existingSize}B) at ${opts.path}. Preserving disk file to prevent data loss.\n`);
375
+ logWarning('manifest', `new content (${newSize}B) is <50% of existing file (${existingSize}B), preserving disk file`, { fn: 'saveArtifactToDb', path: opts.path });
376
376
  dbContent = readFileSync(fullPath, 'utf-8');
377
377
  skipDiskWrite = true;
378
378
  }
@@ -391,7 +391,7 @@ export async function saveArtifactToDb(opts, basePath) {
391
391
  await saveFile(fullPath, opts.content);
392
392
  }
393
393
  catch (diskErr) {
394
- process.stderr.write(`gsd-db: saveArtifactToDb — disk write failed, rolling back DB row: ${diskErr.message}\n`);
394
+ logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveArtifactToDb', error: String(diskErr.message) });
395
395
  const rollbackAdapter = db._getAdapter();
396
396
  rollbackAdapter?.prepare('DELETE FROM artifacts WHERE path = :path').run({ ':path': opts.path });
397
397
  throw diskErr;
@@ -404,7 +404,7 @@ export async function saveArtifactToDb(opts, basePath) {
404
404
  clearParseCache();
405
405
  }
406
406
  catch (err) {
407
- process.stderr.write(`gsd-db: saveArtifactToDb failed: ${err.message}\n`);
407
+ logError('manifest', 'saveArtifactToDb failed', { fn: 'saveArtifactToDb', error: String(err.message) });
408
408
  throw err;
409
409
  }
410
410
  }