gsd-pi 2.82.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (555) hide show
  1. package/README.md +51 -32
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +10 -1
  4. package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
  5. package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
  6. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  7. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +1 -1
  8. package/dist/resources/extensions/cmux/index.js +5 -0
  9. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  10. package/dist/resources/extensions/gsd/auto/loop.js +19 -6
  11. package/dist/resources/extensions/gsd/auto/orchestrator.js +124 -6
  12. package/dist/resources/extensions/gsd/auto/phases.js +90 -31
  13. package/dist/resources/extensions/gsd/auto/session.js +4 -0
  14. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  15. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  16. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  17. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  18. package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
  19. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  20. package/dist/resources/extensions/gsd/auto-post-unit.js +246 -133
  21. package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
  22. package/dist/resources/extensions/gsd/auto-recovery.js +71 -14
  23. package/dist/resources/extensions/gsd/auto-start.js +87 -14
  24. package/dist/resources/extensions/gsd/auto-verification.js +45 -26
  25. package/dist/resources/extensions/gsd/auto-worktree.js +176 -10
  26. package/dist/resources/extensions/gsd/auto.js +178 -63
  27. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
  28. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
  29. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +9 -2
  30. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  31. package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
  32. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +17 -3
  33. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  34. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  35. package/dist/resources/extensions/gsd/commands/handlers/core.js +39 -1
  36. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  37. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  38. package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
  39. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
  40. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  41. package/dist/resources/extensions/gsd/context-store.js +112 -0
  42. package/dist/resources/extensions/gsd/crash-recovery.js +43 -5
  43. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  44. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  45. package/dist/resources/extensions/gsd/db-writer.js +150 -84
  46. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  47. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  48. package/dist/resources/extensions/gsd/doctor-git-checks.js +87 -7
  49. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  50. package/dist/resources/extensions/gsd/doctor.js +2 -28
  51. package/dist/resources/extensions/gsd/export-html.js +27 -425
  52. package/dist/resources/extensions/gsd/forensics.js +3 -3
  53. package/dist/resources/extensions/gsd/git-service.js +45 -3
  54. package/dist/resources/extensions/gsd/gsd-db.js +21 -6
  55. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  56. package/dist/resources/extensions/gsd/guided-flow.js +101 -116
  57. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  58. package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
  59. package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
  60. package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
  61. package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
  62. package/dist/resources/extensions/gsd/markdown-renderer.js +16 -9
  63. package/dist/resources/extensions/gsd/md-importer.js +1 -1
  64. package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
  65. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
  66. package/dist/resources/extensions/gsd/migrate/command.js +5 -0
  67. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  68. package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
  69. package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
  70. package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
  71. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  72. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  73. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  74. package/dist/resources/extensions/gsd/paths.js +4 -0
  75. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  76. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
  77. package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
  78. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  79. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  80. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  82. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  83. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  84. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  85. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  86. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  87. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  88. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  89. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  90. package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
  91. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  92. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  93. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  94. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  95. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  96. package/dist/resources/extensions/gsd/state.js +3 -3
  97. package/dist/resources/extensions/gsd/status-guards.js +11 -0
  98. package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
  99. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  100. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  101. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  102. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  103. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  104. package/dist/resources/extensions/gsd/tools/plan-slice.js +87 -14
  105. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  106. package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
  107. package/dist/resources/extensions/gsd/validation.js +23 -1
  108. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  109. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  110. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  111. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  112. package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
  113. package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
  114. package/dist/resources/extensions/shared/html-shell.js +388 -0
  115. package/dist/resources/extensions/subagent/index.js +448 -78
  116. package/dist/resources/extensions/subagent/launch.js +77 -0
  117. package/dist/resources/extensions/subagent/run-store.js +148 -0
  118. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  119. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  120. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  121. package/dist/resources/extensions/visual-brief/index.js +5 -0
  122. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  123. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  124. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  125. package/dist/web/standalone/.next/BUILD_ID +1 -1
  126. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  127. package/dist/web/standalone/.next/build-manifest.json +3 -3
  128. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  129. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  130. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  140. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  147. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  150. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/index.html +1 -1
  153. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  154. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  155. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  156. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  158. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  159. package/dist/web/standalone/.next/server/app/page.js +2 -2
  160. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  163. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  164. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  168. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  169. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  170. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  171. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  172. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  173. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  174. package/dist/web/standalone/.next/static/chunks/app/layout-b23b3f6858dc6dc8.js +1 -0
  175. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  176. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  177. package/package.json +6 -5
  178. package/packages/contracts/dist/rpc.test.js +7 -0
  179. package/packages/contracts/dist/rpc.test.js.map +1 -1
  180. package/packages/contracts/dist/workflow.d.ts +21 -0
  181. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  182. package/packages/contracts/dist/workflow.js +24 -0
  183. package/packages/contracts/dist/workflow.js.map +1 -1
  184. package/packages/contracts/src/rpc.test.ts +8 -0
  185. package/packages/contracts/src/workflow.ts +24 -0
  186. package/packages/daemon/package.json +2 -2
  187. package/packages/mcp-server/README.md +14 -3
  188. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  189. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  190. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  191. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  192. package/packages/mcp-server/package.json +2 -2
  193. package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
  194. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  195. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  196. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  197. package/packages/native/package.json +1 -1
  198. package/packages/native/tsconfig.json +2 -1
  199. package/packages/native/tsconfig.tsbuildinfo +1 -1
  200. package/packages/pi-agent-core/package.json +1 -1
  201. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  202. package/packages/pi-ai/dist/index.d.ts +2 -2
  203. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  204. package/packages/pi-ai/dist/index.js +1 -1
  205. package/packages/pi-ai/dist/index.js.map +1 -1
  206. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  207. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  208. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  209. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  210. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  211. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  212. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  213. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  214. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  215. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  216. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  217. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  218. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  219. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  220. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  221. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  222. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  223. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  224. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  225. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  226. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  227. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  228. package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
  229. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  230. package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
  231. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  232. package/packages/pi-ai/package.json +1 -1
  233. package/packages/pi-ai/src/index.ts +7 -2
  234. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  235. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  236. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  237. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  238. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  239. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  240. package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
  241. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  242. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  243. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  244. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  245. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  246. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  247. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  249. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  251. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  252. package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
  253. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  256. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
  259. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  261. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  263. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  265. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
  267. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
  268. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
  269. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
  270. package/packages/pi-coding-agent/package.json +1 -1
  271. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  272. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  273. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  274. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  275. package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
  276. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  277. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
  278. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  279. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  280. package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
  281. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  282. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  283. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  284. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  285. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  286. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  287. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  288. package/packages/pi-tui/dist/terminal.js +12 -0
  289. package/packages/pi-tui/dist/terminal.js.map +1 -1
  290. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  291. package/packages/pi-tui/dist/tui.js +5 -0
  292. package/packages/pi-tui/dist/tui.js.map +1 -1
  293. package/packages/pi-tui/package.json +1 -1
  294. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  295. package/packages/pi-tui/src/terminal.ts +11 -0
  296. package/packages/pi-tui/src/tui.ts +6 -0
  297. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  298. package/packages/rpc-client/package.json +1 -1
  299. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  300. package/pkg/package.json +1 -1
  301. package/src/resources/GSD-WORKFLOW.md +10 -1
  302. package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
  303. package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
  304. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  305. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +1 -1
  306. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  307. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +9 -0
  308. package/src/resources/extensions/cmux/index.ts +6 -0
  309. package/src/resources/extensions/gsd/auto/contracts.ts +59 -16
  310. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  311. package/src/resources/extensions/gsd/auto/loop.ts +22 -6
  312. package/src/resources/extensions/gsd/auto/orchestrator.ts +129 -6
  313. package/src/resources/extensions/gsd/auto/phases.ts +104 -38
  314. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  315. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  316. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  317. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  318. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  319. package/src/resources/extensions/gsd/auto-dispatch.ts +21 -19
  320. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  321. package/src/resources/extensions/gsd/auto-post-unit.ts +279 -144
  322. package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
  323. package/src/resources/extensions/gsd/auto-recovery.ts +74 -11
  324. package/src/resources/extensions/gsd/auto-start.ts +94 -12
  325. package/src/resources/extensions/gsd/auto-verification.ts +58 -36
  326. package/src/resources/extensions/gsd/auto-worktree.ts +193 -10
  327. package/src/resources/extensions/gsd/auto.ts +187 -61
  328. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
  329. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
  330. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -2
  331. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  332. package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
  333. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +20 -4
  334. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  335. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  336. package/src/resources/extensions/gsd/commands/handlers/core.ts +42 -1
  337. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  338. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  339. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  340. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
  341. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  342. package/src/resources/extensions/gsd/context-store.ts +120 -1
  343. package/src/resources/extensions/gsd/crash-recovery.ts +44 -4
  344. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  345. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  346. package/src/resources/extensions/gsd/db-writer.ts +167 -84
  347. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
  348. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  349. package/src/resources/extensions/gsd/doctor-git-checks.ts +89 -7
  350. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  351. package/src/resources/extensions/gsd/doctor-types.ts +3 -0
  352. package/src/resources/extensions/gsd/doctor.ts +2 -27
  353. package/src/resources/extensions/gsd/export-html.ts +27 -427
  354. package/src/resources/extensions/gsd/forensics.ts +3 -3
  355. package/src/resources/extensions/gsd/git-service.ts +51 -4
  356. package/src/resources/extensions/gsd/gsd-db.ts +21 -6
  357. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  358. package/src/resources/extensions/gsd/guided-flow.ts +134 -133
  359. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  360. package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
  361. package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
  362. package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
  363. package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
  364. package/src/resources/extensions/gsd/markdown-renderer.ts +16 -9
  365. package/src/resources/extensions/gsd/md-importer.ts +1 -1
  366. package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
  367. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
  368. package/src/resources/extensions/gsd/migrate/command.ts +5 -0
  369. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  370. package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
  371. package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
  372. package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
  373. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  374. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  375. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  376. package/src/resources/extensions/gsd/paths.ts +5 -0
  377. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  378. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  379. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  380. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  381. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  382. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  383. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  384. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  385. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  386. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  387. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  388. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  389. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  390. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  391. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  392. package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
  393. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  394. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  395. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  396. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  397. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  398. package/src/resources/extensions/gsd/state.ts +3 -3
  399. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  400. package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
  401. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  402. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  403. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  404. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  405. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -0
  406. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +487 -4
  407. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  408. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  409. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  410. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +91 -6
  411. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
  412. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  413. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  414. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  415. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  416. package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
  417. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  418. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  419. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
  420. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  421. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  422. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  423. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  424. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  425. package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
  426. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +86 -2
  427. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  428. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  429. package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
  430. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
  431. package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
  432. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  433. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
  434. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  435. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  436. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
  437. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  438. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
  439. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +11 -0
  440. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
  441. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  442. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  443. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  444. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  445. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  446. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  447. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  448. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  449. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  450. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  451. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
  452. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  453. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +112 -1
  454. package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
  455. package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
  456. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  457. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +46 -0
  458. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
  459. package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
  460. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
  461. package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
  462. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
  463. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  464. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
  465. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  466. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
  467. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  468. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
  469. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  470. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  471. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  472. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  473. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
  474. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  475. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  476. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +251 -2
  477. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  478. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  479. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
  480. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  481. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  482. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
  483. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +59 -0
  484. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
  485. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  486. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  487. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
  488. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  489. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  490. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  491. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  492. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
  493. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
  494. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  495. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
  496. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  497. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  498. package/src/resources/extensions/gsd/tests/status-guards.test.ts +13 -1
  499. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  500. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  501. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +103 -7
  502. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  503. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  504. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  505. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  506. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  507. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  508. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  509. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  510. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  511. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
  512. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
  513. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  514. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  515. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  516. package/src/resources/extensions/gsd/tools/plan-slice.ts +97 -12
  517. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  518. package/src/resources/extensions/gsd/types.ts +1 -1
  519. package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
  520. package/src/resources/extensions/gsd/validation.ts +23 -1
  521. package/src/resources/extensions/gsd/verification-gate.ts +78 -6
  522. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  523. package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
  524. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  525. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  526. package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
  527. package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
  528. package/src/resources/extensions/shared/html-shell.ts +412 -0
  529. package/src/resources/extensions/subagent/index.ts +567 -103
  530. package/src/resources/extensions/subagent/launch.ts +131 -0
  531. package/src/resources/extensions/subagent/run-store.ts +218 -0
  532. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  533. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  534. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  535. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  536. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  537. package/src/resources/extensions/visual-brief/index.ts +8 -0
  538. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  539. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  540. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  541. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  542. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  543. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  544. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  545. package/dist/web/standalone/.next/static/chunks/app/layout-9ecfd95f343793f0.js +0 -1
  546. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  547. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  548. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  549. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  550. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  551. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  552. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  553. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  554. /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_buildManifest.js +0 -0
  555. /package/dist/web/standalone/.next/static/{S44UQTFCUdA44dkjfYt6S → qoMxZh-xuwuvpFW0x0k01}/_ssgManifest.js +0 -0
