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
@@ -52,12 +52,6 @@ import {
52
52
  updateSessionLock,
53
53
  } from "./session-lock.js";
54
54
  import type { SessionLockStatus } from "./session-lock.js";
55
- import {
56
- clearUnitRuntimeRecord,
57
- inspectExecuteTaskDurability,
58
- readUnitRuntimeRecord,
59
- writeUnitRuntimeRecord,
60
- } from "./unit-runtime.js";
61
55
  import {
62
56
  resolveAutoSupervisorConfig,
63
57
  loadEffectiveGSDPreferences,
@@ -81,7 +75,6 @@ import {
81
75
  } from "./auto-tool-tracking.js";
82
76
  import { closeoutUnit } from "./auto-unit-closeout.js";
83
77
  import { recoverTimedOutUnit } from "./auto-timeout-recovery.js";
84
- import { selfHealRuntimeRecords } from "./auto-recovery.js";
85
78
  import { selectAndApplyModel, resolveModelId } from "./auto-model-selection.js";
86
79
  import {
87
80
  syncProjectRootToWorktree,
@@ -155,10 +148,6 @@ import { pruneQueueOrder } from "./queue-order.js";
155
148
 
156
149
  import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
157
150
  import {
158
- resolveExpectedArtifactPath,
159
- verifyExpectedArtifact,
160
- writeBlockerPlaceholder,
161
- diagnoseExpectedArtifact,
162
151
  buildLoopRemediationSteps,
163
152
  reconcileMergeState,
164
153
  } from "./auto-recovery.js";
@@ -213,7 +202,6 @@ import {
213
202
  NEW_SESSION_TIMEOUT_MS,
214
203
  } from "./auto/session.js";
215
204
  import type {
216
- CompletedUnit,
217
205
  CurrentUnit,
218
206
  UnitRouting,
219
207
  StartModel,
@@ -225,7 +213,6 @@ export {
225
213
  NEW_SESSION_TIMEOUT_MS,
226
214
  } from "./auto/session.js";
227
215
  export type {
228
- CompletedUnit,
229
216
  CurrentUnit,
230
217
  UnitRouting,
231
218
  StartModel,
@@ -250,9 +237,9 @@ const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
250
237
 
251
238
  export function shouldUseWorktreeIsolation(): boolean {
252
239
  const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
253
- if (prefs?.isolation === "none") return false;
254
- if (prefs?.isolation === "branch") return false;
255
- return true; // default: worktree
240
+ if (prefs?.isolation === "worktree") return true;
241
+ // Default is false — worktree isolation requires explicit opt-in
242
+ return false;
256
243
  }
257
244
 
258
245
  /** Crash recovery prompt — set by startAuto, consumed by the main loop */
@@ -335,7 +322,6 @@ export function getAutoDashboardData(): AutoDashboardData {
335
322
  ? (s.autoStartTime > 0 ? Date.now() - s.autoStartTime : 0)
336
323
  : 0,
337
324
  currentUnit: s.currentUnit ? { ...s.currentUnit } : null,
338
- completedUnits: [...s.completedUnits],
339
325
  basePath: s.basePath,
340
326
  totalCost: totals?.cost ?? 0,
341
327
  totalTokens: totals?.tokens.total ?? 0,
@@ -447,7 +433,6 @@ export function checkRemoteAutoSession(projectRoot: string): {
447
433
  unitType?: string;
448
434
  unitId?: string;
449
435
  startedAt?: string;
450
- completedUnits?: number;
451
436
  } {
452
437
  const lock = readCrashLock(projectRoot);
453
438
  if (!lock) return { running: false };
@@ -463,7 +448,6 @@ export function checkRemoteAutoSession(projectRoot: string): {
463
448
  unitType: lock.unitType,
464
449
  unitId: lock.unitId,
465
450
  startedAt: lock.startedAt,
466
- completedUnits: lock.completedUnits,
467
451
  };
468
452
  }
469
453
 
@@ -491,23 +475,19 @@ function clearUnitTimeout(): void {
491
475
  clearInFlightTools();
492
476
  }
493
477
 
494
- /** Build snapshot metric opts, enriching with continueHereFired from the runtime record. */
478
+ /** Build snapshot metric opts. */
495
479
  function buildSnapshotOpts(
496
- unitType: string,
497
- unitId: string,
480
+ _unitType: string,
481
+ _unitId: string,
498
482
  ): {
499
483
  continueHereFired?: boolean;
500
484
  promptCharCount?: number;
501
485
  baselineCharCount?: number;
502
486
  } & Record<string, unknown> {
503
- const runtime = s.currentUnit
504
- ? readUnitRuntimeRecord(s.basePath, unitType, unitId)
505
- : null;
506
487
  return {
507
488
  promptCharCount: s.lastPromptCharCount,
508
489
  baselineCharCount: s.lastBaselineCharCount,
509
490
  ...(s.currentUnitRouting ?? {}),
510
- ...(runtime?.continueHereFired ? { continueHereFired: true } : {}),
511
491
  };
512
492
  }
513
493
 
@@ -848,11 +828,6 @@ export async function pauseAuto(
848
828
  } catch {
849
829
  // Non-fatal — best-effort closeout on pause
850
830
  }
851
- try {
852
- clearUnitRuntimeRecord(s.basePath, s.currentUnit.type, s.currentUnit.id);
853
- } catch {
854
- // Non-fatal
855
- }
856
831
  s.currentUnit = null;
857
832
  }
858
833
 
@@ -993,9 +968,6 @@ function buildLoopDeps(): LoopDeps {
993
968
  getMainBranch,
994
969
  // Unit closeout + runtime records
995
970
  closeoutUnit,
996
- verifyExpectedArtifact,
997
- clearUnitRuntimeRecord,
998
- writeUnitRuntimeRecord,
999
971
  recordOutcome,
1000
972
  writeLock,
1001
973
  captureAvailableSkills,
@@ -1168,15 +1140,6 @@ export async function startAuto(
1168
1140
  }
1169
1141
  invalidateAllCaches();
1170
1142
 
1171
- // Clean stale runtime records left from the paused session
1172
- try {
1173
- await selfHealRuntimeRecords(s.basePath, ctx);
1174
- } catch (e) {
1175
- debugLog("resume-self-heal-runtime-failed", {
1176
- error: e instanceof Error ? e.message : String(e),
1177
- });
1178
- }
1179
-
1180
1143
  if (s.pausedSessionFile) {
1181
1144
  const activityDir = join(gsdRoot(s.basePath), "activity");
1182
1145
  const recovery = synthesizeCrashRecovery(
@@ -1200,19 +1163,14 @@ export async function startAuto(
1200
1163
  lockBase(),
1201
1164
  "resuming",
1202
1165
  s.currentMilestoneId ?? "unknown",
1203
- s.completedUnits.length,
1204
1166
  );
1205
1167
  writeLock(
1206
1168
  lockBase(),
1207
1169
  "resuming",
1208
1170
  s.currentMilestoneId ?? "unknown",
1209
- s.completedUnits.length,
1210
1171
  );
1211
1172
  logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "progress");
1212
1173
 
1213
- // Clear orphaned runtime records from prior process deaths before entering the loop
1214
- await selfHealRuntimeRecords(s.basePath, ctx);
1215
-
1216
1174
  await autoLoop(ctx, pi, s, buildLoopDeps());
1217
1175
  cleanupAfterLoopExit(ctx);
1218
1176
  return;
@@ -1244,9 +1202,6 @@ export async function startAuto(
1244
1202
  }
1245
1203
  logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, requestedStepMode ? "Step-mode started." : "Auto-mode started.", "progress");
1246
1204
 
1247
- // Clear orphaned runtime records from prior process deaths before entering the loop
1248
- await selfHealRuntimeRecords(s.basePath, ctx);
1249
-
1250
1205
  // Dispatch the first unit
1251
1206
  await autoLoop(ctx, pi, s, buildLoopDeps());
1252
1207
  cleanupAfterLoopExit(ctx);
@@ -1387,7 +1342,6 @@ export async function dispatchHookUnit(
1387
1342
  s.basePath = targetBasePath;
1388
1343
  s.autoStartTime = Date.now();
1389
1344
  s.currentUnit = null;
1390
- s.completedUnits = [];
1391
1345
  s.pendingQuickTasks = [];
1392
1346
  }
1393
1347
 
@@ -1412,21 +1366,6 @@ export async function dispatchHookUnit(
1412
1366
  startedAt: hookStartedAt,
1413
1367
  };
1414
1368
 
1415
- writeUnitRuntimeRecord(
1416
- s.basePath,
1417
- hookUnitType,
1418
- triggerUnitId,
1419
- hookStartedAt,
1420
- {
1421
- phase: "dispatched",
1422
- wrapupWarningSent: false,
1423
- timeoutAt: null,
1424
- lastProgressAt: hookStartedAt,
1425
- progressCount: 0,
1426
- lastProgressKind: "dispatch",
1427
- },
1428
- );
1429
-
1430
1369
  if (hookModel) {
1431
1370
  const availableModels = ctx.modelRegistry.getAvailable();
1432
1371
  const match = resolveModelId(hookModel, availableModels, ctx.model?.provider);
@@ -1450,7 +1389,6 @@ export async function dispatchHookUnit(
1450
1389
  lockBase(),
1451
1390
  hookUnitType,
1452
1391
  triggerUnitId,
1453
- s.completedUnits.length,
1454
1392
  sessionFile,
1455
1393
  );
1456
1394
 
@@ -1460,18 +1398,6 @@ export async function dispatchHookUnit(
1460
1398
  s.unitTimeoutHandle = setTimeout(async () => {
1461
1399
  s.unitTimeoutHandle = null;
1462
1400
  if (!s.active) return;
1463
- if (s.currentUnit) {
1464
- writeUnitRuntimeRecord(
1465
- s.basePath,
1466
- hookUnitType,
1467
- triggerUnitId,
1468
- hookStartedAt,
1469
- {
1470
- phase: "timeout",
1471
- timeoutAt: Date.now(),
1472
- },
1473
- );
1474
- }
1475
1401
  ctx.ui.notify(
1476
1402
  `Hook ${hookName} exceeded ${supervisor.hard_timeout_minutes ?? 30}min timeout. Pausing auto-mode.`,
1477
1403
  "warning",
@@ -1503,8 +1429,6 @@ export { dispatchDirectPhase } from "./auto-direct-dispatch.js";
1503
1429
 
1504
1430
  // Re-export recovery functions for external consumers
1505
1431
  export {
1506
- resolveExpectedArtifactPath,
1507
- verifyExpectedArtifact,
1508
- writeBlockerPlaceholder,
1509
1432
  buildLoopRemediationSteps,
1510
1433
  } from "./auto-recovery.js";
1434
+ export { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
@@ -6,6 +6,7 @@ import { findMilestoneIds, nextMilestoneId, claimReservedId, getReservedMileston
6
6
  import { loadEffectiveGSDPreferences } from "../preferences.js";
7
7
  import { ensureDbOpen } from "./dynamic-tools.js";
8
8
  import { StringEnum } from "@gsd/pi-ai";
9
+ import { logError } from "../workflow-logger.js";
9
10
 
10
11
  /**
11
12
  * Register an alias tool that shares the same execute function as its canonical counterpart.
@@ -52,7 +53,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
52
53
  };
53
54
  } catch (err) {
54
55
  const msg = err instanceof Error ? err.message : String(err);
55
- process.stderr.write(`gsd-db: gsd_decision_save tool failed: ${msg}\n`);
56
+ logError("tool", `gsd_decision_save tool failed: ${msg}`, { tool: "gsd_decision_save", error: String(err) });
56
57
  return {
57
58
  content: [{ type: "text" as const, text: `Error saving decision: ${msg}` }],
58
59
  details: { operation: "save_decision", error: msg } as any,
@@ -143,7 +144,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
143
144
  };
144
145
  } catch (err) {
145
146
  const msg = err instanceof Error ? err.message : String(err);
146
- process.stderr.write(`gsd-db: gsd_requirement_update tool failed: ${msg}\n`);
147
+ logError("tool", `gsd_requirement_update tool failed: ${msg}`, { tool: "gsd_requirement_update", error: String(err) });
147
148
  return {
148
149
  content: [{ type: "text" as const, text: `Error updating requirement: ${msg}` }],
149
150
  details: { operation: "update_requirement", id: params.id, error: msg } as any,
@@ -239,7 +240,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
239
240
  };
240
241
  } catch (err) {
241
242
  const msg = err instanceof Error ? err.message : String(err);
242
- process.stderr.write(`gsd-db: gsd_summary_save tool failed: ${msg}\n`);
243
+ logError("tool", `gsd_summary_save tool failed: ${msg}`, { tool: "gsd_summary_save", error: String(err) });
243
244
  return {
244
245
  content: [{ type: "text" as const, text: `Error saving artifact: ${msg}` }],
245
246
  details: { operation: "save_summary", error: msg } as any,
@@ -402,7 +403,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
402
403
  };
403
404
  } catch (err) {
404
405
  const msg = err instanceof Error ? err.message : String(err);
405
- process.stderr.write(`gsd-db: plan_milestone tool failed: ${msg}\n`);
406
+ logError("tool", `plan_milestone tool failed: ${msg}`, { tool: "gsd_plan_milestone", error: String(err) });
406
407
  return {
407
408
  content: [{ type: "text" as const, text: `Error planning milestone: ${msg}` }],
408
409
  details: { operation: "plan_milestone", error: msg } as any,
@@ -495,7 +496,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
495
496
  };
496
497
  } catch (err) {
497
498
  const msg = err instanceof Error ? err.message : String(err);
498
- process.stderr.write(`gsd-db: plan_slice tool failed: ${msg}\n`);
499
+ logError("tool", `plan_slice tool failed: ${msg}`, { tool: "gsd_plan_slice", error: String(err) });
499
500
  return {
500
501
  content: [{ type: "text" as const, text: `Error planning slice: ${msg}` }],
501
502
  details: { operation: "plan_slice", error: msg } as any,
@@ -572,7 +573,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
572
573
  };
573
574
  } catch (err) {
574
575
  const msg = err instanceof Error ? err.message : String(err);
575
- process.stderr.write(`gsd-db: plan_task tool failed: ${msg}\n`);
576
+ logError("tool", `plan_task tool failed: ${msg}`, { tool: "gsd_plan_task", error: String(err) });
576
577
  return {
577
578
  content: [{ type: "text" as const, text: `Error planning task: ${msg}` }],
578
579
  details: { operation: "plan_task", error: msg } as any,
@@ -642,7 +643,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
642
643
  };
643
644
  } catch (err) {
644
645
  const msg = err instanceof Error ? err.message : String(err);
645
- process.stderr.write(`gsd-db: complete_task tool failed: ${msg}\n`);
646
+ logError("tool", `complete_task tool failed: ${msg}`, { tool: "gsd_task_complete", error: String(err) });
646
647
  return {
647
648
  content: [{ type: "text" as const, text: `Error completing task: ${msg}` }],
648
649
  details: { operation: "complete_task", error: msg } as any,
@@ -723,7 +724,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
723
724
  };
724
725
  } catch (err) {
725
726
  const msg = err instanceof Error ? err.message : String(err);
726
- process.stderr.write(`gsd-db: complete_slice tool failed: ${msg}\n`);
727
+ logError("tool", `complete_slice tool failed: ${msg}`, { tool: "gsd_slice_complete", error: String(err) });
727
728
  return {
728
729
  content: [{ type: "text" as const, text: `Error completing slice: ${msg}` }],
729
730
  details: { operation: "complete_slice", error: msg } as any,
@@ -834,7 +835,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
834
835
  };
835
836
  } catch (err) {
836
837
  const msg = err instanceof Error ? err.message : String(err);
837
- process.stderr.write(`gsd-db: complete_milestone tool failed: ${msg}\n`);
838
+ logError("tool", `complete_milestone tool failed: ${msg}`, { tool: "gsd_complete_milestone", error: String(err) });
838
839
  return {
839
840
  content: [{ type: "text" as const, text: `Error completing milestone: ${msg}` }],
840
841
  details: { operation: "complete_milestone", error: msg } as any,
@@ -852,6 +853,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
852
853
  promptGuidelines: [
853
854
  "Use gsd_complete_milestone when all slices in a milestone are finished and the milestone needs to be recorded.",
854
855
  "All slices in the milestone must have status 'complete' — the handler validates this before proceeding.",
856
+ "verificationPassed must be explicitly set to true — the handler rejects completion if verification did not pass.",
855
857
  "On success, returns summaryPath where the MILESTONE-SUMMARY.md was written.",
856
858
  ],
857
859
  parameters: Type.Object({
@@ -867,6 +869,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
867
869
  lessonsLearned: Type.Array(Type.String(), { description: "Lessons learned during the milestone" }),
868
870
  followUps: Type.Optional(Type.String({ description: "Follow-up items for future milestones" })),
869
871
  deviations: Type.Optional(Type.String({ description: "Deviations from the original plan" })),
872
+ verificationPassed: Type.Boolean({ description: "Must be true — confirms that code change verification, success criteria, and definition of done checks all passed before completion" }),
870
873
  }),
871
874
  execute: milestoneCompleteExecute,
872
875
  };
@@ -904,7 +907,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
904
907
  };
905
908
  } catch (err) {
906
909
  const msg = err instanceof Error ? err.message : String(err);
907
- process.stderr.write(`gsd-db: validate_milestone tool failed: ${msg}\n`);
910
+ logError("tool", `validate_milestone tool failed: ${msg}`, { tool: "gsd_validate_milestone", error: String(err) });
908
911
  return {
909
912
  content: [{ type: "text" as const, text: `Error validating milestone: ${msg}` }],
910
913
  details: { operation: "validate_milestone", error: msg } as any,
@@ -973,7 +976,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
973
976
  };
974
977
  } catch (err) {
975
978
  const msg = err instanceof Error ? err.message : String(err);
976
- process.stderr.write(`gsd-db: replan_slice tool failed: ${msg}\n`);
979
+ logError("tool", `replan_slice tool failed: ${msg}`, { tool: "gsd_replan_slice", error: String(err) });
977
980
  return {
978
981
  content: [{ type: "text" as const, text: `Error replanning slice: ${msg}` }],
979
982
  details: { operation: "replan_slice", error: msg } as any,
@@ -1053,7 +1056,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
1053
1056
  };
1054
1057
  } catch (err) {
1055
1058
  const msg = err instanceof Error ? err.message : String(err);
1056
- process.stderr.write(`gsd-db: reassess_roadmap tool failed: ${msg}\n`);
1059
+ logError("tool", `reassess_roadmap tool failed: ${msg}`, { tool: "gsd_reassess_roadmap", error: String(err) });
1057
1060
  return {
1058
1061
  content: [{ type: "text" as const, text: `Error reassessing roadmap: ${msg}` }],
1059
1062
  details: { operation: "reassess_roadmap", error: msg } as any,
@@ -7,6 +7,7 @@ import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolve
7
7
  import { buildBeforeAgentStartResult } from "./system-context.js";
8
8
  import { handleAgentEnd } from "./agent-end-recovery.js";
9
9
  import { clearDiscussionFlowState, isDepthVerified, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite } from "./write-gate.js";
10
+ import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
10
11
  import { getDiscussionMilestoneId } from "../guided-flow.js";
11
12
  import { loadToolApiKeys } from "../commands-config.js";
12
13
  import { loadFile, saveFile, formatContinue } from "../files.js";
@@ -135,7 +136,28 @@ export function registerHooks(pi: ExtensionAPI): void {
135
136
  return { block: true, reason: loopCheck.reason };
136
137
  }
137
138
 
139
+ // ── Single-writer engine: block direct writes to STATE.md ──────────
140
+ // Covers write, edit, and bash tools to prevent bypass vectors.
141
+ if (isToolCallEventType("write", event)) {
142
+ if (isBlockedStateFile(event.input.path)) {
143
+ return { block: true, reason: BLOCKED_WRITE_ERROR };
144
+ }
145
+ }
146
+
147
+ if (isToolCallEventType("edit", event)) {
148
+ if (isBlockedStateFile(event.input.path)) {
149
+ return { block: true, reason: BLOCKED_WRITE_ERROR };
150
+ }
151
+ }
152
+
153
+ if (isToolCallEventType("bash", event)) {
154
+ if (isBashWriteToStateFile(event.input.command)) {
155
+ return { block: true, reason: BLOCKED_WRITE_ERROR };
156
+ }
157
+ }
158
+
138
159
  if (!isToolCallEventType("write", event)) return;
160
+
139
161
  const result = shouldBlockContextWrite(
140
162
  event.toolName,
141
163
  event.input.path,
@@ -47,15 +47,10 @@ export async function guardRemoteSession(
47
47
  return false;
48
48
  }
49
49
 
50
- const unitsMsg = remote.completedUnits != null
51
- ? `${remote.completedUnits} units completed`
52
- : "";
53
-
54
50
  const choice = await showNextAction(ctx, {
55
51
  title: `Auto-mode is running in another terminal (PID ${remote.pid})`,
56
52
  summary: [
57
53
  `Currently executing: ${unitLabel}`,
58
- ...(unitsMsg ? [unitsMsg] : []),
59
54
  ...(remote.startedAt ? [`Started: ${remote.startedAt}`] : []),
60
55
  ],
61
56
  actions: [
@@ -63,7 +63,7 @@ export async function handleParallelCommand(trimmed: string, _ctx: ExtensionComm
63
63
  }
64
64
  const lines = ["# Parallel Workers\n"];
65
65
  for (const worker of workers) {
66
- lines.push(`- **${worker.milestoneId}** (${worker.title}) — ${worker.state} — ${worker.completedUnits} units — $${worker.cost.toFixed(2)}`);
66
+ lines.push(`- **${worker.milestoneId}** (${worker.title}) — ${worker.state} — $${worker.cost.toFixed(2)}`);
67
67
  }
68
68
  const state = getOrchestratorState();
69
69
  if (state) {
@@ -23,7 +23,6 @@ export interface LockData {
23
23
  unitType: string;
24
24
  unitId: string;
25
25
  unitStartedAt: string;
26
- completedUnits: number;
27
26
  /** Path to the pi session JSONL file that was active when this unit started. */
28
27
  sessionFile?: string;
29
28
  }
@@ -37,7 +36,6 @@ export function writeLock(
37
36
  basePath: string,
38
37
  unitType: string,
39
38
  unitId: string,
40
- completedUnits: number,
41
39
  sessionFile?: string,
42
40
  ): void {
43
41
  try {
@@ -47,7 +45,6 @@ export function writeLock(
47
45
  unitType,
48
46
  unitId,
49
47
  unitStartedAt: new Date().toISOString(),
50
- completedUnits,
51
48
  sessionFile,
52
49
  };
53
50
  const lp = lockPath(basePath);
@@ -102,12 +99,11 @@ export function formatCrashInfo(lock: LockData): string {
102
99
  `Previous auto-mode session was interrupted.`,
103
100
  ` Was executing: ${lock.unitType} (${lock.unitId})`,
104
101
  ` Started at: ${lock.unitStartedAt}`,
105
- ` Units completed before crash: ${lock.completedUnits}`,
106
102
  ` PID: ${lock.pid}`,
107
103
  ];
108
104
 
109
105
  // Add recovery guidance based on what was happening when it crashed
110
- if (lock.unitType === "starting" && lock.unitId === "bootstrap" && lock.completedUnits === 0) {
106
+ if (lock.unitType === "starting" && lock.unitId === "bootstrap") {
111
107
  lines.push(`No work was lost. Run /gsd auto to restart.`);
112
108
  } else if (lock.unitType.includes("research") || lock.unitType.includes("plan")) {
113
109
  lines.push(`The ${lock.unitType} unit may be incomplete. Run /gsd auto to re-run it.`);
@@ -99,18 +99,11 @@ export class GSDDashboardOverlay {
99
99
  const currentUnit = dashData.currentUnit
100
100
  ? `${dashData.currentUnit.type}:${dashData.currentUnit.id}:${dashData.currentUnit.startedAt}`
101
101
  : "-";
102
- const lastCompleted = dashData.completedUnits.length > 0
103
- ? dashData.completedUnits[dashData.completedUnits.length - 1]
104
- : null;
105
- const completedKey = lastCompleted
106
- ? `${dashData.completedUnits.length}:${lastCompleted.type}:${lastCompleted.id}:${lastCompleted.finishedAt}`
107
- : "0";
108
102
  return [
109
103
  base,
110
104
  dashData.active ? "1" : "0",
111
105
  dashData.paused ? "1" : "0",
112
106
  currentUnit,
113
- completedKey,
114
107
  ].join("|");
115
108
  }
116
109
 
@@ -458,49 +451,6 @@ export class GSDDashboardOverlay {
458
451
  lines.push(centered(th.fg("dim", "No active milestone.")));
459
452
  }
460
453
 
461
- if (this.dashData.completedUnits.length > 0) {
462
- lines.push(blank());
463
- lines.push(hr());
464
- lines.push(row(th.fg("text", th.bold("Completed"))));
465
- lines.push(blank());
466
-
467
- // Build ledger lookup for budget indicators (last entry wins for retries)
468
- const ledgerLookup = new Map<string, UnitMetrics>();
469
- const currentLedger = getLedger();
470
- if (currentLedger) {
471
- for (const lu of currentLedger.units) {
472
- ledgerLookup.set(`${lu.type}:${lu.id}`, lu);
473
- }
474
- }
475
-
476
- const recent = [...this.dashData.completedUnits].reverse().slice(0, 10);
477
- for (const u of recent) {
478
- // Budget indicators from ledger — use warning glyph for pressured units
479
- const ledgerEntry = ledgerLookup.get(`${u.type}:${u.id}`);
480
- const hadPressure = ledgerEntry?.continueHereFired === true;
481
- const hadTruncation = (ledgerEntry?.truncationSections ?? 0) > 0;
482
- const unitGlyph = hadPressure
483
- ? th.fg(STATUS_COLOR.warning, STATUS_GLYPH.warning)
484
- : th.fg(STATUS_COLOR.done, STATUS_GLYPH.done);
485
- const left = ` ${unitGlyph} ${th.fg("muted", unitLabel(u.type))} ${th.fg("muted", u.id)}`;
486
-
487
- let budgetMarkers = "";
488
- if (hadTruncation) {
489
- budgetMarkers += th.fg("warning", ` ▼${ledgerEntry!.truncationSections}`);
490
- }
491
- if (hadPressure) {
492
- budgetMarkers += th.fg("error", " → wrap-up");
493
- }
494
-
495
- const right = th.fg("dim", formatDuration(u.finishedAt - u.startedAt));
496
- lines.push(row(joinColumns(`${left}${budgetMarkers}`, right, contentWidth)));
497
- }
498
-
499
- if (this.dashData.completedUnits.length > 10) {
500
- lines.push(row(th.fg("dim", ` ...and ${this.dashData.completedUnits.length - 10} more`)));
501
- }
502
- }
503
-
504
454
  const ledger = getLedger();
505
455
  if (ledger && ledger.units.length > 0) {
506
456
  const totals = getProjectTotals(ledger.units);
@@ -14,6 +14,7 @@ import type { Decision, Requirement } from './types.js';
14
14
  import { resolveGsdRootFile } from './paths.js';
15
15
  import { saveFile } from './files.js';
16
16
  import { GSDError, GSD_STALE_STATE, GSD_IO_ERROR } from './errors.js';
17
+ import { logWarning, logError } from './workflow-logger.js';
17
18
  import { invalidateStateCache } from './state.js';
18
19
  import { clearPathCache } from './paths.js';
19
20
  import { clearParseCache } from './files.js';
@@ -221,7 +222,7 @@ export async function nextDecisionId(): Promise<string> {
221
222
  const next = maxNum + 1;
222
223
  return `D${String(next).padStart(3, '0')}`;
223
224
  } catch (err) {
224
- process.stderr.write(`gsd-db: nextDecisionId failed: ${(err as Error).message}\n`);
225
+ logError('manifest', 'nextDecisionId failed', { fn: 'nextDecisionId', error: String((err as Error).message) });
225
226
  return 'D001';
226
227
  }
227
228
  }
@@ -311,9 +312,7 @@ export async function saveDecisionToDb(
311
312
  try {
312
313
  await saveFile(filePath, md);
313
314
  } catch (diskErr) {
314
- process.stderr.write(
315
- `gsd-db: saveDecisionToDb — disk write failed, rolling back DB row: ${(diskErr as Error).message}\n`,
316
- );
315
+ logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveDecisionToDb', error: String((diskErr as Error).message) });
317
316
  adapter?.prepare('DELETE FROM decisions WHERE id = :id').run({ ':id': id });
318
317
  throw diskErr;
319
318
  }
@@ -325,7 +324,7 @@ export async function saveDecisionToDb(
325
324
 
326
325
  return { id };
327
326
  } catch (err) {
328
- process.stderr.write(`gsd-db: saveDecisionToDb failed: ${(err as Error).message}\n`);
327
+ logError('manifest', 'saveDecisionToDb failed', { fn: 'saveDecisionToDb', error: String((err as Error).message) });
329
328
  throw err;
330
329
  }
331
330
  }
@@ -388,9 +387,7 @@ export async function updateRequirementInDb(
388
387
  try {
389
388
  await saveFile(filePath, md);
390
389
  } catch (diskErr) {
391
- process.stderr.write(
392
- `gsd-db: updateRequirementInDb — disk write failed, reverting DB row: ${(diskErr as Error).message}\n`,
393
- );
390
+ logError('manifest', 'disk write failed, reverting DB row', { fn: 'updateRequirementInDb', error: String((diskErr as Error).message) });
394
391
  db.upsertRequirement(existing);
395
392
  throw diskErr;
396
393
  }
@@ -400,7 +397,7 @@ export async function updateRequirementInDb(
400
397
  clearPathCache();
401
398
  clearParseCache();
402
399
  } catch (err) {
403
- process.stderr.write(`gsd-db: updateRequirementInDb failed: ${(err as Error).message}\n`);
400
+ logError('manifest', 'updateRequirementInDb failed', { fn: 'updateRequirementInDb', error: String((err as Error).message) });
404
401
  throw err;
405
402
  }
406
403
  }
@@ -444,10 +441,7 @@ export async function saveArtifactToDb(
444
441
  const existingSize = statSync(fullPath).size;
445
442
  const newSize = Buffer.byteLength(opts.content, 'utf-8');
446
443
  if (existingSize > 0 && newSize < existingSize * 0.5) {
447
- process.stderr.write(
448
- `gsd-db: saveArtifactToDb — new content (${newSize}B) is <50% of existing file ` +
449
- `(${existingSize}B) at ${opts.path}. Preserving disk file to prevent data loss.\n`,
450
- );
444
+ logWarning('manifest', `new content (${newSize}B) is <50% of existing file (${existingSize}B), preserving disk file`, { fn: 'saveArtifactToDb', path: opts.path });
451
445
  dbContent = readFileSync(fullPath, 'utf-8');
452
446
  skipDiskWrite = true;
453
447
  }
@@ -467,9 +461,7 @@ export async function saveArtifactToDb(
467
461
  try {
468
462
  await saveFile(fullPath, opts.content);
469
463
  } catch (diskErr) {
470
- process.stderr.write(
471
- `gsd-db: saveArtifactToDb — disk write failed, rolling back DB row: ${(diskErr as Error).message}\n`,
472
- );
464
+ logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveArtifactToDb', error: String((diskErr as Error).message) });
473
465
  const rollbackAdapter = db._getAdapter();
474
466
  rollbackAdapter?.prepare('DELETE FROM artifacts WHERE path = :path').run({ ':path': opts.path });
475
467
  throw diskErr;
@@ -481,7 +473,7 @@ export async function saveArtifactToDb(
481
473
  clearPathCache();
482
474
  clearParseCache();
483
475
  } catch (err) {
484
- process.stderr.write(`gsd-db: saveArtifactToDb failed: ${(err as Error).message}\n`);
476
+ logError('manifest', 'saveArtifactToDb failed', { fn: 'saveArtifactToDb', error: String((err as Error).message) });
485
477
  throw err;
486
478
  }
487
479
  }