gsd-pi 2.74.0 → 2.75.0-dev.fd2382b9f

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 (1043) hide show
  1. package/README.md +186 -149
  2. package/dist/claude-cli-check.d.ts +10 -0
  3. package/dist/claude-cli-check.js +13 -3
  4. package/dist/cli.js +85 -0
  5. package/dist/headless-events.d.ts +1 -1
  6. package/dist/headless-events.js +5 -2
  7. package/dist/headless-query.js +4 -1
  8. package/dist/headless.js +5 -6
  9. package/dist/help-text.js +23 -0
  10. package/dist/loader.js +0 -0
  11. package/dist/onboarding.js +39 -14
  12. package/dist/resources/extensions/ask-user-questions.js +17 -5
  13. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  14. package/dist/resources/extensions/claude-code-cli/readiness.js +12 -2
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +76 -4
  16. package/dist/resources/extensions/gsd/activity-log.js +16 -0
  17. package/dist/resources/extensions/gsd/auto/detect-stuck.js +20 -4
  18. package/dist/resources/extensions/gsd/auto/loop.js +214 -14
  19. package/dist/resources/extensions/gsd/auto/phases.js +273 -51
  20. package/dist/resources/extensions/gsd/auto/resolve.js +1 -1
  21. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -1
  22. package/dist/resources/extensions/gsd/auto/session.js +15 -0
  23. package/dist/resources/extensions/gsd/auto-artifact-paths.js +20 -0
  24. package/dist/resources/extensions/gsd/auto-dashboard.js +15 -7
  25. package/dist/resources/extensions/gsd/auto-dispatch.js +123 -7
  26. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  27. package/dist/resources/extensions/gsd/auto-model-selection.js +64 -10
  28. package/dist/resources/extensions/gsd/auto-post-unit.js +229 -24
  29. package/dist/resources/extensions/gsd/auto-prompts.js +159 -33
  30. package/dist/resources/extensions/gsd/auto-recovery.js +81 -10
  31. package/dist/resources/extensions/gsd/auto-start.js +5 -3
  32. package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
  33. package/dist/resources/extensions/gsd/auto-verification.js +103 -5
  34. package/dist/resources/extensions/gsd/auto-worktree.js +57 -1
  35. package/dist/resources/extensions/gsd/auto.js +84 -27
  36. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +8 -21
  37. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +22 -4
  38. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -3
  39. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +29 -0
  40. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +30 -8
  41. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +83 -9
  42. package/dist/resources/extensions/gsd/cache.js +16 -5
  43. package/dist/resources/extensions/gsd/commands/catalog.js +97 -3
  44. package/dist/resources/extensions/gsd/commands/handlers/core.js +11 -1
  45. package/dist/resources/extensions/gsd/commands/handlers/escalate.js +171 -0
  46. package/dist/resources/extensions/gsd/commands/handlers/ops.js +41 -0
  47. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +295 -37
  48. package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
  49. package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
  50. package/dist/resources/extensions/gsd/commands-cmux.js +5 -2
  51. package/dist/resources/extensions/gsd/commands-debug.js +388 -0
  52. package/dist/resources/extensions/gsd/commands-do.js +80 -0
  53. package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
  54. package/dist/resources/extensions/gsd/commands-handlers.js +21 -2
  55. package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
  56. package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
  57. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +51 -4
  58. package/dist/resources/extensions/gsd/commands-scan.js +94 -0
  59. package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
  60. package/dist/resources/extensions/gsd/commands-ship.js +187 -0
  61. package/dist/resources/extensions/gsd/commands-workflow-templates.js +101 -2
  62. package/dist/resources/extensions/gsd/custom-workflow-engine.js +74 -54
  63. package/dist/resources/extensions/gsd/db-writer.js +4 -5
  64. package/dist/resources/extensions/gsd/debug-session-store.js +238 -0
  65. package/dist/resources/extensions/gsd/definition-loader.js +7 -0
  66. package/dist/resources/extensions/gsd/docs/preferences-reference.md +17 -2
  67. package/dist/resources/extensions/gsd/doctor-git-checks.js +5 -1
  68. package/dist/resources/extensions/gsd/doctor-proactive.js +4 -1
  69. package/dist/resources/extensions/gsd/doctor-providers.js +48 -20
  70. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +22 -4
  71. package/dist/resources/extensions/gsd/doctor.js +7 -1
  72. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
  73. package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
  74. package/dist/resources/extensions/gsd/error-classifier.js +6 -3
  75. package/dist/resources/extensions/gsd/escalation.js +321 -0
  76. package/dist/resources/extensions/gsd/forensics.js +26 -29
  77. package/dist/resources/extensions/gsd/git-service.js +49 -2
  78. package/dist/resources/extensions/gsd/graph-context.js +157 -0
  79. package/dist/resources/extensions/gsd/graph.js +26 -2
  80. package/dist/resources/extensions/gsd/gsd-db.js +822 -18
  81. package/dist/resources/extensions/gsd/guided-flow.js +31 -6
  82. package/dist/resources/extensions/gsd/health-widget-core.js +42 -14
  83. package/dist/resources/extensions/gsd/health-widget.js +7 -4
  84. package/dist/resources/extensions/gsd/index.js +15 -2
  85. package/dist/resources/extensions/gsd/init-wizard.js +1 -0
  86. package/dist/resources/extensions/gsd/journal.js +27 -0
  87. package/dist/resources/extensions/gsd/md-importer.js +3 -4
  88. package/dist/resources/extensions/gsd/memory-store.js +19 -51
  89. package/dist/resources/extensions/gsd/metrics.js +20 -0
  90. package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
  91. package/dist/resources/extensions/gsd/model-cost-table.js +3 -1
  92. package/dist/resources/extensions/gsd/model-router.js +7 -1
  93. package/dist/resources/extensions/gsd/native-git-bridge.js +144 -9
  94. package/dist/resources/extensions/gsd/notification-widget.js +24 -39
  95. package/dist/resources/extensions/gsd/notifications.js +4 -0
  96. package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
  97. package/dist/resources/extensions/gsd/post-execution-checks.js +27 -11
  98. package/dist/resources/extensions/gsd/pre-execution-checks.js +97 -4
  99. package/dist/resources/extensions/gsd/preferences-models.js +21 -3
  100. package/dist/resources/extensions/gsd/preferences-types.js +4 -1
  101. package/dist/resources/extensions/gsd/preferences-validation.js +160 -10
  102. package/dist/resources/extensions/gsd/preferences.js +41 -10
  103. package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
  104. package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  105. package/dist/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  106. package/dist/resources/extensions/gsd/prompts/execute-task.md +12 -0
  107. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  108. package/dist/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  109. package/dist/resources/extensions/gsd/prompts/scan.md +79 -0
  110. package/dist/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  111. package/dist/resources/extensions/gsd/run-manager.js +37 -17
  112. package/dist/resources/extensions/gsd/safety/evidence-collector.js +15 -30
  113. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
  114. package/dist/resources/extensions/gsd/state.js +52 -4
  115. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +19 -0
  116. package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -0
  117. package/dist/resources/extensions/gsd/tools/complete-task.js +80 -0
  118. package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -12
  119. package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -2
  120. package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
  121. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
  122. package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
  123. package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
  124. package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
  125. package/dist/resources/extensions/gsd/uok/audit.js +40 -0
  126. package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
  127. package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
  128. package/dist/resources/extensions/gsd/uok/flags.js +29 -0
  129. package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
  130. package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
  131. package/dist/resources/extensions/gsd/uok/kernel.js +85 -0
  132. package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
  133. package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
  134. package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
  135. package/dist/resources/extensions/gsd/workflow-dispatch.js +64 -0
  136. package/dist/resources/extensions/gsd/workflow-install.js +327 -0
  137. package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
  138. package/dist/resources/extensions/gsd/workflow-manifest.js +16 -69
  139. package/dist/resources/extensions/gsd/workflow-mcp.js +1 -6
  140. package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
  141. package/dist/resources/extensions/gsd/workflow-plugins.js +346 -0
  142. package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
  143. package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
  144. package/dist/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  145. package/dist/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  146. package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  147. package/dist/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  148. package/dist/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  149. package/dist/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  150. package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  151. package/dist/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  152. package/dist/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  153. package/dist/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  154. package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  155. package/dist/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  156. package/dist/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  157. package/dist/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  158. package/dist/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  159. package/dist/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  160. package/dist/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  161. package/dist/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  162. package/dist/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  163. package/dist/resources/extensions/gsd/workflow-templates/release.md +118 -0
  164. package/dist/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  165. package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  166. package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  167. package/dist/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  168. package/dist/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  169. package/dist/resources/extensions/gsd/worktree-resolver.js +42 -1
  170. package/dist/resources/extensions/remote-questions/commands.js +380 -0
  171. package/dist/resources/extensions/remote-questions/manager.js +39 -5
  172. package/dist/resources/extensions/remote-questions/telegram-adapter.js +79 -4
  173. package/dist/resources/extensions/shared/interview-ui.js +189 -1
  174. package/dist/resources/extensions/shared/layout-utils.js +17 -0
  175. package/dist/resources/extensions/shared/rtk-shared.js +47 -0
  176. package/dist/resources/extensions/shared/rtk.js +3 -46
  177. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  178. package/dist/resources/skills/create-workflow/SKILL.md +33 -6
  179. package/dist/rtk-shared.d.ts +10 -0
  180. package/dist/rtk-shared.js +47 -0
  181. package/dist/rtk.d.ts +2 -6
  182. package/dist/rtk.js +3 -48
  183. package/dist/shared/workspace-types.d.ts +52 -0
  184. package/dist/shared/workspace-types.js +1 -0
  185. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  186. package/dist/update-check.d.ts +10 -0
  187. package/dist/update-check.js +24 -3
  188. package/dist/web/standalone/.next/BUILD_ID +1 -1
  189. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  190. package/dist/web/standalone/.next/build-manifest.json +4 -4
  191. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  192. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  193. package/dist/web/standalone/.next/required-server-files.json +3 -3
  194. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  195. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  197. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  198. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  199. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  200. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  205. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  207. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  208. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  209. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  210. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  211. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  212. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  213. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  214. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  221. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  233. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  235. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  238. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  240. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  241. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  242. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  243. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  244. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  246. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  247. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  248. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  249. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  250. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  252. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  253. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  254. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  255. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  256. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  257. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  258. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  259. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  260. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  261. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  262. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  263. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  264. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  265. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  266. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  267. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  268. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  269. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  270. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  271. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  272. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  273. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  274. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  275. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  276. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  277. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  278. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  279. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  280. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  281. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  282. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  283. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  284. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  285. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  286. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  287. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  288. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  289. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  290. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  291. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  292. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  293. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  294. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  295. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  296. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  297. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  298. package/dist/web/standalone/.next/server/app/index.html +1 -1
  299. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  300. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  301. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  302. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  303. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  304. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  305. package/dist/web/standalone/.next/server/app/page.js +2 -2
  306. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  307. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  308. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  309. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  310. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  311. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  312. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  313. package/dist/web/standalone/.next/server/middleware.js +2 -2
  314. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  315. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  316. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  317. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  318. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  319. package/dist/web/standalone/.next/static/chunks/2826.02df9631042cc18e.js +9 -0
  320. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  321. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  322. package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
  323. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  324. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  325. package/dist/web/standalone/.next/static/chunks/{webpack-b868033a5834586d.js → webpack-6c7cda3e318eedb6.js} +1 -1
  326. package/dist/web/standalone/.next/static/css/3e9cdadb4d23b8a4.css +1 -0
  327. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  328. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  329. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  330. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  331. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  332. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  333. package/dist/web/standalone/server.js +1 -1
  334. package/dist/welcome-screen.js +48 -24
  335. package/dist/wizard.js +2 -2
  336. package/dist/worktree-cli.d.ts +6 -5
  337. package/dist/worktree-cli.js +23 -7
  338. package/package.json +5 -4
  339. package/packages/daemon/package.json +2 -2
  340. package/packages/mcp-server/dist/index.d.ts +3 -0
  341. package/packages/mcp-server/dist/index.d.ts.map +1 -1
  342. package/packages/mcp-server/dist/index.js +3 -0
  343. package/packages/mcp-server/dist/index.js.map +1 -1
  344. package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
  345. package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
  346. package/packages/mcp-server/dist/readers/graph.js +655 -0
  347. package/packages/mcp-server/dist/readers/graph.js.map +1 -0
  348. package/packages/mcp-server/dist/readers/index.d.ts +2 -0
  349. package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
  350. package/packages/mcp-server/dist/readers/index.js +1 -0
  351. package/packages/mcp-server/dist/readers/index.js.map +1 -1
  352. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  353. package/packages/mcp-server/dist/server.js +65 -0
  354. package/packages/mcp-server/dist/server.js.map +1 -1
  355. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  356. package/packages/mcp-server/dist/workflow-tools.js +88 -6
  357. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  358. package/packages/mcp-server/package.json +2 -2
  359. package/packages/mcp-server/src/index.ts +15 -0
  360. package/packages/mcp-server/src/readers/graph.test.ts +604 -0
  361. package/packages/mcp-server/src/readers/graph.ts +855 -0
  362. package/packages/mcp-server/src/readers/index.ts +12 -0
  363. package/packages/mcp-server/src/server.ts +83 -0
  364. package/packages/mcp-server/src/workflow-tools.ts +95 -10
  365. package/packages/mcp-server/tsconfig.json +1 -0
  366. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
  367. package/packages/native/package.json +2 -2
  368. package/packages/native/tsconfig.tsbuildinfo +1 -0
  369. package/packages/pi-agent-core/package.json +1 -1
  370. package/packages/pi-agent-core/tsconfig.json +1 -0
  371. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
  372. package/packages/pi-ai/dist/index.d.ts +1 -9
  373. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  374. package/packages/pi-ai/dist/index.js +1 -9
  375. package/packages/pi-ai/dist/index.js.map +1 -1
  376. package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
  377. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
  378. package/packages/pi-ai/dist/models/capability-patches.js +37 -0
  379. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
  380. package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
  381. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
  382. package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
  383. package/packages/pi-ai/dist/models/custom.js.map +1 -0
  384. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1550 -0
  385. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
  386. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1552 -0
  387. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
  388. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +394 -0
  389. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
  390. package/packages/pi-ai/dist/models/generated/anthropic.js +396 -0
  391. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
  392. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
  393. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
  394. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
  395. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
  396. package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
  397. package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
  398. package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
  399. package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
  400. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
  401. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
  402. package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
  403. package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
  404. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +173 -0
  405. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
  406. package/packages/pi-ai/dist/models/generated/google-antigravity.js +175 -0
  407. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
  408. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
  409. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
  410. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
  411. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
  412. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
  413. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
  414. package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
  415. package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
  416. package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
  417. package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
  418. package/packages/pi-ai/dist/models/generated/google.js +464 -0
  419. package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
  420. package/packages/pi-ai/dist/models/generated/groq.d.ts +156 -0
  421. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
  422. package/packages/pi-ai/dist/models/generated/groq.js +158 -0
  423. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
  424. package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
  425. package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
  426. package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
  427. package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
  428. package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +137 -154
  429. package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
  430. package/packages/pi-ai/dist/models/generated/index.js +51 -0
  431. package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
  432. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
  433. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
  434. package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
  435. package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
  436. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
  437. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
  438. package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
  439. package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
  440. package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
  441. package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
  442. package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
  443. package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
  444. package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
  445. package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
  446. package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
  447. package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
  448. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +156 -0
  449. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
  450. package/packages/pi-ai/dist/models/generated/openai-codex.js +158 -0
  451. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
  452. package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
  453. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
  454. package/packages/pi-ai/dist/models/generated/openai.js +702 -0
  455. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
  456. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
  457. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
  458. package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
  459. package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
  460. package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
  461. package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
  462. package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
  463. package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
  464. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4287 -0
  465. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
  466. package/packages/pi-ai/dist/models/generated/openrouter.js +4289 -0
  467. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
  468. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
  469. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
  470. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
  471. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
  472. package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
  473. package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
  474. package/packages/pi-ai/dist/models/generated/xai.js +413 -0
  475. package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
  476. package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
  477. package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
  478. package/packages/pi-ai/dist/models/generated/zai.js +239 -0
  479. package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
  480. package/packages/pi-ai/dist/models/index.d.ts +27 -0
  481. package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
  482. package/packages/pi-ai/dist/models/index.js +80 -0
  483. package/packages/pi-ai/dist/models/index.js.map +1 -0
  484. package/packages/pi-ai/dist/models.d.ts +1 -36
  485. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  486. package/packages/pi-ai/dist/models.generated.test.js +18 -2
  487. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  488. package/packages/pi-ai/dist/models.js +3 -112
  489. package/packages/pi-ai/dist/models.js.map +1 -1
  490. package/packages/pi-ai/dist/models.test.js +6 -5
  491. package/packages/pi-ai/dist/models.test.js.map +1 -1
  492. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts +22 -1
  493. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  494. package/packages/pi-ai/dist/providers/amazon-bedrock.js +40 -6
  495. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  496. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts +2 -0
  497. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts.map +1 -0
  498. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js +106 -0
  499. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js.map +1 -0
  500. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +42 -1
  501. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  502. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +20 -1
  503. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  504. package/packages/pi-ai/dist/providers/anthropic-shared.js +32 -2
  505. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  506. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +12 -1
  507. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
  508. package/packages/pi-ai/dist/providers/anthropic.d.ts +11 -0
  509. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  510. package/packages/pi-ai/dist/providers/anthropic.js +18 -1
  511. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  512. package/packages/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
  513. package/packages/pi-ai/dist/utils/oauth/openai-codex.js +12 -0
  514. package/packages/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
  515. package/packages/pi-ai/package.json +2 -2
  516. package/packages/pi-ai/scripts/generate-models.ts +124 -40
  517. package/packages/pi-ai/src/index.ts +1 -9
  518. package/packages/pi-ai/src/models/capability-patches.ts +43 -0
  519. package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
  520. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1554 -0
  521. package/packages/pi-ai/src/models/generated/anthropic.ts +398 -0
  522. package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
  523. package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
  524. package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
  525. package/packages/pi-ai/src/models/generated/google-antigravity.ts +177 -0
  526. package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
  527. package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
  528. package/packages/pi-ai/src/models/generated/google.ts +466 -0
  529. package/packages/pi-ai/src/models/generated/groq.ts +160 -0
  530. package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
  531. package/packages/pi-ai/src/models/generated/index.ts +52 -0
  532. package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
  533. package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
  534. package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
  535. package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
  536. package/packages/pi-ai/src/models/generated/openai-codex.ts +160 -0
  537. package/packages/pi-ai/src/models/generated/openai.ts +704 -0
  538. package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
  539. package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
  540. package/packages/pi-ai/src/models/generated/openrouter.ts +4291 -0
  541. package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
  542. package/packages/pi-ai/src/models/generated/xai.ts +415 -0
  543. package/packages/pi-ai/src/models/generated/zai.ts +241 -0
  544. package/packages/pi-ai/src/models/index.ts +106 -0
  545. package/packages/pi-ai/src/models.generated.test.ts +18 -2
  546. package/packages/pi-ai/src/models.test.ts +6 -5
  547. package/packages/pi-ai/src/models.ts +3 -153
  548. package/packages/pi-ai/src/providers/amazon-bedrock.test.ts +164 -0
  549. package/packages/pi-ai/src/providers/amazon-bedrock.ts +41 -7
  550. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +47 -1
  551. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +15 -1
  552. package/packages/pi-ai/src/providers/anthropic-shared.ts +36 -3
  553. package/packages/pi-ai/src/providers/anthropic.ts +19 -1
  554. package/packages/pi-ai/src/utils/oauth/openai-codex.ts +15 -0
  555. package/packages/pi-ai/tsconfig.json +1 -0
  556. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
  557. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts +2 -0
  558. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts.map +1 -0
  559. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +38 -0
  560. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -0
  561. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  562. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -2
  563. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  564. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +14 -0
  565. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  566. package/packages/pi-coding-agent/dist/core/auth-storage.js +34 -0
  567. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  568. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +74 -0
  569. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  570. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +476 -1
  571. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  572. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +32 -0
  573. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  574. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
  575. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
  576. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
  577. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
  578. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  579. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  580. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  581. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  582. package/packages/pi-coding-agent/dist/core/sdk.js +32 -0
  583. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  584. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +2 -2
  585. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  586. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.d.ts +2 -0
  587. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.d.ts.map +1 -0
  588. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +61 -0
  589. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -0
  590. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +11 -0
  591. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  592. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +1 -0
  593. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  594. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +23 -9
  595. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  596. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +11 -0
  597. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
  598. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +63 -0
  599. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -0
  600. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.d.ts +8 -5
  601. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  602. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +27 -13
  603. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  604. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  605. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +48 -34
  606. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  607. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  608. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  609. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +68 -8
  610. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  611. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  612. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +22 -22
  613. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  614. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts +4 -0
  615. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  616. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +315 -51
  617. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  618. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
  619. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
  620. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
  621. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
  622. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +14 -0
  623. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  624. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +70 -6
  625. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  626. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
  627. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  628. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +77 -0
  629. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  630. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -66
  631. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  632. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +1 -75
  633. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  634. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +1 -1
  635. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  636. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +192 -24
  637. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  638. package/packages/pi-coding-agent/package.json +1 -1
  639. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +56 -0
  640. package/packages/pi-coding-agent/src/core/agent-session.ts +12 -6
  641. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +83 -0
  642. package/packages/pi-coding-agent/src/core/auth-storage.ts +35 -0
  643. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +616 -1
  644. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +37 -1
  645. package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
  646. package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
  647. package/packages/pi-coding-agent/src/core/sdk.ts +41 -0
  648. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +2 -2
  649. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +92 -0
  650. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +19 -0
  651. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +25 -10
  652. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +87 -0
  653. package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +36 -15
  654. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +53 -31
  655. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +83 -7
  656. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +23 -26
  657. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +386 -77
  658. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  659. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +92 -6
  660. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +83 -0
  661. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +2 -83
  662. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +208 -27
  663. package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
  664. package/packages/pi-coding-agent/tsconfig.json +3 -2
  665. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
  666. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  667. package/packages/pi-tui/dist/tui.js +9 -2
  668. package/packages/pi-tui/dist/tui.js.map +1 -1
  669. package/packages/pi-tui/package.json +1 -1
  670. package/packages/pi-tui/src/tui.ts +9 -1
  671. package/packages/pi-tui/tsconfig.json +1 -0
  672. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
  673. package/packages/rpc-client/package.json +1 -1
  674. package/packages/rpc-client/tsconfig.json +1 -0
  675. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
  676. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
  677. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  678. package/pkg/dist/modes/interactive/theme/theme-schema.js +77 -0
  679. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  680. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -66
  681. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  682. package/pkg/dist/modes/interactive/theme/theme.js +1 -75
  683. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  684. package/pkg/dist/modes/interactive/theme/themes.d.ts +1 -1
  685. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  686. package/pkg/dist/modes/interactive/theme/themes.js +192 -24
  687. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  688. package/pkg/package.json +1 -1
  689. package/src/resources/extensions/ask-user-questions.ts +24 -6
  690. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  691. package/src/resources/extensions/claude-code-cli/readiness.ts +13 -2
  692. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +94 -4
  693. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +84 -0
  694. package/src/resources/extensions/gsd/activity-log.ts +21 -0
  695. package/src/resources/extensions/gsd/auto/detect-stuck.ts +22 -4
  696. package/src/resources/extensions/gsd/auto/loop-deps.ts +11 -0
  697. package/src/resources/extensions/gsd/auto/loop.ts +268 -13
  698. package/src/resources/extensions/gsd/auto/phases.ts +349 -64
  699. package/src/resources/extensions/gsd/auto/resolve.ts +1 -1
  700. package/src/resources/extensions/gsd/auto/run-unit.ts +11 -1
  701. package/src/resources/extensions/gsd/auto/session.ts +17 -0
  702. package/src/resources/extensions/gsd/auto-artifact-paths.ts +20 -0
  703. package/src/resources/extensions/gsd/auto-dashboard.ts +21 -4
  704. package/src/resources/extensions/gsd/auto-dispatch.ts +139 -11
  705. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  706. package/src/resources/extensions/gsd/auto-model-selection.ts +82 -10
  707. package/src/resources/extensions/gsd/auto-post-unit.ts +247 -25
  708. package/src/resources/extensions/gsd/auto-prompts.ts +188 -35
  709. package/src/resources/extensions/gsd/auto-recovery.ts +92 -10
  710. package/src/resources/extensions/gsd/auto-start.ts +8 -6
  711. package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
  712. package/src/resources/extensions/gsd/auto-verification.ts +132 -5
  713. package/src/resources/extensions/gsd/auto-worktree.ts +66 -0
  714. package/src/resources/extensions/gsd/auto.ts +92 -28
  715. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +8 -21
  716. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +22 -4
  717. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +5 -3
  718. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +31 -0
  719. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +38 -8
  720. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +94 -8
  721. package/src/resources/extensions/gsd/cache.ts +16 -5
  722. package/src/resources/extensions/gsd/commands/catalog.ts +90 -3
  723. package/src/resources/extensions/gsd/commands/handlers/core.ts +11 -1
  724. package/src/resources/extensions/gsd/commands/handlers/escalate.ts +216 -0
  725. package/src/resources/extensions/gsd/commands/handlers/ops.ts +41 -0
  726. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +352 -37
  727. package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
  728. package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
  729. package/src/resources/extensions/gsd/commands-cmux.ts +6 -2
  730. package/src/resources/extensions/gsd/commands-debug.ts +484 -0
  731. package/src/resources/extensions/gsd/commands-do.ts +110 -0
  732. package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
  733. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  734. package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
  735. package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
  736. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +58 -4
  737. package/src/resources/extensions/gsd/commands-scan.ts +125 -0
  738. package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
  739. package/src/resources/extensions/gsd/commands-ship.ts +219 -0
  740. package/src/resources/extensions/gsd/commands-workflow-templates.ts +129 -2
  741. package/src/resources/extensions/gsd/custom-workflow-engine.ts +85 -60
  742. package/src/resources/extensions/gsd/db-writer.ts +6 -5
  743. package/src/resources/extensions/gsd/debug-session-store.ts +377 -0
  744. package/src/resources/extensions/gsd/definition-loader.ts +7 -0
  745. package/src/resources/extensions/gsd/docs/preferences-reference.md +17 -2
  746. package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -1
  747. package/src/resources/extensions/gsd/doctor-proactive.ts +4 -1
  748. package/src/resources/extensions/gsd/doctor-providers.ts +52 -22
  749. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +23 -4
  750. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  751. package/src/resources/extensions/gsd/doctor.ts +7 -1
  752. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
  753. package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
  754. package/src/resources/extensions/gsd/error-classifier.ts +6 -3
  755. package/src/resources/extensions/gsd/escalation.ts +367 -0
  756. package/src/resources/extensions/gsd/forensics.ts +25 -29
  757. package/src/resources/extensions/gsd/git-service.ts +68 -1
  758. package/src/resources/extensions/gsd/graph-context.ts +212 -0
  759. package/src/resources/extensions/gsd/graph.ts +33 -3
  760. package/src/resources/extensions/gsd/gsd-db.ts +1083 -21
  761. package/src/resources/extensions/gsd/guided-flow.ts +36 -2
  762. package/src/resources/extensions/gsd/health-widget-core.ts +43 -14
  763. package/src/resources/extensions/gsd/health-widget.ts +7 -3
  764. package/src/resources/extensions/gsd/index.ts +18 -2
  765. package/src/resources/extensions/gsd/init-wizard.ts +3 -2
  766. package/src/resources/extensions/gsd/journal.ts +30 -0
  767. package/src/resources/extensions/gsd/md-importer.ts +3 -5
  768. package/src/resources/extensions/gsd/memory-store.ts +31 -62
  769. package/src/resources/extensions/gsd/metrics.ts +27 -0
  770. package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
  771. package/src/resources/extensions/gsd/model-cost-table.ts +3 -1
  772. package/src/resources/extensions/gsd/model-router.ts +15 -1
  773. package/src/resources/extensions/gsd/native-git-bridge.ts +145 -18
  774. package/src/resources/extensions/gsd/notification-widget.ts +25 -43
  775. package/src/resources/extensions/gsd/notifications.ts +6 -0
  776. package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
  777. package/src/resources/extensions/gsd/post-execution-checks.ts +37 -14
  778. package/src/resources/extensions/gsd/pre-execution-checks.ts +98 -8
  779. package/src/resources/extensions/gsd/preferences-models.ts +21 -3
  780. package/src/resources/extensions/gsd/preferences-types.ts +47 -1
  781. package/src/resources/extensions/gsd/preferences-validation.ts +150 -9
  782. package/src/resources/extensions/gsd/preferences.ts +44 -10
  783. package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
  784. package/src/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  785. package/src/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  786. package/src/resources/extensions/gsd/prompts/execute-task.md +12 -0
  787. package/src/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  788. package/src/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  789. package/src/resources/extensions/gsd/prompts/scan.md +79 -0
  790. package/src/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  791. package/src/resources/extensions/gsd/run-manager.ts +53 -19
  792. package/src/resources/extensions/gsd/safety/evidence-collector.ts +15 -31
  793. package/src/resources/extensions/gsd/session-lock.ts +14 -2
  794. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
  795. package/src/resources/extensions/gsd/state.ts +59 -4
  796. package/src/resources/extensions/gsd/templates/PREFERENCES.md +19 -0
  797. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -34
  798. package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +7 -0
  799. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +177 -0
  800. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +49 -31
  801. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
  802. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
  803. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +123 -1
  804. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +272 -0
  805. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +117 -0
  806. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +39 -0
  807. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +39 -0
  808. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
  809. package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
  810. package/src/resources/extensions/gsd/tests/commands-do.test.ts +175 -0
  811. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
  812. package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
  813. package/src/resources/extensions/gsd/tests/commands-scan.test.ts +351 -0
  814. package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
  815. package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
  816. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +22 -6
  817. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  818. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  819. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +63 -0
  820. package/src/resources/extensions/gsd/tests/debug-command-handler.test.ts +905 -0
  821. package/src/resources/extensions/gsd/tests/debug-command-lifecycle.integration.test.ts +1229 -0
  822. package/src/resources/extensions/gsd/tests/debug-session-store.test.ts +565 -0
  823. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +64 -0
  824. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +67 -0
  825. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +62 -18
  826. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +5 -0
  827. package/src/resources/extensions/gsd/tests/escalation.test.ts +818 -0
  828. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
  829. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +39 -19
  830. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +106 -0
  831. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +74 -0
  832. package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
  833. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +0 -4
  834. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -1
  835. package/src/resources/extensions/gsd/tests/health-widget.test.ts +9 -3
  836. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +39 -0
  837. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +44 -0
  838. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +68 -1
  839. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +109 -11
  840. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +51 -0
  841. package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
  842. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +242 -5
  843. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
  844. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
  845. package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +3 -2
  846. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +2 -2
  847. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  848. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +59 -0
  849. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
  850. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +1 -1
  851. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +17 -0
  852. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  853. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -1
  854. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
  855. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +275 -6
  856. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
  857. package/src/resources/extensions/gsd/tests/preferences.test.ts +214 -1
  858. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +539 -0
  859. package/src/resources/extensions/gsd/tests/projection-regression.test.ts +7 -0
  860. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +27 -0
  861. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +24 -0
  862. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +1 -1
  863. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +90 -2
  864. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +68 -1
  865. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +107 -0
  866. package/src/resources/extensions/gsd/tests/requirements.test.ts +9 -0
  867. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +153 -0
  868. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
  869. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +16 -4
  870. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +3 -0
  871. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +15 -0
  872. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +5 -0
  873. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -5
  874. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
  875. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +86 -0
  876. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
  877. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +69 -0
  878. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
  879. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
  880. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
  881. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +166 -0
  882. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
  883. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
  884. package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
  885. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
  886. package/src/resources/extensions/gsd/tests/workflow-install.test.ts +113 -0
  887. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +232 -0
  888. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  889. package/src/resources/extensions/gsd/tests/workflow-plugins.test.ts +310 -0
  890. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +7 -0
  891. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +8 -2
  892. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +2 -1
  893. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +77 -2
  894. package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -0
  895. package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
  896. package/src/resources/extensions/gsd/tools/plan-milestone.ts +42 -8
  897. package/src/resources/extensions/gsd/tools/plan-slice.ts +6 -1
  898. package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
  899. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
  900. package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
  901. package/src/resources/extensions/gsd/types.ts +76 -1
  902. package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
  903. package/src/resources/extensions/gsd/unit-runtime.ts +1 -0
  904. package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
  905. package/src/resources/extensions/gsd/uok/audit.ts +51 -0
  906. package/src/resources/extensions/gsd/uok/contracts.ts +136 -0
  907. package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
  908. package/src/resources/extensions/gsd/uok/flags.ts +45 -0
  909. package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
  910. package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
  911. package/src/resources/extensions/gsd/uok/kernel.ts +117 -0
  912. package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
  913. package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
  914. package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
  915. package/src/resources/extensions/gsd/workflow-dispatch.ts +106 -0
  916. package/src/resources/extensions/gsd/workflow-install.ts +423 -0
  917. package/src/resources/extensions/gsd/workflow-logger.ts +27 -1
  918. package/src/resources/extensions/gsd/workflow-manifest.ts +17 -104
  919. package/src/resources/extensions/gsd/workflow-mcp.ts +1 -6
  920. package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
  921. package/src/resources/extensions/gsd/workflow-plugins.ts +403 -0
  922. package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
  923. package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
  924. package/src/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  925. package/src/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  926. package/src/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  927. package/src/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  928. package/src/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  929. package/src/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  930. package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  931. package/src/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  932. package/src/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  933. package/src/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  934. package/src/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  935. package/src/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  936. package/src/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  937. package/src/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  938. package/src/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  939. package/src/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  940. package/src/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  941. package/src/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  942. package/src/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  943. package/src/resources/extensions/gsd/workflow-templates/release.md +118 -0
  944. package/src/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  945. package/src/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  946. package/src/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  947. package/src/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  948. package/src/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  949. package/src/resources/extensions/gsd/workflow-templates.ts +7 -0
  950. package/src/resources/extensions/gsd/workspace-index.ts +9 -4
  951. package/src/resources/extensions/gsd/worktree-resolver.ts +47 -1
  952. package/src/resources/extensions/remote-questions/commands.ts +480 -0
  953. package/src/resources/extensions/remote-questions/manager.ts +49 -4
  954. package/src/resources/extensions/remote-questions/telegram-adapter.ts +86 -4
  955. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +246 -0
  956. package/src/resources/extensions/remote-questions/tests/remote-answer-normalization.test.ts +92 -0
  957. package/src/resources/extensions/remote-questions/tests/telegram-commands.test.ts +267 -0
  958. package/src/resources/extensions/shared/interview-ui.ts +195 -1
  959. package/src/resources/extensions/shared/layout-utils.ts +26 -0
  960. package/src/resources/extensions/shared/rtk-shared.ts +58 -0
  961. package/src/resources/extensions/shared/rtk.ts +12 -52
  962. package/src/resources/extensions/shared/tests/interview-preview.test.ts +177 -0
  963. package/src/resources/extensions/shared/tests/preview-layout.test.ts +120 -0
  964. package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
  965. package/src/resources/skills/create-workflow/SKILL.md +33 -6
  966. package/dist/web/standalone/.next/static/chunks/2826.dd3dc8bbd3025fa5.js +0 -9
  967. package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
  968. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  969. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  970. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +0 -1
  971. package/packages/native/dist/ps/types.d.ts +0 -5
  972. package/packages/native/dist/ps/types.js +0 -2
  973. package/packages/native/src/ps/types.ts +0 -5
  974. package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
  975. package/packages/pi-ai/dist/models.custom.js.map +0 -1
  976. package/packages/pi-ai/dist/models.generated.js +0 -14343
  977. package/packages/pi-ai/dist/models.generated.js.map +0 -1
  978. package/packages/pi-ai/node_modules/@smithy/node-http-handler/LICENSE +0 -201
  979. package/packages/pi-ai/node_modules/@smithy/node-http-handler/README.md +0 -9
  980. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-cjs/index.js +0 -762
  981. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +0 -19
  982. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/constants.js +0 -1
  983. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +0 -9
  984. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/index.js +0 -3
  985. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +0 -230
  986. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +0 -87
  987. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +0 -32
  988. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +0 -169
  989. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/readable.mock.js +0 -21
  990. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/server.mock.js +0 -88
  991. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +0 -36
  992. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +0 -21
  993. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +0 -22
  994. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +0 -23
  995. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +0 -8
  996. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +0 -41
  997. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/readable.mock.js +0 -21
  998. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/timing.js +0 -4
  999. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +0 -63
  1000. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +0 -10
  1001. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +0 -5
  1002. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +0 -4
  1003. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +0 -3
  1004. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +0 -46
  1005. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +0 -24
  1006. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +0 -12
  1007. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +0 -63
  1008. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/readable.mock.d.ts +0 -13
  1009. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/server.mock.d.ts +0 -12
  1010. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +0 -2
  1011. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +0 -6
  1012. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +0 -6
  1013. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +0 -2
  1014. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +0 -5
  1015. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +0 -6
  1016. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/readable.mock.d.ts +0 -13
  1017. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +0 -8
  1018. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/build-abort-error.d.ts +0 -10
  1019. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/constants.d.ts +0 -5
  1020. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/get-transformed-headers.d.ts +0 -4
  1021. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/index.d.ts +0 -3
  1022. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http-handler.d.ts +0 -46
  1023. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-manager.d.ts +0 -24
  1024. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-pool.d.ts +0 -12
  1025. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-handler.d.ts +0 -63
  1026. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/readable.mock.d.ts +0 -13
  1027. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/server.mock.d.ts +0 -12
  1028. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-connection-timeout.d.ts +0 -2
  1029. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-request-timeout.d.ts +0 -6
  1030. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-keep-alive.d.ts +0 -6
  1031. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-timeout.d.ts +0 -2
  1032. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/collector.d.ts +0 -5
  1033. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/index.d.ts +0 -6
  1034. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/readable.mock.d.ts +0 -13
  1035. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/timing.d.ts +0 -8
  1036. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/write-request-body.d.ts +0 -12
  1037. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +0 -12
  1038. package/packages/pi-ai/node_modules/@smithy/node-http-handler/package.json +0 -68
  1039. package/packages/pi-ai/oauth.d.ts +0 -1
  1040. package/packages/pi-ai/oauth.js +0 -1
  1041. package/packages/pi-ai/src/models.generated.ts +0 -14345
  1042. /package/dist/web/standalone/.next/static/{JpjdI2QtmIkQr4xz6gbhM → jaWw1Jh0TYayjbfOrFe8D}/_buildManifest.js +0 -0
  1043. /package/dist/web/standalone/.next/static/{JpjdI2QtmIkQr4xz6gbhM → jaWw1Jh0TYayjbfOrFe8D}/_ssgManifest.js +0 -0