@@ -5,7 +5,7 @@
5
5
  // All functions degrade gracefully: return empty results when DB unavailable, never throw.
6
6
 
7
7
  import { isDbAvailable, _getAdapter } from './gsd-db.js';
8
- import type { Decision, Requirement } from './types.js';
8
+ import type { Decision, DecisionMadeBy, Requirement } from './types.js';
9
9
 
10
10
  // ─── Query Functions ───────────────────────────────────────────────────────
11
11
 
@@ -66,6 +66,125 @@ export function queryDecisions(opts?: DecisionQueryOpts): Decision[] {
66
66
  }
67
67
  }
68
68
 
69
+ /**
70
+ * Internal: shared core for the two memory-sourced decision queries. Reads
71
+ * memory rows tagged with `sourceDecisionId` and reconstructs `Decision[]`
72
+ * from their `structured_fields` JSON.
73
+ *
74
+ * @param includeSuperseded — when false, drops rows whose
75
+ * `structured_fields.superseded_by` is non-null. The supersedes-chain is
76
+ * captured by the backfill (`memory-backfill.ts`) and kept in sync by
77
+ * the backfill's drift auto-heal pass.
78
+ */
79
+ function readDecisionsFromMemories(
80
+ opts: DecisionQueryOpts | undefined,
81
+ includeSuperseded: boolean,
82
+ ): Decision[] {
83
+ if (!isDbAvailable()) return [];
84
+ const adapter = _getAdapter();
85
+ if (!adapter) return [];
86
+
87
+ try {
88
+ const clauses: string[] = [
89
+ "category = 'architecture'",
90
+ "structured_fields LIKE '%\"sourceDecisionId\":\"%'",
91
+ ];
92
+ const params: Record<string, unknown> = {};
93
+
94
+ if (opts?.milestoneId) {
95
+ // when_context is a free-text JSON value; substring match preserves the
96
+ // semantics of `when_context LIKE '%milestoneId%'` on the legacy table.
97
+ clauses.push("json_extract(structured_fields, '$.when_context') LIKE :milestone_pattern");
98
+ params[':milestone_pattern'] = `%${opts.milestoneId}%`;
99
+ }
100
+
101
+ if (opts?.scope) {
102
+ // Stage 1 used `json_extract` in main (post-merge); preserve that
103
+ // style here. Exact equality on the JSON value avoids the prefix
104
+ // collision risk LIKE patterns had (scope=M001 vs scope=M001-S01).
105
+ clauses.push("json_extract(structured_fields, '$.scope') = :scope");
106
+ params[':scope'] = opts.scope;
107
+ }
108
+
109
+ const sql = `SELECT seq, structured_fields FROM memories WHERE ${clauses.join(' AND ')} ORDER BY seq`;
110
+ const rows = adapter.prepare(sql).all(params) as Array<Record<string, unknown>>;
111
+
112
+ const decisions: Decision[] = [];
113
+ for (const row of rows) {
114
+ const seq = row['seq'] as number;
115
+ const sfRaw = row['structured_fields'] as string | null;
116
+ if (!sfRaw) continue;
117
+ let sf: Record<string, unknown>;
118
+ try {
119
+ sf = JSON.parse(sfRaw) as Record<string, unknown>;
120
+ } catch {
121
+ continue;
122
+ }
123
+ const sourceId = sf['sourceDecisionId'];
124
+ if (typeof sourceId !== 'string' || sourceId.length === 0) continue;
125
+
126
+ // Decision-level superseded status lives in structured_fields.superseded_by
127
+ // (written by mirrorDecisionToMemory / memory-backfill.ts). The top-level
128
+ // memories.superseded_by column is intentionally never set for decision mirrors,
129
+ // so active-only filtering must be done here in the JS loop.
130
+ const supersededBy = typeof sf['superseded_by'] === 'string' ? (sf['superseded_by'] as string) : null;
131
+ if (!includeSuperseded && supersededBy) continue;
132
+
133
+ decisions.push({
134
+ seq,
135
+ id: sourceId,
136
+ when_context: typeof sf['when_context'] === 'string' ? (sf['when_context'] as string) : '',
137
+ scope: typeof sf['scope'] === 'string' ? (sf['scope'] as string) : '',
138
+ decision: typeof sf['decision'] === 'string' ? (sf['decision'] as string) : '',
139
+ choice: typeof sf['choice'] === 'string' ? (sf['choice'] as string) : '',
140
+ rationale: typeof sf['rationale'] === 'string' ? (sf['rationale'] as string) : '',
141
+ revisable: typeof sf['revisable'] === 'string' ? (sf['revisable'] as string) : '',
142
+ made_by: ((typeof sf['made_by'] === 'string' ? sf['made_by'] : 'agent') as DecisionMadeBy),
143
+ superseded_by: supersededBy,
144
+ });
145
+ }
146
+
147
+ return decisions;
148
+ } catch {
149
+ return [];
150
+ }
151
+ }
152
+
153
+ /**
154
+ * ADR-013 Phase 6 cutover (Stage 1): read **active** decisions from the
155
+ * `memories` table instead of the legacy `decisions` table. Returns the
156
+ * same `Decision[]` shape as `queryDecisions` so downstream formatters
157
+ * work unchanged.
158
+ *
159
+ * Filter semantics match `queryDecisions` exactly:
160
+ * - active only (skips rows where `structured_fields.superseded_by` is set)
161
+ * - `milestoneId`: substring match on `structured_fields.when_context`
162
+ * - `scope`: exact match on `structured_fields.scope`
163
+ *
164
+ * Used by the prompt-inline path (`inlineDecisionsFromDb` in
165
+ * `auto-prompts.ts`). For the projection regen (which renders superseded
166
+ * rows too), see `getAllDecisionsFromMemories`.
167
+ */
168
+ export function queryDecisionsFromMemories(opts?: DecisionQueryOpts): Decision[] {
169
+ return readDecisionsFromMemories(opts, /* includeSuperseded */ false);
170
+ }
171
+
172
+ /**
173
+ * ADR-013 Phase 6 cutover (Stage 2a): read **all** decisions (active +
174
+ * superseded) from the `memories` table. Used by the DECISIONS.md
175
+ * projection regen in `saveDecisionToDb`, which must render the full
176
+ * supersedes-chain for the canonical register format.
177
+ *
178
+ * Equivalent to `SELECT * FROM decisions ORDER BY seq` over the legacy
179
+ * table — but sourced from memories so the legacy table can be retired
180
+ * in Stage 3. Includes `superseded_by` reconstructed from
181
+ * `structured_fields.superseded_by` (populated by the backfill's drift
182
+ * auto-heal pass).
183
+ */
184
+ export function getAllDecisionsFromMemories(): Decision[] {
185
+ return readDecisionsFromMemories(undefined, /* includeSuperseded */ true);
186
+ }
187
+
69
188
  /**
70
189
  * Query active (non-superseded) requirements with optional filters.
71
190
  * - milestoneId: combined with sliceId for precise filtering (e.g. %M005/S01%)
@@ -30,9 +30,12 @@ import { join } from "node:path";
30
30
  import {
31
31
  findStaleWorkerForProject,
32
32
  getAllAutoWorkers,
33
+ markWorkerCrashed,
34
+ markWorkerStopping,
33
35
  type AutoWorkerRow,
34
36
  } from "./db/auto-workers.js";
35
- import { getLatestForUnit, type DispatchStatus } from "./db/unit-dispatches.js";
37
+ import { forceReleaseLeasesForWorker } from "./db/milestone-leases.js";
38
+ import { markLatestActiveForWorkerCanceled, type DispatchStatus } from "./db/unit-dispatches.js";
36
39
  import { getRuntimeKv, setRuntimeKv, deleteRuntimeKv } from "./db/runtime-kv.js";
37
40
  import { _getAdapter, isDbAvailable } from "./gsd-db.js";
38
41
  import { gsdRoot, normalizeRealPath } from "./paths.js";
@@ -56,6 +59,15 @@ function lockPath(basePath: string): string {
56
59
  return join(gsdRoot(basePath), effectiveLockFile());
57
60
  }
58
61
 
62
+ function clearLegacyLockFile(basePath: string): void {
63
+ try {
64
+ const p = lockPath(basePath);
65
+ if (existsSync(p)) unlinkSync(p);
66
+ } catch {
67
+ // Best-effort.
68
+ }
69
+ }
70
+
59
71
  function readLegacyLock(basePath: string): LockData | null {
60
72
  try {
61
73
  const p = lockPath(basePath);
@@ -204,18 +216,46 @@ export function writeLock(
204
216
  * stale session-file pointer.
205
217
  */
206
218
  export function clearLock(basePath: string): void {
219
+ clearLegacyLockFile(basePath);
220
+
221
+ if (!isDbAvailable()) return;
207
222
  try {
208
- const p = lockPath(basePath);
209
- if (existsSync(p)) unlinkSync(p);
223
+ const projectRoot = normalizeRealPath(basePath);
224
+ const staleWorker = findStaleWorkerForProject(projectRoot);
225
+ if (staleWorker) {
226
+ markWorkerCrashed(staleWorker.worker_id);
227
+ forceReleaseLeasesForWorker(staleWorker.worker_id);
228
+ deleteRuntimeKv("worker", staleWorker.worker_id, SESSION_FILE_KV_KEY);
229
+ return;
230
+ }
231
+ const worker = findActiveWorkerForCurrentProcess(projectRoot);
232
+ if (worker) deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
233
+
234
+ const stale = findStaleWorkerForProject(projectRoot);
235
+ if (stale) {
236
+ markWorkerStopping(stale.worker_id);
237
+ deleteRuntimeKv("worker", stale.worker_id, SESSION_FILE_KV_KEY);
238
+ }
210
239
  } catch {
211
240
  // Best-effort.
212
241
  }
242
+ }
243
+
244
+ /**
245
+ * Clear a stale DB-backed worker lock after readCrashLock/findStaleWorkerForProject
246
+ * has identified a dead worker. Unlike clearLock(), this targets the stale
247
+ * worker row instead of the current process's active worker.
248
+ */
249
+ export function clearStaleWorkerLock(basePath: string): void {
250
+ clearLegacyLockFile(basePath);
213
251
 
214
252
  if (!isDbAvailable()) return;
215
253
  try {
216
254
  const projectRoot = normalizeRealPath(basePath);
217
- const worker = findActiveWorkerForCurrentProcess(projectRoot);
255
+ const worker = findStaleWorkerForProject(projectRoot);
218
256
  if (!worker) return;
257
+ markLatestActiveForWorkerCanceled(worker.worker_id, "crash-recovered");
258
+ markWorkerCrashed(worker.worker_id);
219
259
  deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
220
260
  } catch {
221
261
  // Best-effort.
@@ -255,6 +255,32 @@ export function releaseMilestoneLease(
255
255
  });
256
256
  }