@@ -4,6 +4,21 @@
4
4
  //
5
5
  // Exposes a unified sync API for decisions and requirements storage.
6
6
  // Schema is initialized on first open with WAL mode for file-backed DBs.
7
+ //
8
+ // ─── Single-writer invariant ─────────────────────────────────────────────
9
+ // This file is the ONLY place in the codebase that issues write SQL
10
+ // (INSERT / UPDATE / DELETE / REPLACE / BEGIN-COMMIT transactions) against
11
+ // the engine database at `.gsd/gsd.db`. All other modules must call the
12
+ // typed wrappers exported here. The structural test
13
+ // `tests/single-writer-invariant.test.ts` fails CI if a new bypass appears.
14
+ //
15
+ // `_getAdapter()` is retained for read-only SELECTs in query modules
16
+ // (context-store, memory-store queries, doctor checks, projections).
17
+ // Do NOT use it for writes — add a wrapper here instead.
18
+ //
19
+ // The separate `.gsd/unit-claims.db` managed by `unit-ownership.ts` is an
20
+ // intentionally independent store for cross-worktree claim races and is
21
+ // excluded from this invariant.
7
22
 
8
23
  import { createRequire } from "node:module";
9
24
  import { existsSync, copyFileSync, mkdirSync, realpathSync } from "node:fs";
@@ -12,6 +27,10 @@ import type { Decision, Requirement, GateRow, GateId, GateScope, GateStatus, Gat
12
27
  import { GSDError, GSD_STALE_STATE } from "./errors.js";
13
28
  import { getGateIdsForTurn, type OwnerTurn } from "./gate-registry.js";
14
29
  import { logError, logWarning } from "./workflow-logger.js";
30
+ // Type-only import to avoid a circular runtime dep. The runtime side of
31
+ // workflow-manifest.ts depends on this file, but the StateManifest type is
32
+ // pure structure with no runtime coupling.
33
+ import type { StateManifest } from "./workflow-manifest.js";
15
34
 
16
35
  const _require = createRequire(import.meta.url);
17
36
 
@@ -35,8 +54,8 @@ let loadAttempted = false;
35
54
 
36
55
  function suppressSqliteWarning(): void {
37
56
  const origEmit = process.emit;
38
- // @ts-expect-error overriding process.emit for warning filter
39
- process.emit = function (event: string, ...args: unknown[]): boolean {
57
+ // Override via loose cast: Node's overloaded emit signature is not directly assignable.
58
+ (process as any).emit = function (event: string, ...args: unknown[]): boolean {
40
59
  if (
41
60
  event === "warning" &&
42
61
  args[0] &&
@@ -161,7 +180,7 @@ function openRawDb(path: string): unknown {
161
180
  return new Database(path);
162
181
  }
163
182
 
164
- const SCHEMA_VERSION = 14;
183
+ const SCHEMA_VERSION = 17;
165
184
 
166
185
  function indexExists(db: DbAdapter, name: string): boolean {
167
186
  return !!db.prepare(
@@ -216,6 +235,7 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
216
235
  rationale TEXT NOT NULL DEFAULT '',
217
236
  revisable TEXT NOT NULL DEFAULT '',
218
237
  made_by TEXT NOT NULL DEFAULT 'agent',
238
+ source TEXT NOT NULL DEFAULT 'discussion', -- ADR-011 P2: 'discussion' | 'planning' | 'escalation'
219
239
  superseded_by TEXT DEFAULT NULL
220
240
  )
221
241
  `);
@@ -315,6 +335,8 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
315
335
  observability_impact TEXT NOT NULL DEFAULT '',
316
336
  sequence INTEGER DEFAULT 0, -- Ordering hint: tools may set this to control execution order
317
337
  replan_triggered_at TEXT DEFAULT NULL,
338
+ is_sketch INTEGER NOT NULL DEFAULT 0, -- ADR-011: 1 = slice is a sketch awaiting refinement
339
+ sketch_scope TEXT NOT NULL DEFAULT '', -- ADR-011: 2-3 sentence rough scope from plan-milestone
318
340
  PRIMARY KEY (milestone_id, id),
319
341
  FOREIGN KEY (milestone_id) REFERENCES milestones(id)
320
342
  )
@@ -333,6 +355,11 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
333
355
  duration TEXT NOT NULL DEFAULT '',
334
356
  completed_at TEXT DEFAULT NULL,
335
357
  blocker_discovered INTEGER DEFAULT 0,
358
+ blocker_source TEXT NOT NULL DEFAULT '', -- ADR-011 P2: provenance for blocker_discovered (e.g. 'reject-escalation')
359
+ escalation_pending INTEGER NOT NULL DEFAULT 0, -- ADR-011 P2: pause-on-escalation flag
360
+ escalation_awaiting_review INTEGER NOT NULL DEFAULT 0, -- ADR-011 P2: artifact exists but continueWithDefault=true (no pause)
361
+ escalation_artifact_path TEXT DEFAULT NULL, -- ADR-011 P2: path to T##-ESCALATION.json
362
+ escalation_override_applied_at TEXT DEFAULT NULL, -- ADR-011 P2: DB claim lock for idempotent override injection
336
363
  deviations TEXT NOT NULL DEFAULT '',
337
364
  known_issues TEXT NOT NULL DEFAULT '',
338
365
  key_files TEXT NOT NULL DEFAULT '[]',
@@ -424,6 +451,70 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
424
451
  )
425
452
  `);
426
453
 
454
+ db.exec(`
455
+ CREATE TABLE IF NOT EXISTS gate_runs (
456
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
457
+ trace_id TEXT NOT NULL,
458
+ turn_id TEXT NOT NULL,
459
+ gate_id TEXT NOT NULL,
460
+ gate_type TEXT NOT NULL DEFAULT '',
461
+ unit_type TEXT DEFAULT NULL,
462
+ unit_id TEXT DEFAULT NULL,
463
+ milestone_id TEXT DEFAULT NULL,
464
+ slice_id TEXT DEFAULT NULL,
465
+ task_id TEXT DEFAULT NULL,
466
+ outcome TEXT NOT NULL DEFAULT 'pass',
467
+ failure_class TEXT NOT NULL DEFAULT 'none',
468
+ rationale TEXT NOT NULL DEFAULT '',
469
+ findings TEXT NOT NULL DEFAULT '',
470
+ attempt INTEGER NOT NULL DEFAULT 1,
471
+ max_attempts INTEGER NOT NULL DEFAULT 1,
472
+ retryable INTEGER NOT NULL DEFAULT 0,
473
+ evaluated_at TEXT NOT NULL DEFAULT ''
474
+ )
475
+ `);
476
+
477
+ db.exec(`
478
+ CREATE TABLE IF NOT EXISTS turn_git_transactions (
479
+ trace_id TEXT NOT NULL,
480
+ turn_id TEXT NOT NULL,
481
+ unit_type TEXT DEFAULT NULL,
482
+ unit_id TEXT DEFAULT NULL,
483
+ stage TEXT NOT NULL DEFAULT 'turn-start',
484
+ action TEXT NOT NULL DEFAULT 'status-only',
485
+ push INTEGER NOT NULL DEFAULT 0,
486
+ status TEXT NOT NULL DEFAULT 'ok',
487
+ error TEXT DEFAULT NULL,
488
+ metadata_json TEXT NOT NULL DEFAULT '{}',
489
+ updated_at TEXT NOT NULL DEFAULT '',
490
+ PRIMARY KEY (trace_id, turn_id, stage)
491
+ )
492
+ `);
493
+
494
+ db.exec(`
495
+ CREATE TABLE IF NOT EXISTS audit_events (
496
+ event_id TEXT PRIMARY KEY,
497
+ trace_id TEXT NOT NULL,
498
+ turn_id TEXT DEFAULT NULL,
499
+ caused_by TEXT DEFAULT NULL,
500
+ category TEXT NOT NULL,
501
+ type TEXT NOT NULL,
502
+ ts TEXT NOT NULL,
503
+ payload_json TEXT NOT NULL DEFAULT '{}'
504
+ )
505
+ `);
506
+
507
+ db.exec(`
508
+ CREATE TABLE IF NOT EXISTS audit_turn_index (
509
+ trace_id TEXT NOT NULL,
510
+ turn_id TEXT NOT NULL,
511
+ first_ts TEXT NOT NULL,
512
+ last_ts TEXT NOT NULL,
513
+ event_count INTEGER NOT NULL DEFAULT 0,
514
+ PRIMARY KEY (trace_id, turn_id)
515
+ )
516
+ `);
517
+
427
518
  db.exec("CREATE INDEX IF NOT EXISTS idx_memories_active ON memories(superseded_by)");
428
519
  db.exec("CREATE INDEX IF NOT EXISTS idx_replan_history_milestone ON replan_history(milestone_id, created_at)");
429
520
 
@@ -437,6 +528,14 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
437
528
 
438
529
  // v14 index — slice dependency lookups
439
530
  db.exec("CREATE INDEX IF NOT EXISTS idx_slice_deps_target ON slice_dependencies(milestone_id, depends_on_slice_id)");
531
+ db.exec("CREATE INDEX IF NOT EXISTS idx_gate_runs_turn ON gate_runs(trace_id, turn_id)");
532
+ db.exec("CREATE INDEX IF NOT EXISTS idx_gate_runs_lookup ON gate_runs(milestone_id, slice_id, task_id, gate_id)");
533
+ db.exec("CREATE INDEX IF NOT EXISTS idx_turn_git_tx_turn ON turn_git_transactions(trace_id, turn_id)");
534
+ db.exec("CREATE INDEX IF NOT EXISTS idx_audit_events_trace ON audit_events(trace_id, ts)");
535
+ db.exec("CREATE INDEX IF NOT EXISTS idx_audit_events_turn ON audit_events(trace_id, turn_id, ts)");
536
+ // ADR-011 Phase 2 — also created by the v17 migration; fresh installs
537
+ // skip migrations so the index must be created here too.
538
+ db.exec("CREATE INDEX IF NOT EXISTS idx_tasks_escalation_pending ON tasks(milestone_id, slice_id, escalation_pending)");
440
539
 
441
540
  db.exec(`CREATE VIEW IF NOT EXISTS active_decisions AS SELECT * FROM decisions WHERE superseded_by IS NULL`);
442
541
  db.exec(`CREATE VIEW IF NOT EXISTS active_requirements AS SELECT * FROM requirements WHERE superseded_by IS NULL`);
@@ -791,6 +890,104 @@ function migrateSchema(db: DbAdapter): void {
791
890
  });
792
891
  }
793
892
 
893
+ if (currentVersion < 15) {
894
+ db.exec(`
895
+ CREATE TABLE IF NOT EXISTS gate_runs (
896
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
897
+ trace_id TEXT NOT NULL,
898
+ turn_id TEXT NOT NULL,
899
+ gate_id TEXT NOT NULL,
900
+ gate_type TEXT NOT NULL DEFAULT '',
901
+ unit_type TEXT DEFAULT NULL,
902
+ unit_id TEXT DEFAULT NULL,
903
+ milestone_id TEXT DEFAULT NULL,
904
+ slice_id TEXT DEFAULT NULL,
905
+ task_id TEXT DEFAULT NULL,
906
+ outcome TEXT NOT NULL DEFAULT 'pass',
907
+ failure_class TEXT NOT NULL DEFAULT 'none',
908
+ rationale TEXT NOT NULL DEFAULT '',
909
+ findings TEXT NOT NULL DEFAULT '',
910
+ attempt INTEGER NOT NULL DEFAULT 1,
911
+ max_attempts INTEGER NOT NULL DEFAULT 1,
912
+ retryable INTEGER NOT NULL DEFAULT 0,
913
+ evaluated_at TEXT NOT NULL DEFAULT ''
914
+ )
915
+ `);
916
+ db.exec(`
917
+ CREATE TABLE IF NOT EXISTS turn_git_transactions (
918
+ trace_id TEXT NOT NULL,
919
+ turn_id TEXT NOT NULL,
920
+ unit_type TEXT DEFAULT NULL,
921
+ unit_id TEXT DEFAULT NULL,
922
+ stage TEXT NOT NULL DEFAULT 'turn-start',
923
+ action TEXT NOT NULL DEFAULT 'status-only',
924
+ push INTEGER NOT NULL DEFAULT 0,
925
+ status TEXT NOT NULL DEFAULT 'ok',
926
+ error TEXT DEFAULT NULL,
927
+ metadata_json TEXT NOT NULL DEFAULT '{}',
928
+ updated_at TEXT NOT NULL DEFAULT '',
929
+ PRIMARY KEY (trace_id, turn_id, stage)
930
+ )
931
+ `);
932
+ db.exec(`
933
+ CREATE TABLE IF NOT EXISTS audit_events (
934
+ event_id TEXT PRIMARY KEY,
935
+ trace_id TEXT NOT NULL,
936
+ turn_id TEXT DEFAULT NULL,
937
+ caused_by TEXT DEFAULT NULL,
938
+ category TEXT NOT NULL,
939
+ type TEXT NOT NULL,
940
+ ts TEXT NOT NULL,
941
+ payload_json TEXT NOT NULL DEFAULT '{}'
942
+ )
943
+ `);
944
+ db.exec(`
945
+ CREATE TABLE IF NOT EXISTS audit_turn_index (
946
+ trace_id TEXT NOT NULL,
947
+ turn_id TEXT NOT NULL,
948
+ first_ts TEXT NOT NULL,
949
+ last_ts TEXT NOT NULL,
950
+ event_count INTEGER NOT NULL DEFAULT 0,
951
+ PRIMARY KEY (trace_id, turn_id)
952
+ )
953
+ `);
954
+ db.exec("CREATE INDEX IF NOT EXISTS idx_gate_runs_turn ON gate_runs(trace_id, turn_id)");
955
+ db.exec("CREATE INDEX IF NOT EXISTS idx_gate_runs_lookup ON gate_runs(milestone_id, slice_id, task_id, gate_id)");
956
+ db.exec("CREATE INDEX IF NOT EXISTS idx_turn_git_tx_turn ON turn_git_transactions(trace_id, turn_id)");
957
+ db.exec("CREATE INDEX IF NOT EXISTS idx_audit_events_trace ON audit_events(trace_id, ts)");
958
+ db.exec("CREATE INDEX IF NOT EXISTS idx_audit_events_turn ON audit_events(trace_id, turn_id, ts)");
959
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
960
+ ":version": 15,
961
+ ":applied_at": new Date().toISOString(),
962
+ });
963
+ }
964
+
965
+ if (currentVersion < 16) {
966
+ // ADR-011 Phase 1: sketch-then-refine progressive planning — sketch columns on slices.
967
+ ensureColumn(db, "slices", "is_sketch", `ALTER TABLE slices ADD COLUMN is_sketch INTEGER NOT NULL DEFAULT 0`);
968
+ ensureColumn(db, "slices", "sketch_scope", `ALTER TABLE slices ADD COLUMN sketch_scope TEXT NOT NULL DEFAULT ''`);
969
+ // ADR-011 Phase 2: decisions can now be sourced from escalation resolutions.
970
+ ensureColumn(db, "decisions", "source", `ALTER TABLE decisions ADD COLUMN source TEXT NOT NULL DEFAULT 'discussion'`);
971
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
972
+ ":version": 16,
973
+ ":applied_at": new Date().toISOString(),
974
+ });
975
+ }
976
+
977
+ if (currentVersion < 17) {
978
+ // ADR-011 Phase 2: mid-execution escalation — columns on the tasks table.
979
+ ensureColumn(db, "tasks", "blocker_source", `ALTER TABLE tasks ADD COLUMN blocker_source TEXT NOT NULL DEFAULT ''`);
980
+ ensureColumn(db, "tasks", "escalation_pending", `ALTER TABLE tasks ADD COLUMN escalation_pending INTEGER NOT NULL DEFAULT 0`);
981
+ ensureColumn(db, "tasks", "escalation_awaiting_review", `ALTER TABLE tasks ADD COLUMN escalation_awaiting_review INTEGER NOT NULL DEFAULT 0`);
982
+ ensureColumn(db, "tasks", "escalation_artifact_path", `ALTER TABLE tasks ADD COLUMN escalation_artifact_path TEXT DEFAULT NULL`);
983
+ ensureColumn(db, "tasks", "escalation_override_applied_at", `ALTER TABLE tasks ADD COLUMN escalation_override_applied_at TEXT DEFAULT NULL`);
984
+ db.exec("CREATE INDEX IF NOT EXISTS idx_tasks_escalation_pending ON tasks(milestone_id, slice_id, escalation_pending)");
985
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
986
+ ":version": 17,
987
+ ":applied_at": new Date().toISOString(),
988
+ });
989
+ }
990
+
794
991
  db.exec("COMMIT");