257
257
 
258
+ /**
259
+ * Force-release all held leases for a worker.
260
+ *
261
+ * Used by crash recovery once PID liveness has confirmed the worker is dead.
262
+ * No fencing token is required because this path is cleanup-only for a
263
+ * non-running process.
264
+ */
265
+ export function forceReleaseLeasesForWorker(workerId: string): number {
266
+ if (!isDbAvailable()) return 0;
267
+ const db = _getAdapter()!;
268
+ let changes = 0;
269
+ transaction(() => {
270
+ const result = db.prepare(
271
+ `UPDATE milestone_leases
272
+ SET status = 'released'
273
+ WHERE worker_id = :worker_id
274
+ AND status = 'held'`,
275
+ ).run({ ":worker_id": workerId });
276
+ changes =
277
+ typeof (result as { changes?: unknown }).changes === "number"
278
+ ? (result as { changes: number }).changes
279
+ : 0;
280
+ });
281
+ return changes;
282
+ }
283
+
258
284
  /**
259
285
  * Read current lease row for diagnostics. Returns null if no row exists.
260
286
  */
@@ -524,17 +524,18 @@ export function getRecentUnitKeysForProjectRoot(
524
524
  if (!isDbAvailable()) return [];
525
525
  const db = _getAdapter()!;
526
526
  const rows = db.prepare(
527
- `SELECT ud.unit_id
527
+ `SELECT ud.unit_type, ud.unit_id
528
528
  FROM unit_dispatches ud
529
529
  INNER JOIN workers w ON w.worker_id = ud.worker_id
530
530
  WHERE w.project_root_realpath = :project_root_realpath
531
+ AND w.status != 'crashed'
531
532
  ORDER BY ud.started_at DESC, ud.id DESC
532
533
  LIMIT :limit`,
533
534
  ).all({
534
535
  ":project_root_realpath": projectRootRealpath,
535
536
  ":limit": limit,
536
- }) as Array<{ unit_id: string }>;
537
- return rows.reverse().map((r) => ({ key: r.unit_id }));
537
+ }) as Array<{ unit_type: string; unit_id: string }>;
538
+ return rows.reverse().map((r) => ({ key: `${r.unit_type}/${r.unit_id}` }));
538
539
  }
539
540
 
540
541
  /**
@@ -235,14 +235,63 @@ export async function nextDecisionId(): Promise<string> {
235
235
  }
236
236
  }
237
237
 
238
- /** Synchronous variant for use inside db.transaction(). */
239
- function nextDecisionIdSync(adapter: ReturnType<typeof import('./gsd-db.js')._getAdapter>): string {
238
+ /**
239
+ * ADR-013 Stage 3: compute the next `D###` identifier across both the legacy
240
+ * `decisions` table AND the `memories.structured_fields.sourceDecisionId`
241
+ * surface. Returns the max numeric suffix from either side + 1, three-digit
242
+ * padded.
243
+ *
244
+ * Used by `saveDecisionToDb` once writes to the `decisions` table stop —
245
+ * new decisions live only in memories, but historical IDs sit in both
246
+ * places during the cutover bake. The cross-surface max keeps IDs
247
+ * monotonic and avoids collisions on the next save.
248
+ */
249
+ function nextDecisionIdAcrossSurfaces(
250
+ adapter: ReturnType<typeof import('./gsd-db.js')._getAdapter>,
251
+ ): string {
240
252
  if (!adapter) return 'D001';
241
- const row = adapter
242
- .prepare('SELECT MAX(CAST(SUBSTR(id, 2) AS INTEGER)) as max_num FROM decisions')
243
- .get();
244
- const maxNum = row ? (row['max_num'] as number | null) : null;
245
- if (maxNum == null || isNaN(maxNum)) return 'D001';
253
+
254
+ let maxNum = 0;
255
+
256
+ // Legacy table best-effort.
257
+ try {
258
+ const row = adapter
259
+ .prepare('SELECT MAX(CAST(SUBSTR(id, 2) AS INTEGER)) as max_num FROM decisions')
260
+ .get();
261
+ const candidate = row ? (row['max_num'] as number | null) : null;
262
+ if (typeof candidate === 'number' && Number.isFinite(candidate)) {
263
+ maxNum = Math.max(maxNum, candidate);
264
+ }
265
+ } catch {
266
+ // fall through to memory-only
267
+ }
268
+
269
+ // Memory surface: scan structuredFields.sourceDecisionId for D### values.
270
+ // SQLite LIKE on the JSON-stringified field is sufficient — rows tagged
271
+ // with sourceDecisionId are bounded by the decisions count.
272
+ try {
273
+ const rows = adapter
274
+ .prepare(
275
+ "SELECT structured_fields FROM memories WHERE structured_fields LIKE '%\"sourceDecisionId\":\"D%'",
276
+ )
277
+ .all() as Array<{ structured_fields: string | null }>;
278
+ for (const row of rows) {
279
+ if (!row.structured_fields) continue;
280
+ let sf: Record<string, unknown>;
281
+ try {
282
+ sf = JSON.parse(row.structured_fields) as Record<string, unknown>;
283
+ } catch {
284
+ continue;
285
+ }
286
+ const sourceId = sf['sourceDecisionId'];
287
+ if (typeof sourceId !== 'string' || !sourceId.startsWith('D')) continue;
288
+ const num = parseInt(sourceId.slice(1), 10);
289
+ if (Number.isFinite(num) && num > maxNum) maxNum = num;
290
+ }
291
+ } catch {
292
+ // best-effort
293
+ }
294
+
246
295
  const next = maxNum + 1;
247
296
  return `D${String(next).padStart(3, '0')}`;
248
297
  }
@@ -416,6 +465,16 @@ export interface SaveDecisionFields {
416
465
  source?: string;
417
466
  }
418
467
 
468
+ type NormalizedSaveDecisionFields = Omit<
469
+ SaveDecisionFields,
470
+ 'when_context' | 'revisable' | 'made_by' | 'source'
471
+ > & {
472
+ when_context: string;
473
+ revisable: string;
474
+ made_by: NonNullable<SaveDecisionFields['made_by']>;
475
+ source: string;
476
+ };
477
+
419
478
  /**
420
479
  * Save a new decision to DB and regenerate DECISIONS.md.
421
480
  * Auto-assigns the next ID via nextDecisionId().
@@ -445,44 +504,59 @@ export async function saveDecisionToDb(
445
504
 
446
505
  try {
447
506
  const db = await import('./gsd-db.js');
448
-
449
507
  const adapter = db._getAdapter();
508
+ const normalized: NormalizedSaveDecisionFields = {
509
+ ...fields,
510
+ when_context: fields.when_context ?? '',
511
+ revisable: fields.revisable ?? 'Yes',
512
+ made_by: fields.made_by ?? 'agent',
513
+ source: fields.source ?? 'discussion',
514
+ };
450
515
 
451
- const id = db.transaction(() => {
452
- const nextId = nextDecisionIdSync(adapter);
453
- db.upsertDecision({
454
- id: nextId,
455
- when_context: fields.when_context ?? '',
456
- scope: fields.scope,
457
- decision: fields.decision,
458
- choice: fields.choice,
459
- rationale: fields.rationale,
460
- revisable: fields.revisable ?? 'Yes',
461
- made_by: fields.made_by ?? 'agent',
462
- source: fields.source ?? 'discussion',
463
- superseded_by: null,
516
+ // ADR-013 Stage 3 (destructive): writes to the `decisions` table stop
517
+ // here. New decisions live only in the `memories` table; the projection
518
+ // regen below sources from memories (Stage 2a). The decisions table
519
+ // remains for backwards-compat reads (queryDecisions, md-importer,
520
+ // commands-inspect, workflow-manifest) until #5756 drops it.
521
+ //
522
+ // Reversal: a code revert of this change restores the upsertDecision
523
+ // call. Memory rows written between merge and revert stay durable; the
524
+ // legacy table simply doesn't grow during the cutover window.
525
+ const id = nextDecisionIdAcrossSurfaces(adapter);
526
+
527
+ // The mirror-to-memories write is what persists the new decision. Must
528
+ // run before the projection regen — the regen sources from memories
529
+ // (Stage 2a) and would otherwise miss the just-saved decision. Pass
530
+ // the normalized field set so defaults (revisable, made_by, source)
531
+ // are recorded on the memory row.
532
+ await mirrorDecisionToMemory(id, normalized);
533
+
534
+ // Fetch all decisions (including superseded for the full register).
535
+ // ADR-013 Stage 2a: source from the `memories` table. The Phase 5
536
+ // dual-write keeps memories in sync with each decision save; the backfill
537
+ // (memory-backfill.ts) absorbs the historical chain and drift-heals
538
+ // superseded_by on every session start.
539
+ const { getAllDecisionsFromMemories } = await import('./context-store.js');
540
+ let allDecisions: Decision[] = getAllDecisionsFromMemories();
541
+ if (!allDecisions.some(d => d.id === id)) {
542
+ logWarning('projection', 'just-saved decision missing from memories after mirror; injecting fallback for projection', {
543
+ fn: 'saveDecisionToDb',
544
+ decisionId: id,
464
545
  });
465
-
466
-
467
- return nextId;
468
- });
469
-
470
- // Fetch all decisions (including superseded for the full register)
471
- let allDecisions: Decision[] = [];
472
- if (adapter) {
473
- const rows = adapter.prepare('SELECT * FROM decisions ORDER BY seq').all();
474
- allDecisions = rows.map(row => ({
475
- seq: row['seq'] as number,
476
- id: row['id'] as string,
477
- when_context: row['when_context'] as string,
478
- scope: row['scope'] as string,
479
- decision: row['decision'] as string,
480
- choice: row['choice'] as string,
481
- rationale: row['rationale'] as string,
482
- revisable: row['revisable'] as string,
483
- made_by: (row['made_by'] as string as import('./types.js').DecisionMadeBy) ?? 'agent',
484
- superseded_by: (row['superseded_by'] as string) ?? null,
485
- }));
546
+ const nextSeq = allDecisions.reduce((max, d) => Math.max(max, d.seq ?? 0), 0) + 1;
547
+ const fallback: Decision = {
548
+ seq: nextSeq,
549
+ id,
550
+ when_context: normalized.when_context,
551
+ scope: normalized.scope,
552
+ decision: normalized.decision,
553
+ choice: normalized.choice,
554
+ rationale: normalized.rationale,
555
+ revisable: normalized.revisable,
556
+ made_by: normalized.made_by,
557
+ superseded_by: null,
558
+ };
559
+ allDecisions = [...allDecisions, fallback];
486
560
  }
487
561
 
488
562
  const filePath = resolveGsdRootFile(basePath, 'DECISIONS');
@@ -538,48 +612,6 @@ export async function saveDecisionToDb(
538
612
  clearPathCache();
539
613
  clearParseCache();
540
614
 
541
- // ADR-013 dual-write: keep the memory store in sync with every decision
542
- // persisted via the legacy gsd_save_decision path. Without this, prompts
543
- // that still call gsd_save_decision (discuss.md, plan-milestone.md,
544
- // plan-slice.md, et al.) would create decisions rows invisible to
545
- // memory_query and loadMemoryBlock.
546
- // Best-effort — never throw, never roll back the decision on failure.
547
- try {
548
- const { createMemory } = await import('./memory-store.js');
549
- const decisionText = (fields.decision ?? '').trim();
550
- const choiceText = (fields.choice ?? '').trim();
551
- const rationaleText = (fields.rationale ?? '').trim();
552
- const contentParts: string[] = [];
553
- if (decisionText) contentParts.push(decisionText);
554
- if (choiceText) contentParts.push(`Chose: ${choiceText}.`);
555
- if (rationaleText) contentParts.push(`Rationale: ${rationaleText}.`);
556
- const content = contentParts.join(' ').slice(0, 600);
557
- if (content) {
558
- createMemory({
559
- category: 'architecture',
560
- content,
561
- scope: fields.scope || 'project',
562
- confidence: 0.85,
563
- structuredFields: {
564
- sourceDecisionId: id,
565
- when_context: fields.when_context ?? '',
566
- scope: fields.scope,
567
- decision: fields.decision,
568
- choice: fields.choice,
569
- rationale: fields.rationale,
570
- made_by: fields.made_by ?? 'agent',
571
- revisable: fields.revisable ?? '',
572
- },
573
- });
574
- }
575
- } catch (mirrorErr) {
576
- logError('manifest', 'memory-store mirror write failed (non-fatal)', {
577
- fn: 'saveDecisionToDb',
578
- decisionId: id,
579
- error: String((mirrorErr as Error).message),
580
- });
581
- }
582
-
583
615
  return { id };
584
616
  } catch (err) {
585
617
  logError('manifest', 'saveDecisionToDb failed', { fn: 'saveDecisionToDb', error: String((err as Error).message) });
@@ -589,6 +621,57 @@ export async function saveDecisionToDb(
589
621
  }
590
622
  }
591
623
 
624
+ /**
625
+ * ADR-013 dual-write — mirror a freshly-saved decision into the `memories`
626
+ * table so the memory store remains the single source of truth for the
627
+ * DECISIONS.md projection (Stage 2a) and for prompt-inline reads (Stage 1).
628
+ *
629
+ * Best-effort mirror: logs failures without throwing to avoid blocking saves.
630
+ * Caller invokes this AFTER the decisions-table write completes and
631
+ * BEFORE the projection regen — the regen sources from memories and would
632
+ * otherwise miss the just-saved decision.
633
+ */
634
+ async function mirrorDecisionToMemory(
635
+ id: string,
636
+ normalizedFields: NormalizedSaveDecisionFields,
637
+ ): Promise<boolean> {
638
+ try {
639
+ const { createMemory } = await import('./memory-store.js');
640
+ const { synthesizeDecisionMemoryContent } = await import('./memory-backfill.js');
641
+ const content = synthesizeDecisionMemoryContent(normalizedFields);
642
+ if (!content) return false;
643
+
644
+ createMemory({
645
+ category: 'architecture',
646
+ content,
647
+ scope: normalizedFields.scope || 'project',
648
+ confidence: 0.85,
649
+ structuredFields: {
650
+ sourceDecisionId: id,
651
+ when_context: normalizedFields.when_context,
652
+ scope: normalizedFields.scope,
653
+ decision: normalizedFields.decision,
654
+ choice: normalizedFields.choice,
655
+ rationale: normalizedFields.rationale,
656
+ made_by: normalizedFields.made_by,
657
+ revisable: normalizedFields.revisable,
658
+ // New decisions are always written as active; md-importer can later
659
+ // set superseded_by on the source decision row, and the backfill's
660
+ // drift auto-heal pass propagates that update to this memory.
661
+ superseded_by: null,
662
+ },
663
+ });
664
+ return true;
665
+ } catch (mirrorErr) {
666
+ logError('manifest', 'memory-store mirror write failed', {
667
+ fn: 'saveDecisionToDb',
668
+ decisionId: id,
669
+ error: String((mirrorErr as Error).message),
670
+ });
671
+ return false;
672
+ }
673
+ }
674
+
592
675
  /**
593
676
  * Extract a milestone/slice reference from a deferral decision.
594
677
  *
@@ -5,7 +5,7 @@ import { findMilestoneIds } from "./guided-flow.js";
5
5
  import { parseUnitId } from "./unit-id.js";
6
6
  import { isDbAvailable, getMilestoneSlices, getMilestone } from "./gsd-db.js";
7
7
  import { parseRoadmap } from "./parsers-legacy.js";
8
- import { isClosedStatus } from "./status-guards.js";
8
+ import { isClosedStatus, isSkippedForDispatch } from "./status-guards.js";
9
9
  import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
10
10
  import { readFileSync } from "node:fs";
11
11
 
@@ -58,7 +58,7 @@ export function getPriorSliceCompletionBlocker(
58
58
  // DB-backed projects must not treat SUMMARY.md as authoritative.
59
59
  if (isDbAvailable()) {
60
60
  const milestoneRow = getMilestone(mid);
61
- if (milestoneRow && isClosedStatus(milestoneRow.status)) continue;
61
+ if (milestoneRow && isSkippedForDispatch(milestoneRow.status)) continue;
62
62
  } else {
63
63
  const summaryPath = resolveMilestoneFile(base, mid, "SUMMARY");
64
64
  let summaryContent: string | null = null;
@@ -100,7 +100,7 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
100
100
 
101
101
  - `skill_rules`: situational rules with a human-readable `when` trigger and one or more of `use`, `prefer`, or `avoid`.
102
102
 
103
- - `custom_instructions`: extra durable instructions related to skill use. For operational project knowledge (recurring rules, gotchas, patterns), use `.gsd/KNOWLEDGE.md` instead it's injected into every agent prompt automatically and agents can append to it during execution.
103
+ - `custom_instructions`: extra durable instructions related to skill use. For operational project knowledge, use `.gsd/KNOWLEDGE.md` instead. Rules are file-canonical; patterns and lessons are persisted to the `memories` table and projected back into `KNOWLEDGE.md` on the next session start.
104
104
 
105
105
  - `language`: preferred response language for all GSD interactions. Accepts any language name or code — `"Chinese"`, `"zh"`, `"German"`, `"de"`, `"日本語"`, etc. When set, GSD injects "Always respond in \<language\>" into every agent's system prompt, including after `/clear`. Quickest way to set it: `/gsd language <name>`. To clear: `/gsd language off`.
106
106