795
992
  } catch (err) {
796
993
  db.exec("ROLLBACK");
@@ -892,6 +1089,14 @@ export function vacuumDatabase(): void {
892
1089
  } catch (e) { logWarning("db", `VACUUM failed: ${(e as Error).message}`); }
893
1090
  }
894
1091
 
1092
+ /** Flush WAL into gsd.db so `git add .gsd/gsd.db` stages current state — safe while DB is open. */
1093
+ export function checkpointDatabase(): void {
1094
+ if (!currentDb) return;
1095
+ try {
1096
+ currentDb.exec('PRAGMA wal_checkpoint(TRUNCATE)');
1097
+ } catch (e) { logWarning("db", `WAL checkpoint failed: ${(e as Error).message}`); }
1098
+ }
1099
+
895
1100
  let _txDepth = 0;
896
1101
 
897
1102
  export function transaction<T>(fn: () => T): T {
@@ -922,11 +1127,53 @@ export function transaction<T>(fn: () => T): T {
922
1127
  }
923
1128
  }
924
1129
 
1130
+ /**
1131
+ * Wrap a block of reads in a DEFERRED transaction so that all SELECTs observe
1132
+ * a consistent snapshot of the DB even if a concurrent writer commits between
1133
+ * them. Use this for multi-query read flows (e.g. tool executors that query
1134
+ * milestone + slices + counts and want one snapshot). Re-entrant — if already
1135
+ * inside a transaction, runs fn() without starting a nested one.
1136
+ */
1137
+ export function readTransaction<T>(fn: () => T): T {
1138
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1139
+
1140
+ if (_txDepth > 0) {
1141
+ _txDepth++;
1142
+ try {
1143
+ return fn();
1144
+ } finally {
1145
+ _txDepth--;
1146
+ }
1147
+ }
1148
+
1149
+ _txDepth++;
1150
+ currentDb.exec("BEGIN DEFERRED");
1151
+ try {
1152
+ const result = fn();
1153
+ currentDb.exec("COMMIT");
1154
+ return result;
1155
+ } catch (err) {
1156
+ try {
1157
+ currentDb.exec("ROLLBACK");
1158
+ } catch (rollbackErr) {
1159
+ // A failed ROLLBACK after a failed read is a split-brain signal —
1160
+ // the transaction is in an indeterminate state. Surface it via the
1161
+ // logger instead of swallowing it.
1162
+ logError("db", "snapshotState ROLLBACK failed", {
1163
+ error: (rollbackErr as Error).message,
1164
+ });
1165
+ }
1166
+ throw err;
1167
+ } finally {
1168
+ _txDepth--;
1169
+ }
1170
+ }
1171
+
925
1172
  export function insertDecision(d: Omit<Decision, "seq">): void {
926
1173
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
927
1174
  currentDb.prepare(
928
- `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by)
929
- VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :superseded_by)`,
1175
+ `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by)
1176
+ VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :source, :superseded_by)`,
930
1177
  ).run({
931
1178
  ":id": d.id,
932
1179
  ":when_context": d.when_context,
@@ -936,6 +1183,7 @@ export function insertDecision(d: Omit<Decision, "seq">): void {
936
1183
  ":rationale": d.rationale,
937
1184
  ":revisable": d.revisable,
938
1185
  ":made_by": d.made_by ?? "agent",
1186
+ ":source": d.source ?? "discussion",
939
1187
  ":superseded_by": d.superseded_by,
940
1188
  });
941
1189
  }
@@ -954,6 +1202,7 @@ export function getDecisionById(id: string): Decision | null {
954
1202
  rationale: row["rationale"] as string,
955
1203
  revisable: row["revisable"] as string,
956
1204
  made_by: (row["made_by"] as string as import("./types.js").DecisionMadeBy) ?? "agent",
1205
+ source: (row["source"] as string) ?? "discussion",
957
1206
  superseded_by: (row["superseded_by"] as string) ?? null,
958
1207
  };
959
1208
  }
@@ -971,6 +1220,7 @@ export function getActiveDecisions(): Decision[] {
971
1220
  rationale: row["rationale"] as string,
972
1221
  revisable: row["revisable"] as string,
973
1222
  made_by: (row["made_by"] as string as import("./types.js").DecisionMadeBy) ?? "agent",
1223
+ source: (row["source"] as string) ?? "discussion",
974
1224
  superseded_by: null,
975
1225
  }));
976
1226
  }
@@ -1059,8 +1309,8 @@ export function upsertDecision(d: Omit<Decision, "seq">): void {
1059
1309
  // seq column. INSERT OR REPLACE deletes then reinserts, resetting seq and
1060
1310
  // corrupting decision ordering in DECISIONS.md after reconcile replay.
1061
1311
  currentDb.prepare(
1062
- `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by)
1063
- VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :superseded_by)
1312
+ `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by)
1313
+ VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :source, :superseded_by)
1064
1314
  ON CONFLICT(id) DO UPDATE SET
1065
1315
  when_context = excluded.when_context,
1066
1316
  scope = excluded.scope,
@@ -1069,6 +1319,7 @@ export function upsertDecision(d: Omit<Decision, "seq">): void {
1069
1319
  rationale = excluded.rationale,
1070
1320
  revisable = excluded.revisable,
1071
1321
  made_by = excluded.made_by,
1322
+ source = excluded.source,
1072
1323
  superseded_by = excluded.superseded_by`,
1073
1324
  ).run({
1074
1325
  ":id": d.id,
@@ -1079,6 +1330,7 @@ export function upsertDecision(d: Omit<Decision, "seq">): void {
1079
1330
  ":rationale": d.rationale,
1080
1331
  ":revisable": d.revisable,
1081
1332
  ":made_by": d.made_by ?? "agent",
1333
+ ":source": d.source ?? "discussion",
1082
1334
  ":superseded_by": d.superseded_by ?? null,
1083
1335
  });
1084
1336
  }
@@ -1253,16 +1505,20 @@ export function insertSlice(s: {
1253
1505
  depends?: string[];
1254
1506
  demo?: string;
1255
1507
  sequence?: number;
1508
+ isSketch?: boolean;
1509
+ sketchScope?: string;
1256
1510
  planning?: Partial<SlicePlanningRecord>;
1257
1511
  }): void {
1258
1512
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1259
1513
  currentDb.prepare(
1260
1514
  `INSERT INTO slices (
1261
1515
  milestone_id, id, title, status, risk, depends, demo, created_at,
1262
- goal, success_criteria, proof_level, integration_closure, observability_impact, sequence
1516
+ goal, success_criteria, proof_level, integration_closure, observability_impact, sequence,
1517
+ is_sketch, sketch_scope
1263
1518
  ) VALUES (
1264
1519
  :milestone_id, :id, :title, :status, :risk, :depends, :demo, :created_at,
1265
- :goal, :success_criteria, :proof_level, :integration_closure, :observability_impact, :sequence
1520
+ :goal, :success_criteria, :proof_level, :integration_closure, :observability_impact, :sequence,
1521
+ :is_sketch, :sketch_scope
1266
1522
  )
1267
1523
  ON CONFLICT (milestone_id, id) DO UPDATE SET
1268
1524
  title = CASE WHEN :raw_title IS NOT NULL THEN excluded.title ELSE slices.title END,
@@ -1275,7 +1531,9 @@ export function insertSlice(s: {
1275
1531
  proof_level = CASE WHEN :raw_proof_level IS NOT NULL THEN excluded.proof_level ELSE slices.proof_level END,
1276
1532
  integration_closure = CASE WHEN :raw_integration_closure IS NOT NULL THEN excluded.integration_closure ELSE slices.integration_closure END,
1277
1533
  observability_impact = CASE WHEN :raw_observability_impact IS NOT NULL THEN excluded.observability_impact ELSE slices.observability_impact END,
1278
- sequence = CASE WHEN :raw_sequence IS NOT NULL THEN excluded.sequence ELSE slices.sequence END`,
1534
+ sequence = CASE WHEN :raw_sequence IS NOT NULL THEN excluded.sequence ELSE slices.sequence END,
1535
+ is_sketch = CASE WHEN :raw_is_sketch IS NOT NULL THEN excluded.is_sketch ELSE slices.is_sketch END,
1536
+ sketch_scope = CASE WHEN :raw_sketch_scope IS NOT NULL THEN excluded.sketch_scope ELSE slices.sketch_scope END`,
1279
1537
  ).run({
1280
1538
  ":milestone_id": s.milestoneId,
1281
1539
  ":id": s.id,
@@ -1291,6 +1549,8 @@ export function insertSlice(s: {
1291
1549
  ":integration_closure": s.planning?.integrationClosure ?? "",
1292
1550
  ":observability_impact": s.planning?.observabilityImpact ?? "",
1293
1551
  ":sequence": s.sequence ?? 0,
1552
+ ":is_sketch": s.isSketch ? 1 : 0,
1553
+ ":sketch_scope": s.sketchScope ?? "",
1294
1554
  // Raw sentinel params: NULL when caller omitted the field, used in ON CONFLICT guards
1295
1555
  ":raw_title": s.title ?? null,
1296
1556
  ":raw_risk": s.risk ?? null,
@@ -1301,9 +1561,52 @@ export function insertSlice(s: {
1301
1561
  ":raw_integration_closure": s.planning?.integrationClosure ?? null,
1302
1562
  ":raw_observability_impact": s.planning?.observabilityImpact ?? null,
1303
1563
  ":raw_sequence": s.sequence ?? null,
1564
+ ":raw_is_sketch": s.isSketch === undefined ? null : (s.isSketch ? 1 : 0),
1565
+ // NOTE: use !== undefined (not ??) so an explicit empty string "" is treated
1566
+ // as a present value and correctly clears the existing sketch_scope on
1567
+ // CONFLICT. ?? would incorrectly preserve the stale value.
1568
+ ":raw_sketch_scope": s.sketchScope !== undefined ? s.sketchScope : null,
1304
1569
  });
1305
1570
  }
1306
1571
 
1572
+ // ADR-011: sketch-then-refine helpers
1573
+ export function setSliceSketchFlag(milestoneId: string, sliceId: string, isSketch: boolean): void {
1574
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1575
+ currentDb.prepare(
1576
+ `UPDATE slices SET is_sketch = :is_sketch WHERE milestone_id = :mid AND id = :sid`,
1577
+ ).run({ ":is_sketch": isSketch ? 1 : 0, ":mid": milestoneId, ":sid": sliceId });
1578
+ }
1579
+
1580
+ /**
1581
+ * ADR-011 auto-heal: reconcile stale is_sketch=1 rows whose PLAN already exists.
1582
+ *
1583
+ * Callers pass a predicate that resolves whether a plan file exists for a slice.
1584
+ * The predicate MUST use the canonical path resolver (`resolveSliceFile`, etc.)
1585
+ * to keep path logic in one place — do not hand-roll the path inside the callback.
1586
+ *
1587
+ * Recovers from two scenarios:
1588
+ * 1. Crash between `gsd_plan_slice` write and the sketch flag flip.
1589
+ * 2. Flag-OFF downgrade path: when `progressive_planning` is off, the dispatch
1590
+ * rule routes sketch slices to plan-slice, which writes PLAN.md but leaves
1591
+ * `is_sketch=1` — the next state derivation auto-heals it to 0 here.
1592
+ *
1593
+ * Not aggressive in practice: PLAN.md is only written via the DB-backed
1594
+ * `gsd_plan_slice` tool (which also inserts tasks), so a "stale PLAN.md with
1595
+ * is_sketch=1" is extremely unlikely to indicate anything other than the two
1596
+ * recovery scenarios above.
1597
+ */
1598
+ export function autoHealSketchFlags(milestoneId: string, hasPlanFile: (sliceId: string) => boolean): void {
1599
+ if (!currentDb) return;
1600
+ const rows = currentDb.prepare(
1601
+ `SELECT id FROM slices WHERE milestone_id = :mid AND is_sketch = 1`,
1602
+ ).all({ ":mid": milestoneId }) as Array<{ id: string }>;
1603
+ for (const row of rows) {
1604
+ if (hasPlanFile(row.id)) {
1605
+ setSliceSketchFlag(milestoneId, row.id, false);
1606
+ }
1607
+ }
1608
+ }
1609
+
1307
1610
  export function upsertSlicePlanning(milestoneId: string, sliceId: string, planning: Partial<SlicePlanningRecord>): void {
1308
1611
  if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1309
1612
  currentDb.prepare(
@@ -1477,6 +1780,8 @@ export interface SliceRow {
1477
1780
  observability_impact: string;
1478
1781
  sequence: number;
1479
1782
  replan_triggered_at: string | null;
1783
+ is_sketch: number;
1784
+ sketch_scope: string;
1480
1785
  }
1481
1786
 
1482
1787
  function rowToSlice(row: Record<string, unknown>): SliceRow {
@@ -1499,6 +1804,8 @@ function rowToSlice(row: Record<string, unknown>): SliceRow {
1499
1804
  observability_impact: (row["observability_impact"] as string) ?? "",
1500
1805
  sequence: (row["sequence"] as number) ?? 0,
1501
1806
  replan_triggered_at: (row["replan_triggered_at"] as string) ?? null,
1807
+ is_sketch: (row["is_sketch"] as number) ?? 0,
1808
+ sketch_scope: (row["sketch_scope"] as string) ?? "",
1502
1809
  };
1503
1810
  }
1504
1811
 
@@ -1562,6 +1869,12 @@ export interface TaskRow {
1562
1869
  observability_impact: string;
1563
1870
  full_plan_md: string;
1564
1871
  sequence: number;
1872
+ // ADR-011 Phase 2 escalation fields
1873
+ blocker_source: string;
1874
+ escalation_pending: number;
1875
+ escalation_awaiting_review: number;
1876
+ escalation_artifact_path: string | null;
1877
+ escalation_override_applied_at: string | null;
1565
1878
  }
1566
1879
 
1567
1880
  function parseTaskArrayColumn(raw: unknown): string[] {
@@ -1632,6 +1945,11 @@ function rowToTask(row: Record<string, unknown>): TaskRow {
1632
1945
  observability_impact: (row["observability_impact"] as string) ?? "",
1633
1946
  full_plan_md: (row["full_plan_md"] as string) ?? "",
1634
1947
  sequence: (row["sequence"] as number) ?? 0,
1948
+ blocker_source: (row["blocker_source"] as string) ?? "",
1949
+ escalation_pending: (row["escalation_pending"] as number) ?? 0,
1950
+ escalation_awaiting_review: (row["escalation_awaiting_review"] as number) ?? 0,
1951
+ escalation_artifact_path: (row["escalation_artifact_path"] as string) ?? null,
1952
+ escalation_override_applied_at: (row["escalation_override_applied_at"] as string) ?? null,
1635
1953
  };
1636
1954
  }
1637
1955
 
@@ -1652,6 +1970,125 @@ export function getSliceTasks(milestoneId: string, sliceId: string): TaskRow[] {
1652
1970
  return rows.map(rowToTask);
1653
1971
  }
1654
1972
 
1973
+ // ─── ADR-011 Phase 2 escalation helpers ──────────────────────────────────
1974
+
1975
+ /** Set pause-on-escalation state on a completed task. Mutually exclusive with awaiting_review. */
1976
+ export function setTaskEscalationPending(
1977
+ milestoneId: string, sliceId: string, taskId: string,
1978
+ artifactPath: string,
1979
+ ): void {
1980
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1981
+ currentDb.prepare(
1982
+ `UPDATE tasks
1983
+ SET escalation_pending = 1,
1984
+ escalation_awaiting_review = 0,
1985
+ escalation_artifact_path = :path
1986
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
1987
+ ).run({ ":path": artifactPath, ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1988
+ }
1989
+
1990
+ /** Set awaiting-review state (artifact exists but continueWithDefault=true, no pause). Mutually exclusive with pending. */
1991
+ export function setTaskEscalationAwaitingReview(
1992
+ milestoneId: string, sliceId: string, taskId: string,
1993
+ artifactPath: string,
1994
+ ): void {
1995
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
1996
+ currentDb.prepare(
1997
+ `UPDATE tasks
1998
+ SET escalation_awaiting_review = 1,
1999
+ escalation_pending = 0,
2000
+ escalation_artifact_path = :path
2001
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
2002
+ ).run({ ":path": artifactPath, ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
2003
+ }
2004
+
2005
+ /** Clear escalation-pending and awaiting-review flags once the user has resolved it. */
2006
+ export function clearTaskEscalationFlags(
2007
+ milestoneId: string, sliceId: string, taskId: string,
2008
+ ): void {
2009
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
2010
+ currentDb.prepare(
2011
+ `UPDATE tasks
2012
+ SET escalation_pending = 0,
2013
+ escalation_awaiting_review = 0
2014
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
2015
+ ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
2016
+ }
2017
+
2018
+ /**
2019
+ * Atomically claim a resolved escalation override for injection into a downstream
2020
+ * task's prompt. Returns true if this caller claimed it (must inject), false if
2021
+ * another caller already claimed it (must skip).
2022
+ */
2023
+ export function claimEscalationOverride(
2024
+ milestoneId: string, sliceId: string, sourceTaskId: string,
2025
+ ): boolean {
2026
+ if (!currentDb) return false;
2027
+ const now = new Date().toISOString();
2028
+ const result = currentDb.prepare(
2029
+ `UPDATE tasks
2030
+ SET escalation_override_applied_at = :now
2031
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid
2032
+ AND escalation_override_applied_at IS NULL
2033
+ AND escalation_artifact_path IS NOT NULL`,
2034
+ ).run({ ":now": now, ":mid": milestoneId, ":sid": sliceId, ":tid": sourceTaskId });
2035
+ // node:sqlite + better-sqlite3 both surface `changes` on the run result.
2036
+ const changes = (result as { changes?: number }).changes ?? 0;
2037
+ return changes > 0;
2038
+ }
2039
+
2040
+ /** Find the most recent resolved-but-unapplied escalation override in a slice. */
2041
+ export function findUnappliedEscalationOverride(
2042
+ milestoneId: string, sliceId: string,
2043
+ ): { taskId: string; artifactPath: string } | null {
2044
+ if (!currentDb) return null;
2045
+ // Filter BOTH flags: escalation_pending=0 AND escalation_awaiting_review=0
2046
+ // ensures we only claim overrides the user has explicitly resolved.
2047
+ // Without the awaiting_review filter, continueWithDefault=true artifacts
2048
+ // (not yet responded to) would be prematurely claimed, causing the override
2049
+ // to be lost when the user later resolves (#ADR-011 Phase 2 peer-review Bug 2).
2050
+ const row = currentDb.prepare(
2051
+ `SELECT id, escalation_artifact_path AS path
2052
+ FROM tasks
2053
+ WHERE milestone_id = :mid AND slice_id = :sid
2054
+ AND escalation_artifact_path IS NOT NULL
2055
+ AND escalation_override_applied_at IS NULL
2056
+ AND escalation_pending = 0
2057
+ AND escalation_awaiting_review = 0
2058
+ ORDER BY sequence DESC, id DESC
2059
+ LIMIT 1`,
2060
+ ).get({ ":mid": milestoneId, ":sid": sliceId }) as
2061
+ | { id: string; path: string | null }
2062
+ | undefined;
2063
+ if (!row || !row.path) return null;
2064
+ return { taskId: row.id, artifactPath: row.path };
2065
+ }
2066
+
2067
+ /** Set the blocker_source provenance field (used when rejecting an escalation). */
2068
+ export function setTaskBlockerSource(
2069
+ milestoneId: string, sliceId: string, taskId: string, source: string,
2070
+ ): void {
2071
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
2072
+ currentDb.prepare(
2073
+ `UPDATE tasks
2074
+ SET blocker_discovered = 1,
2075
+ blocker_source = :src
2076
+ WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
2077
+ ).run({ ":src": source, ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
2078
+ }
2079
+
2080
+ /** List tasks with active escalation artifacts across a milestone (for /gsd escalate list). */
2081
+ export function listEscalationArtifacts(milestoneId: string, includeResolved: boolean = false): TaskRow[] {
2082
+ if (!currentDb) return [];
2083
+ const filter = includeResolved
2084
+ ? "escalation_artifact_path IS NOT NULL"
2085
+ : "(escalation_pending = 1 OR escalation_awaiting_review = 1) AND escalation_artifact_path IS NOT NULL";
2086
+ const rows = currentDb.prepare(
2087
+ `SELECT * FROM tasks WHERE milestone_id = :mid AND ${filter} ORDER BY slice_id, sequence, id`,
2088
+ ).all({ ":mid": milestoneId });
2089
+ return rows.map(rowToTask);
2090
+ }
2091
+
1655
2092
  export function insertVerificationEvidence(e: {
1656
2093
  taskId: string;
1657
2094
  sliceId: string;
@@ -1965,6 +2402,19 @@ export function reconcileWorktreeDb(
1965
2402
  try {
1966
2403
  const wtInfo = adapter.prepare("PRAGMA wt.table_info('decisions')").all();
1967
2404
  const hasMadeBy = wtInfo.some((col) => col["name"] === "made_by");
2405
+ // ADR-011: worktree may predate schema v16/v17. For missing columns we
2406
+ // fall through to the main DB's existing value (not a literal default)
2407
+ // so reconcile never silently clears state the main tree has recorded.
2408
+ const hasDecisionSource = wtInfo.some((col) => col["name"] === "source");
2409
+ const wtSliceInfo = adapter.prepare("PRAGMA wt.table_info('slices')").all();
2410
+ const hasIsSketch = wtSliceInfo.some((col) => col["name"] === "is_sketch");
2411
+ const hasSketchScope = wtSliceInfo.some((col) => col["name"] === "sketch_scope");
2412
+ const wtTaskInfo = adapter.prepare("PRAGMA wt.table_info('tasks')").all();
2413
+ const hasBlockerSource = wtTaskInfo.some((col) => col["name"] === "blocker_source");
2414
+ const hasEscalationPending = wtTaskInfo.some((col) => col["name"] === "escalation_pending");
2415
+ const hasEscalationAwaiting = wtTaskInfo.some((col) => col["name"] === "escalation_awaiting_review");
2416
+ const hasEscalationArtifact = wtTaskInfo.some((col) => col["name"] === "escalation_artifact_path");
2417
+ const hasEscalationOverride = wtTaskInfo.some((col) => col["name"] === "escalation_override_applied_at");
1968
2418
 
1969
2419
  const decConf = adapter.prepare(
1970
2420
  `SELECT m.id FROM decisions m INNER JOIN wt.decisions w ON m.id = w.id WHERE m.decision != w.decision OR m.choice != w.choice OR m.rationale != w.rationale OR ${
@@ -1986,13 +2436,20 @@ export function reconcileWorktreeDb(
1986
2436
 
1987
2437
  adapter.exec("BEGIN");
1988
2438
  try {
2439
+ // Join the target decisions so we can prefer an existing main.source
2440
+ // when the worktree predates v16 — otherwise a write-through reconcile
2441
+ // would clobber 'escalation'-sourced decisions with the literal default.
1989
2442
  merged.decisions = countChanges(adapter.prepare(`
1990
2443
  INSERT OR REPLACE INTO decisions (
1991
- id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by
2444
+ id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by
1992
2445
  )
1993
- SELECT id, when_context, scope, decision, choice, rationale, revisable, ${
1994
- hasMadeBy ? "made_by" : "'agent'"
1995
- }, superseded_by FROM wt.decisions
2446
+ SELECT w.id, w.when_context, w.scope, w.decision, w.choice, w.rationale, w.revisable, ${
2447
+ hasMadeBy ? "w.made_by" : "COALESCE(m.made_by, 'agent')"
2448
+ }, ${
2449
+ hasDecisionSource ? "w.source" : "COALESCE(m.source, 'discussion')"
2450
+ }, w.superseded_by
2451
+ FROM wt.decisions w
2452
+ LEFT JOIN decisions m ON m.id = w.id
1996
2453
  `).run());
1997
2454
 
1998
2455
  merged.requirements = countChanges(adapter.prepare(`
@@ -2029,13 +2486,15 @@ export function reconcileWorktreeDb(
2029
2486
  `).run());
2030
2487
 
2031
2488
  // Merge slices — preserve worktree progress but never downgrade completed status (#2558).
2032
- // Uses INSERT OR REPLACE with a subquery that picks the best status — if the main DB
2033
- // already has a completed slice, keep that status even if the worktree copy is stale.
2489
+ // ADR-011 Phase 1: carry is_sketch + sketch_scope so reconcile doesn't
2490
+ // silently clear sketch metadata. When the worktree predates v16,
2491
+ // fall back to the main DB's existing value rather than a literal 0/''.
2034
2492
  merged.slices = countChanges(adapter.prepare(`
2035
2493
  INSERT OR REPLACE INTO slices (
2036
2494
  milestone_id, id, title, status, risk, depends, demo, created_at, completed_at,
2037
2495
  full_summary_md, full_uat_md, goal, success_criteria, proof_level,
2038
- integration_closure, observability_impact, sequence, replan_triggered_at
2496
+ integration_closure, observability_impact, sequence, replan_triggered_at,
2497
+ is_sketch, sketch_scope
2039
2498
  )
2040
2499
  SELECT w.milestone_id, w.id, w.title,
2041
2500
  CASE
@@ -2048,19 +2507,25 @@ export function reconcileWorktreeDb(
2048
2507
  THEN m.completed_at ELSE w.completed_at
2049
2508
  END,
2050
2509
  w.full_summary_md, w.full_uat_md, w.goal, w.success_criteria, w.proof_level,
2051
- w.integration_closure, w.observability_impact, w.sequence, w.replan_triggered_at
2510
+ w.integration_closure, w.observability_impact, w.sequence, w.replan_triggered_at,
2511
+ ${hasIsSketch ? "w.is_sketch" : "COALESCE(m.is_sketch, 0)"},
2512
+ ${hasSketchScope ? "w.sketch_scope" : "COALESCE(m.sketch_scope, '')"}
2052
2513
  FROM wt.slices w
2053
2514
  LEFT JOIN slices m ON m.milestone_id = w.milestone_id AND m.id = w.id
2054
2515
  `).run());
2055
2516
 
2056
- // Merge tasks — preserve execution results, never downgrade completed status (#2558)
2517
+ // Merge tasks — preserve execution results, never downgrade completed status (#2558).
2518
+ // ADR-011 P2: carry blocker_source + escalation_* columns so worktree reconcile
2519
+ // doesn't silently clear escalation state back to defaults.
2057
2520
  merged.tasks = countChanges(adapter.prepare(`
2058
2521
  INSERT OR REPLACE INTO tasks (
2059
2522
  milestone_id, slice_id, id, title, status, one_liner, narrative,
2060
2523
  verification_result, duration, completed_at, blocker_discovered,
2061
2524
  deviations, known_issues, key_files, key_decisions, full_summary_md,
2062
2525
  description, estimate, files, verify, inputs, expected_output,
2063
- observability_impact, full_plan_md, sequence
2526
+ observability_impact, full_plan_md, sequence,
2527
+ blocker_source, escalation_pending, escalation_awaiting_review,
2528
+ escalation_artifact_path, escalation_override_applied_at
2064
2529
  )
2065
2530
  SELECT w.milestone_id, w.slice_id, w.id, w.title,
2066
2531
  CASE
@@ -2076,7 +2541,12 @@ export function reconcileWorktreeDb(
2076
2541
  w.blocker_discovered,
2077
2542
  w.deviations, w.known_issues, w.key_files, w.key_decisions, w.full_summary_md,
2078
2543
  w.description, w.estimate, w.files, w.verify, w.inputs, w.expected_output,
2079
- w.observability_impact, w.full_plan_md, w.sequence
2544
+ w.observability_impact, w.full_plan_md, w.sequence,
2545
+ ${hasBlockerSource ? "w.blocker_source" : "COALESCE(m.blocker_source, '')"},
2546
+ ${hasEscalationPending ? "w.escalation_pending" : "COALESCE(m.escalation_pending, 0)"},
2547
+ ${hasEscalationAwaiting ? "w.escalation_awaiting_review" : "COALESCE(m.escalation_awaiting_review, 0)"},
2548
+ ${hasEscalationArtifact ? "w.escalation_artifact_path" : "m.escalation_artifact_path"},
2549
+ ${hasEscalationOverride ? "w.escalation_override_applied_at" : "m.escalation_override_applied_at"}
2080
2550
  FROM wt.tasks w
2081
2551
  LEFT JOIN tasks m ON m.milestone_id = w.milestone_id AND m.slice_id = w.slice_id AND m.id = w.id
2082
2552
  `).run());
@@ -2226,6 +2696,9 @@ export function deleteMilestone(milestoneId: string): void {
2226
2696
  currentDb!.prepare(
2227
2697
  `DELETE FROM quality_gates WHERE milestone_id = :mid`,
2228
2698
  ).run({ ":mid": milestoneId });
2699
+ currentDb!.prepare(
2700
+ `DELETE FROM gate_runs WHERE milestone_id = :mid`,
2701
+ ).run({ ":mid": milestoneId });
2229
2702
  currentDb!.prepare(
2230
2703
  `DELETE FROM tasks WHERE milestone_id = :mid`,
2231
2704
  ).run({ ":mid": milestoneId });
@@ -2359,6 +2832,30 @@ export function saveGateResult(g: {
2359
2832
  ":findings": g.findings,
2360
2833
  ":evaluated_at": new Date().toISOString(),
2361
2834
  });
2835
+
2836
+ const outcome =
2837
+ g.verdict === "pass"
2838
+ ? "pass"
2839
+ : g.verdict === "omitted"
2840
+ ? "manual-attention"
2841
+ : "fail";
2842
+ insertGateRun({
2843
+ traceId: `quality-gate:${g.milestoneId}:${g.sliceId}`,
2844
+ turnId: `gate:${g.gateId}:${g.taskId ?? "slice"}`,
2845
+ gateId: g.gateId,
2846
+ gateType: "quality-gate",
2847
+ milestoneId: g.milestoneId,
2848
+ sliceId: g.sliceId,
2849
+ taskId: g.taskId ?? undefined,
2850
+ outcome,
2851
+ failureClass: outcome === "fail" ? "verification" : outcome === "manual-attention" ? "manual-attention" : "none",
2852
+ rationale: g.rationale,
2853
+ findings: g.findings,
2854
+ attempt: 1,
2855
+ maxAttempts: 1,
2856
+ retryable: false,
2857
+ evaluatedAt: new Date().toISOString(),
2858
+ });
2362
2859
  }
2363
2860
 
2364
2861
  export function getPendingGates(milestoneId: string, sliceId: string, scope?: GateScope): GateRow[] {
@@ -2451,3 +2948,568 @@ export function getPendingGateCountForTurn(
2451
2948
  ): number {
2452
2949
  return getPendingGatesForTurn(milestoneId, sliceId, turn).length;
2453
2950
  }
2951
+
2952
+ export function insertGateRun(entry: {
2953
+ traceId: string;
2954
+ turnId: string;
2955
+ gateId: string;
2956
+ gateType: string;
2957
+ unitType?: string;
2958
+ unitId?: string;
2959
+ milestoneId?: string;
2960
+ sliceId?: string;
2961
+ taskId?: string;
2962
+ outcome: "pass" | "fail" | "retry" | "manual-attention";
2963
+ failureClass: "none" | "policy" | "input" | "execution" | "artifact" | "verification" | "closeout" | "git" | "timeout" | "manual-attention" | "unknown";
2964
+ rationale?: string;
2965
+ findings?: string;
2966
+ attempt: number;
2967
+ maxAttempts: number;
2968
+ retryable: boolean;
2969
+ evaluatedAt: string;
2970
+ }): void {
2971
+ if (!currentDb) return;
2972
+ currentDb.prepare(
2973
+ `INSERT INTO gate_runs (
2974
+ trace_id, turn_id, gate_id, gate_type, unit_type, unit_id, milestone_id, slice_id, task_id,
2975
+ outcome, failure_class, rationale, findings, attempt, max_attempts, retryable, evaluated_at
2976
+ ) VALUES (
2977
+ :trace_id, :turn_id, :gate_id, :gate_type, :unit_type, :unit_id, :milestone_id, :slice_id, :task_id,
2978
+ :outcome, :failure_class, :rationale, :findings, :attempt, :max_attempts, :retryable, :evaluated_at
2979
+ )`,
2980
+ ).run({
2981
+ ":trace_id": entry.traceId,
2982
+ ":turn_id": entry.turnId,
2983
+ ":gate_id": entry.gateId,
2984
+ ":gate_type": entry.gateType,
2985
+ ":unit_type": entry.unitType ?? null,
2986
+ ":unit_id": entry.unitId ?? null,
2987
+ ":milestone_id": entry.milestoneId ?? null,
2988
+ ":slice_id": entry.sliceId ?? null,
2989
+ ":task_id": entry.taskId ?? null,
2990
+ ":outcome": entry.outcome,
2991
+ ":failure_class": entry.failureClass,
2992
+ ":rationale": entry.rationale ?? "",
2993
+ ":findings": entry.findings ?? "",
2994
+ ":attempt": entry.attempt,
2995
+ ":max_attempts": entry.maxAttempts,
2996
+ ":retryable": entry.retryable ? 1 : 0,
2997
+ ":evaluated_at": entry.evaluatedAt,
2998
+ });
2999
+ }
3000
+
3001
+ export function upsertTurnGitTransaction(entry: {
3002
+ traceId: string;
3003
+ turnId: string;
3004
+ unitType?: string;
3005
+ unitId?: string;
3006
+ stage: string;
3007
+ action: "commit" | "snapshot" | "status-only";
3008
+ push: boolean;
3009
+ status: "ok" | "failed";
3010
+ error?: string;
3011
+ metadata?: Record<string, unknown>;
3012
+ updatedAt: string;
3013
+ }): void {
3014
+ if (!currentDb) return;
3015
+ currentDb.prepare(
3016
+ `INSERT OR REPLACE INTO turn_git_transactions (
3017
+ trace_id, turn_id, unit_type, unit_id, stage, action, push, status, error, metadata_json, updated_at
3018
+ ) VALUES (
3019
+ :trace_id, :turn_id, :unit_type, :unit_id, :stage, :action, :push, :status, :error, :metadata_json, :updated_at
3020
+ )`,
3021
+ ).run({
3022
+ ":trace_id": entry.traceId,
3023
+ ":turn_id": entry.turnId,
3024
+ ":unit_type": entry.unitType ?? null,
3025
+ ":unit_id": entry.unitId ?? null,
3026
+ ":stage": entry.stage,
3027
+ ":action": entry.action,
3028
+ ":push": entry.push ? 1 : 0,
3029
+ ":status": entry.status,
3030
+ ":error": entry.error ?? null,
3031
+ ":metadata_json": JSON.stringify(entry.metadata ?? {}),
3032
+ ":updated_at": entry.updatedAt,
3033
+ });
3034
+ }
3035
+
3036
+ export function insertAuditEvent(entry: {
3037
+ eventId: string;
3038
+ traceId: string;
3039
+ turnId?: string;
3040
+ causedBy?: string;
3041
+ category: string;
3042
+ type: string;
3043
+ ts: string;
3044
+ payload: Record<string, unknown>;
3045
+ }): void {
3046
+ if (!currentDb) return;
3047
+ transaction(() => {
3048
+ currentDb!.prepare(
3049
+ `INSERT OR IGNORE INTO audit_events (
3050
+ event_id, trace_id, turn_id, caused_by, category, type, ts, payload_json
3051
+ ) VALUES (
3052
+ :event_id, :trace_id, :turn_id, :caused_by, :category, :type, :ts, :payload_json
3053
+ )`,
3054
+ ).run({
3055
+ ":event_id": entry.eventId,
3056
+ ":trace_id": entry.traceId,
3057
+ ":turn_id": entry.turnId ?? null,
3058
+ ":caused_by": entry.causedBy ?? null,
3059
+ ":category": entry.category,
3060
+ ":type": entry.type,
3061
+ ":ts": entry.ts,
3062
+ ":payload_json": JSON.stringify(entry.payload ?? {}),
3063
+ });
3064
+
3065
+ if (entry.turnId) {
3066
+ const row = currentDb!.prepare(
3067
+ `SELECT event_count, first_ts, last_ts
3068
+ FROM audit_turn_index
3069
+ WHERE trace_id = :trace_id AND turn_id = :turn_id`,
3070
+ ).get({
3071
+ ":trace_id": entry.traceId,
3072
+ ":turn_id": entry.turnId,
3073
+ });
3074
+ if (row) {
3075
+ currentDb!.prepare(
3076
+ `UPDATE audit_turn_index
3077
+ SET first_ts = CASE WHEN :ts < first_ts THEN :ts ELSE first_ts END,
3078
+ last_ts = CASE WHEN :ts > last_ts THEN :ts ELSE last_ts END,
3079
+ event_count = event_count + 1
3080
+ WHERE trace_id = :trace_id AND turn_id = :turn_id`,
3081
+ ).run({
3082
+ ":trace_id": entry.traceId,
3083
+ ":turn_id": entry.turnId,
3084
+ ":ts": entry.ts,
3085
+ });
3086
+ } else {
3087
+ currentDb!.prepare(
3088
+ `INSERT INTO audit_turn_index (trace_id, turn_id, first_ts, last_ts, event_count)
3089
+ VALUES (:trace_id, :turn_id, :first_ts, :last_ts, :event_count)`,
3090
+ ).run({
3091
+ ":trace_id": entry.traceId,
3092
+ ":turn_id": entry.turnId,
3093
+ ":first_ts": entry.ts,
3094
+ ":last_ts": entry.ts,
3095
+ ":event_count": 1,
3096
+ });
3097
+ }
3098
+ }
3099
+ });
3100
+ }
3101
+
3102
+ // ─── Single-writer bypass wrappers ───────────────────────────────────────
3103
+ // These wrappers exist so modules outside this file never need to call
3104
+ // `_getAdapter()` for writes. Each one is a byte-equivalent replacement for
3105
+ // a raw prepare/run previously issued from another module. Keep them
3106
+ // minimal and direct — they exist to hold SQL text in one place, not to
3107
+ // add new behavior.
3108
+
3109
+ /** Delete a decision row by id. Used by db-writer.ts rollback on disk-write failure. */
3110
+ export function deleteDecisionById(id: string): void {
3111
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3112
+ currentDb.prepare("DELETE FROM decisions WHERE id = :id").run({ ":id": id });
3113
+ }
3114
+
3115
+ /** Delete a requirement row by id. Used by db-writer.ts rollback on disk-write failure. */
3116
+ export function deleteRequirementById(id: string): void {
3117
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3118
+ currentDb.prepare("DELETE FROM requirements WHERE id = :id").run({ ":id": id });
3119
+ }
3120
+
3121
+ /** Delete an artifact row by path. Used by db-writer.ts rollback on disk-write failure. */
3122
+ export function deleteArtifactByPath(path: string): void {
3123
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3124
+ currentDb.prepare("DELETE FROM artifacts WHERE path = :path").run({ ":path": path });
3125
+ }
3126
+
3127
+ /**
3128
+ * Drop all rows from tasks/slices/milestones in dependency order inside a
3129
+ * transaction. Used by `gsd recover` to rebuild engine state from markdown.
3130
+ */
3131
+ export function clearEngineHierarchy(): void {
3132
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3133
+ transaction(() => {
3134
+ currentDb!.exec("DELETE FROM tasks");
3135
+ currentDb!.exec("DELETE FROM slices");
3136
+ currentDb!.exec("DELETE FROM milestones");
3137
+ });
3138
+ }
3139
+
3140
+ /**
3141
+ * INSERT OR IGNORE a slice during event replay (workflow-reconcile.ts).
3142
+ * Strict insert-or-ignore semantics are required here to avoid the
3143
+ * `insertSlice` ON CONFLICT path that could downgrade an already-completed
3144
+ * slice back to 'pending'.
3145
+ */
3146
+ export function insertOrIgnoreSlice(args: {
3147
+ milestoneId: string;
3148
+ sliceId: string;
3149
+ title: string;
3150
+ createdAt: string;
3151
+ }): void {
3152
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3153
+ currentDb.prepare(
3154
+ `INSERT OR IGNORE INTO slices (milestone_id, id, title, status, created_at)
3155
+ VALUES (:mid, :sid, :title, 'pending', :ts)`,
3156
+ ).run({
3157
+ ":mid": args.milestoneId,
3158
+ ":sid": args.sliceId,
3159
+ ":title": args.title,
3160
+ ":ts": args.createdAt,
3161
+ });
3162
+ }
3163
+
3164
+ /**
3165
+ * INSERT OR IGNORE a task during event replay (workflow-reconcile.ts).
3166
+ * Same rationale as `insertOrIgnoreSlice`.
3167
+ */
3168
+ export function insertOrIgnoreTask(args: {
3169
+ milestoneId: string;
3170
+ sliceId: string;
3171
+ taskId: string;
3172
+ title: string;
3173
+ createdAt: string;
3174
+ }): void {
3175
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3176
+ currentDb.prepare(
3177
+ `INSERT OR IGNORE INTO tasks (milestone_id, slice_id, id, title, status, created_at)
3178
+ VALUES (:mid, :sid, :tid, :title, 'pending', :ts)`,
3179
+ ).run({
3180
+ ":mid": args.milestoneId,
3181
+ ":sid": args.sliceId,
3182
+ ":tid": args.taskId,
3183
+ ":title": args.title,
3184
+ ":ts": args.createdAt,
3185
+ });
3186
+ }
3187
+
3188
+ /**
3189
+ * Stamp the `replan_triggered_at` column on a slice. Used by triage-resolution
3190
+ * when a user capture requests a replan so the dispatcher can detect the
3191
+ * trigger via DB in addition to the on-disk REPLAN-TRIGGER.md marker.
3192
+ */
3193
+ export function setSliceReplanTriggeredAt(milestoneId: string, sliceId: string, ts: string): void {
3194
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3195
+ currentDb.prepare(
3196
+ "UPDATE slices SET replan_triggered_at = :ts WHERE milestone_id = :mid AND id = :sid",
3197
+ ).run({ ":ts": ts, ":mid": milestoneId, ":sid": sliceId });
3198
+ }
3199
+
3200
+ /**
3201
+ * INSERT OR REPLACE a quality_gates row. Used by milestone-validation-gates.ts
3202
+ * to persist milestone-level (MV*) gate outcomes after validate-milestone runs.
3203
+ */
3204
+ export function upsertQualityGate(g: {
3205
+ milestoneId: string;
3206
+ sliceId: string;
3207
+ gateId: string;
3208
+ scope: string;
3209
+ taskId: string;
3210
+ status: string;
3211
+ verdict: string;
3212
+ rationale: string;
3213
+ findings: string;
3214
+ evaluatedAt: string;
3215
+ }): void {
3216
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3217
+ currentDb.prepare(
3218
+ `INSERT OR REPLACE INTO quality_gates
3219
+ (milestone_id, slice_id, gate_id, scope, task_id, status, verdict, rationale, findings, evaluated_at)
3220
+ VALUES (:mid, :sid, :gid, :scope, :tid, :status, :verdict, :rationale, :findings, :evaluated_at)`,
3221
+ ).run({
3222
+ ":mid": g.milestoneId,
3223
+ ":sid": g.sliceId,
3224
+ ":gid": g.gateId,
3225
+ ":scope": g.scope,
3226
+ ":tid": g.taskId,
3227
+ ":status": g.status,
3228
+ ":verdict": g.verdict,
3229
+ ":rationale": g.rationale,
3230
+ ":findings": g.findings,
3231
+ ":evaluated_at": g.evaluatedAt,
3232
+ });
3233
+ }
3234
+
3235
+ /**
3236
+ * Atomically replace all workflow state from a manifest. Lifted verbatim from
3237
+ * workflow-manifest.ts so the single-writer invariant holds. Only touches
3238
+ * engine tables + decisions. Does NOT modify artifacts or memories.
3239
+ */
3240
+ export function restoreManifest(manifest: StateManifest): void {
3241
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3242
+ const db = currentDb;
3243
+
3244
+ transaction(() => {
3245
+ // Clear engine tables (order matters for foreign-key-like consistency)
3246
+ db.exec("DELETE FROM verification_evidence");
3247
+ db.exec("DELETE FROM tasks");
3248
+ db.exec("DELETE FROM slices");
3249
+ db.exec("DELETE FROM milestones");
3250
+ db.exec("DELETE FROM decisions WHERE 1=1");
3251
+
3252
+ // Restore milestones
3253
+ const msStmt = db.prepare(
3254
+ `INSERT INTO milestones (id, title, status, depends_on, created_at, completed_at,
3255
+ vision, success_criteria, key_risks, proof_strategy,
3256
+ verification_contract, verification_integration, verification_operational, verification_uat,
3257
+ definition_of_done, requirement_coverage, boundary_map_markdown)
3258
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3259
+ );
3260
+ for (const m of manifest.milestones) {
3261
+ msStmt.run(
3262
+ m.id, m.title, m.status,
3263
+ JSON.stringify(m.depends_on), m.created_at, m.completed_at,
3264
+ m.vision, JSON.stringify(m.success_criteria), JSON.stringify(m.key_risks),
3265
+ JSON.stringify(m.proof_strategy),
3266
+ m.verification_contract, m.verification_integration, m.verification_operational, m.verification_uat,
3267
+ JSON.stringify(m.definition_of_done), m.requirement_coverage, m.boundary_map_markdown,
3268
+ );
3269
+ }
3270
+
3271
+ // Restore slices (ADR-011 Phase 1: includes is_sketch + sketch_scope)
3272
+ const slStmt = db.prepare(
3273
+ `INSERT INTO slices (milestone_id, id, title, status, risk, depends, demo,
3274
+ created_at, completed_at, full_summary_md, full_uat_md,
3275
+ goal, success_criteria, proof_level, integration_closure, observability_impact,
3276
+ sequence, replan_triggered_at, is_sketch, sketch_scope)
3277
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3278
+ );
3279
+ for (const s of manifest.slices) {
3280
+ slStmt.run(
3281
+ s.milestone_id, s.id, s.title, s.status, s.risk,
3282
+ JSON.stringify(s.depends), s.demo,
3283
+ s.created_at, s.completed_at, s.full_summary_md, s.full_uat_md,
3284
+ s.goal, s.success_criteria, s.proof_level, s.integration_closure, s.observability_impact,
3285
+ s.sequence, s.replan_triggered_at,
3286
+ s.is_sketch ?? 0,
3287
+ s.sketch_scope ?? "",
3288
+ );
3289
+ }
3290
+
3291
+ // Restore tasks (ADR-011 P2: includes blocker_source + escalation_* columns)
3292
+ const tkStmt = db.prepare(
3293
+ `INSERT INTO tasks (milestone_id, slice_id, id, title, status,
3294
+ one_liner, narrative, verification_result, duration, completed_at,
3295
+ blocker_discovered, deviations, known_issues, key_files, key_decisions,
3296
+ full_summary_md, description, estimate, files, verify,
3297
+ inputs, expected_output, observability_impact, sequence,
3298
+ blocker_source, escalation_pending, escalation_awaiting_review,
3299
+ escalation_artifact_path, escalation_override_applied_at)
3300
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3301
+ );
3302
+ for (const t of manifest.tasks) {
3303
+ tkStmt.run(
3304
+ t.milestone_id, t.slice_id, t.id, t.title, t.status,
3305
+ t.one_liner, t.narrative, t.verification_result, t.duration, t.completed_at,
3306
+ t.blocker_discovered ? 1 : 0, t.deviations, t.known_issues,
3307
+ JSON.stringify(t.key_files), JSON.stringify(t.key_decisions),
3308
+ t.full_summary_md, t.description, t.estimate, JSON.stringify(t.files), t.verify,
3309
+ JSON.stringify(t.inputs), JSON.stringify(t.expected_output),
3310
+ t.observability_impact, t.sequence,
3311
+ t.blocker_source ?? "",
3312
+ t.escalation_pending ?? 0,
3313
+ t.escalation_awaiting_review ?? 0,
3314
+ t.escalation_artifact_path ?? null,
3315
+ t.escalation_override_applied_at ?? null,
3316
+ );
3317
+ }
3318
+
3319
+ // Restore decisions (ADR-011 P2: include source so escalation decisions survive)
3320
+ const dcStmt = db.prepare(
3321
+ `INSERT INTO decisions (seq, id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by)
3322
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
3323
+ );
3324
+ for (const d of manifest.decisions) {
3325
+ dcStmt.run(d.seq, d.id, d.when_context, d.scope, d.decision, d.choice, d.rationale, d.revisable, d.made_by, d.source ?? "discussion", d.superseded_by);
3326
+ }
3327
+
3328
+ // Restore verification evidence
3329
+ const evStmt = db.prepare(
3330
+ `INSERT INTO verification_evidence (task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at)
3331
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
3332
+ );
3333
+ for (const e of manifest.verification_evidence) {
3334
+ evStmt.run(e.task_id, e.slice_id, e.milestone_id, e.command, e.exit_code, e.verdict, e.duration_ms, e.created_at);
3335
+ }
3336
+ });
3337
+ }
3338
+
3339
+ // ─── Legacy markdown → DB bulk migration ─────────────────────────────────
3340
+
3341
+ export interface LegacyMilestoneInsert {
3342
+ id: string;
3343
+ title: string;
3344
+ status: string;
3345
+ }
3346
+
3347
+ export interface LegacySliceInsert {
3348
+ id: string;
3349
+ milestoneId: string;
3350
+ title: string;
3351
+ status: string;
3352
+ risk: string;
3353
+ sequence: number;
3354
+ }
3355
+
3356
+ export interface LegacyTaskInsert {
3357
+ id: string;
3358
+ sliceId: string;
3359
+ milestoneId: string;
3360
+ title: string;
3361
+ status: string;
3362
+ sequence: number;
3363
+ }
3364
+
3365
+ /**
3366
+ * Bulk delete + insert a legacy milestone hierarchy for markdown → DB migration.
3367
+ * Used by workflow-migration.ts to populate engine tables from parsed ROADMAP/PLAN
3368
+ * files. All operations run inside a single transaction.
3369
+ */
3370
+ export function bulkInsertLegacyHierarchy(payload: {
3371
+ milestones: LegacyMilestoneInsert[];
3372
+ slices: LegacySliceInsert[];
3373
+ tasks: LegacyTaskInsert[];
3374
+ clearMilestoneIds: string[];
3375
+ createdAt: string;
3376
+ }): void {
3377
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3378
+ const db = currentDb;
3379
+ const { milestones, slices, tasks, clearMilestoneIds, createdAt } = payload;
3380
+
3381
+ if (clearMilestoneIds.length === 0) return;
3382
+ const placeholders = clearMilestoneIds.map(() => "?").join(",");
3383
+
3384
+ transaction(() => {
3385
+ db.prepare(`DELETE FROM tasks WHERE milestone_id IN (${placeholders})`).run(...clearMilestoneIds);
3386
+ db.prepare(`DELETE FROM slices WHERE milestone_id IN (${placeholders})`).run(...clearMilestoneIds);
3387
+ db.prepare(`DELETE FROM milestones WHERE id IN (${placeholders})`).run(...clearMilestoneIds);
3388
+
3389
+ const insertMilestone = db.prepare(
3390
+ "INSERT INTO milestones (id, title, status, created_at) VALUES (?, ?, ?, ?)",
3391
+ );
3392
+ for (const m of milestones) {
3393
+ insertMilestone.run(m.id, m.title, m.status, createdAt);
3394
+ }
3395
+
3396
+ const insertSliceStmt = db.prepare(
3397
+ "INSERT INTO slices (id, milestone_id, title, status, risk, depends, sequence, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
3398
+ );
3399
+ for (const s of slices) {
3400
+ insertSliceStmt.run(s.id, s.milestoneId, s.title, s.status, s.risk, "[]", s.sequence, createdAt);
3401
+ }
3402
+
3403
+ const insertTaskStmt = db.prepare(
3404
+ "INSERT INTO tasks (id, slice_id, milestone_id, title, description, status, estimate, files, sequence) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
3405
+ );
3406
+ for (const t of tasks) {
3407
+ insertTaskStmt.run(t.id, t.sliceId, t.milestoneId, t.title, "", t.status, "", "[]", t.sequence);
3408
+ }
3409
+ });
3410
+ }
3411
+
3412
+ // ─── Memory store writers ────────────────────────────────────────────────
3413
+ // All memory writes go through gsd-db.ts so the single-writer invariant
3414
+ // holds. These are direct pass-throughs to the SQL previously in
3415
+ // memory-store.ts — same bindings, same behavior.
3416
+
3417
+ export function insertMemoryRow(args: {
3418
+ id: string;
3419
+ category: string;
3420
+ content: string;
3421
+ confidence: number;
3422
+ sourceUnitType: string | null;
3423
+ sourceUnitId: string | null;
3424
+ createdAt: string;
3425
+ updatedAt: string;
3426
+ }): void {
3427
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3428
+ currentDb.prepare(
3429
+ `INSERT INTO memories (id, category, content, confidence, source_unit_type, source_unit_id, created_at, updated_at)
3430
+ VALUES (:id, :category, :content, :confidence, :source_unit_type, :source_unit_id, :created_at, :updated_at)`,
3431
+ ).run({
3432
+ ":id": args.id,
3433
+ ":category": args.category,
3434
+ ":content": args.content,
3435
+ ":confidence": args.confidence,
3436
+ ":source_unit_type": args.sourceUnitType,
3437
+ ":source_unit_id": args.sourceUnitId,
3438
+ ":created_at": args.createdAt,
3439
+ ":updated_at": args.updatedAt,
3440
+ });
3441
+ }
3442
+
3443
+ export function rewriteMemoryId(placeholderId: string, realId: string): void {
3444
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3445
+ currentDb.prepare("UPDATE memories SET id = :real_id WHERE id = :placeholder").run({
3446
+ ":real_id": realId,
3447
+ ":placeholder": placeholderId,
3448
+ });
3449
+ }
3450
+
3451
+ export function updateMemoryContentRow(
3452
+ id: string,
3453
+ content: string,
3454
+ confidence: number | undefined,
3455
+ updatedAt: string,
3456
+ ): void {
3457
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3458
+ if (confidence != null) {
3459
+ currentDb.prepare(
3460
+ "UPDATE memories SET content = :content, confidence = :confidence, updated_at = :updated_at WHERE id = :id",
3461
+ ).run({ ":content": content, ":confidence": confidence, ":updated_at": updatedAt, ":id": id });
3462
+ } else {
3463
+ currentDb.prepare(
3464
+ "UPDATE memories SET content = :content, updated_at = :updated_at WHERE id = :id",
3465
+ ).run({ ":content": content, ":updated_at": updatedAt, ":id": id });
3466
+ }
3467
+ }
3468
+
3469
+ export function incrementMemoryHitCount(id: string, updatedAt: string): void {
3470
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3471
+ currentDb.prepare(
3472
+ "UPDATE memories SET hit_count = hit_count + 1, updated_at = :updated_at WHERE id = :id",
3473
+ ).run({ ":updated_at": updatedAt, ":id": id });
3474
+ }
3475
+
3476
+ export function supersedeMemoryRow(oldId: string, newId: string, updatedAt: string): void {
3477
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3478
+ currentDb.prepare(
3479
+ "UPDATE memories SET superseded_by = :new_id, updated_at = :updated_at WHERE id = :old_id",
3480
+ ).run({ ":new_id": newId, ":updated_at": updatedAt, ":old_id": oldId });
3481
+ }
3482
+
3483
+ export function markMemoryUnitProcessed(
3484
+ unitKey: string,
3485
+ activityFile: string,
3486
+ processedAt: string,
3487
+ ): void {
3488
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3489
+ currentDb.prepare(
3490
+ `INSERT OR IGNORE INTO memory_processed_units (unit_key, activity_file, processed_at)
3491
+ VALUES (:key, :file, :at)`,
3492
+ ).run({ ":key": unitKey, ":file": activityFile, ":at": processedAt });
3493
+ }
3494
+
3495
+ export function decayMemoriesBefore(cutoffTs: string, now: string): void {
3496
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3497
+ currentDb.prepare(
3498
+ `UPDATE memories
3499
+ SET confidence = MAX(0.1, confidence - 0.1), updated_at = :now
3500
+ WHERE superseded_by IS NULL AND updated_at < :cutoff AND confidence > 0.1`,
3501
+ ).run({ ":now": now, ":cutoff": cutoffTs });
3502
+ }
3503
+
3504
+ export function supersedeLowestRankedMemories(limit: number, now: string): void {
3505
+ if (!currentDb) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
3506
+ currentDb.prepare(
3507
+ `UPDATE memories SET superseded_by = 'CAP_EXCEEDED', updated_at = :now
3508
+ WHERE id IN (
3509
+ SELECT id FROM memories
3510
+ WHERE superseded_by IS NULL
3511
+ ORDER BY (confidence * (1.0 + hit_count * 0.1)) ASC
3512
+ LIMIT :limit
3513
+ )`,
3514
+ ).run({ ":now": now, ":limit": limit });
3515
+ }