akm-cli 0.9.0-rc.0 → 0.9.0-rc.13

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 (598) hide show
  1. package/CHANGELOG.md +1283 -22
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
  26. package/dist/assets/stash-skeleton/README.md +38 -10
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  38. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  39. package/dist/assets/tasks/core/extract.yml +3 -2
  40. package/dist/assets/tasks/core/improve.yml +2 -1
  41. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  42. package/dist/assets/tasks/core/sync.yml +1 -0
  43. package/dist/assets/tasks/core/version-check.yml +2 -1
  44. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  45. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  46. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  48. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  49. package/dist/assets/templates/html/health.html +5 -4
  50. package/dist/assets/workflows/workflow-template.md +31 -15
  51. package/dist/cli/invocation.js +279 -0
  52. package/dist/cli/parse-args.js +5 -90
  53. package/dist/cli/retired-commands.js +78 -0
  54. package/dist/cli/shared.js +158 -48
  55. package/dist/cli-node.mjs +2 -1
  56. package/dist/cli.js +747 -293
  57. package/dist/commands/agent/agent-dispatch.js +19 -18
  58. package/dist/commands/agent/agent-support.js +0 -24
  59. package/dist/commands/agent/contribute-cli.js +43 -97
  60. package/dist/commands/completions.js +80 -23
  61. package/dist/commands/config-cli.js +44 -281
  62. package/dist/commands/env/env-binding.js +99 -0
  63. package/dist/commands/env/env-cli.js +84 -224
  64. package/dist/commands/env/env.js +12 -163
  65. package/dist/commands/env/marker-path.js +6 -0
  66. package/dist/commands/env/secret-cli.js +45 -61
  67. package/dist/commands/env/secret.js +32 -62
  68. package/dist/commands/feedback-cli.js +179 -85
  69. package/dist/commands/health/accept-rate.js +58 -0
  70. package/dist/commands/health/advisories.js +7 -8
  71. package/dist/commands/health/checks.js +279 -94
  72. package/dist/commands/health/html-report.js +197 -578
  73. package/dist/commands/health/improve-metrics.js +277 -246
  74. package/dist/commands/health/llm-usage.js +19 -19
  75. package/dist/commands/health/md-report.js +16 -7
  76. package/dist/commands/health/metrics.js +67 -32
  77. package/dist/commands/health/renderers.js +47 -0
  78. package/dist/commands/health/report-view-model.js +508 -0
  79. package/dist/commands/health/stash-exposure.js +1 -1
  80. package/dist/commands/health/surfaces.js +16 -56
  81. package/dist/commands/health/task-runs.js +3 -67
  82. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  83. package/dist/commands/health/types-improve.js +29 -0
  84. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  85. package/dist/commands/health/types-result.js +7 -0
  86. package/dist/commands/health/types-runs.js +4 -0
  87. package/dist/commands/health/types-session-log.js +4 -0
  88. package/dist/commands/health/types-windows.js +4 -0
  89. package/dist/commands/health/types.js +26 -21
  90. package/dist/commands/health/windows.js +2 -3
  91. package/dist/commands/health.js +296 -167
  92. package/dist/commands/improve/anti-collapse.js +5 -5
  93. package/dist/commands/improve/autonomy-gate.js +68 -0
  94. package/dist/commands/improve/collapse-detector.js +65 -52
  95. package/dist/commands/improve/consolidate/chunking.js +9 -7
  96. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  97. package/dist/commands/improve/consolidate/merge.js +4 -0
  98. package/dist/commands/improve/consolidate.js +454 -1354
  99. package/dist/commands/improve/content-hash.js +39 -0
  100. package/dist/commands/improve/distill/content-repair.js +4 -10
  101. package/dist/commands/improve/distill/promote-memory.js +89 -64
  102. package/dist/commands/improve/distill/quality-gate.js +118 -42
  103. package/dist/commands/improve/distill-guards.js +1 -1
  104. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  105. package/dist/commands/improve/distill.js +607 -363
  106. package/dist/commands/improve/eligibility.js +165 -79
  107. package/dist/commands/improve/extract-cli.js +35 -126
  108. package/dist/commands/improve/extract-prompt.js +6 -35
  109. package/dist/commands/improve/extract.js +640 -391
  110. package/dist/commands/improve/feedback-valence.js +2 -12
  111. package/dist/commands/improve/improve-cli.js +134 -135
  112. package/dist/commands/improve/improve-result-file.js +30 -50
  113. package/dist/commands/improve/improve-run-types.js +4 -0
  114. package/dist/commands/improve/improve-strategies.js +135 -0
  115. package/dist/commands/improve/improve.js +904 -701
  116. package/dist/commands/improve/locks.js +64 -111
  117. package/dist/commands/improve/loop-stages.js +1110 -923
  118. package/dist/commands/improve/memory/derived-ref.js +124 -0
  119. package/dist/commands/improve/memory/memory-belief.js +79 -7
  120. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  121. package/dist/commands/improve/memory/memory-improve.js +25 -37
  122. package/dist/commands/improve/outcome-loop.js +25 -88
  123. package/dist/commands/improve/preparation.js +1034 -813
  124. package/dist/commands/improve/proactive-maintenance.js +34 -9
  125. package/dist/commands/improve/proposal-envelope.js +31 -0
  126. package/dist/commands/improve/reflect.js +983 -794
  127. package/dist/commands/improve/run-context.js +119 -0
  128. package/dist/commands/improve/salience.js +24 -127
  129. package/dist/commands/improve/session-asset.js +7 -3
  130. package/dist/commands/improve/shared.js +14 -34
  131. package/dist/commands/improve/source-identity.js +28 -0
  132. package/dist/commands/improve/triage.js +20 -17
  133. package/dist/commands/lint/base-linter.js +340 -313
  134. package/dist/commands/lint/env-key-rules.js +31 -47
  135. package/dist/commands/lint/index.js +185 -30
  136. package/dist/commands/{events.js → log.js} +28 -38
  137. package/dist/commands/migrate-cli.js +54 -0
  138. package/dist/commands/migration-tool.js +55 -0
  139. package/dist/commands/observability-cli.js +70 -208
  140. package/dist/commands/proposal/diff-format.js +50 -0
  141. package/dist/commands/proposal/drain-policies.js +0 -6
  142. package/dist/commands/proposal/drain.js +91 -40
  143. package/dist/commands/proposal/proposal-cli.js +134 -132
  144. package/dist/commands/proposal/proposal-types.js +56 -0
  145. package/dist/commands/proposal/proposal.js +83 -65
  146. package/dist/commands/proposal/propose-cli.js +88 -0
  147. package/dist/commands/proposal/propose.js +105 -88
  148. package/dist/commands/proposal/repository.js +1303 -278
  149. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  150. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  151. package/dist/commands/proposal/validators/proposals.js +6 -8
  152. package/dist/commands/read/curate.js +78 -73
  153. package/dist/commands/read/knowledge.js +510 -13
  154. package/dist/commands/read/registry-search.js +2 -2
  155. package/dist/commands/read/remember-cli.js +84 -15
  156. package/dist/commands/read/search-cli.js +203 -96
  157. package/dist/commands/read/search.js +126 -94
  158. package/dist/commands/read/show.js +226 -250
  159. package/dist/commands/registry-cli.js +34 -60
  160. package/dist/commands/remember.js +18 -57
  161. package/dist/commands/sources/add-cli.js +104 -49
  162. package/dist/commands/sources/bundle-cli.js +166 -0
  163. package/dist/commands/sources/bundle-config-ops.js +63 -0
  164. package/dist/commands/sources/info.js +27 -15
  165. package/dist/commands/sources/init.js +30 -40
  166. package/dist/commands/sources/installed-stashes.js +469 -172
  167. package/dist/commands/sources/migration-help.js +7 -4
  168. package/dist/commands/sources/schema-repair.js +10 -9
  169. package/dist/commands/sources/self-update.js +182 -121
  170. package/dist/commands/sources/source-add.js +169 -178
  171. package/dist/commands/sources/source-clone.js +144 -41
  172. package/dist/commands/sources/source-manage.js +94 -59
  173. package/dist/commands/sources/sources-cli.js +64 -205
  174. package/dist/commands/sources/stash-cli.js +91 -54
  175. package/dist/commands/sources/stash-skeleton.js +1 -1
  176. package/dist/commands/tasks/tasks-cli.js +106 -104
  177. package/dist/commands/tasks/tasks.js +445 -262
  178. package/dist/commands/workflow-cli.js +232 -121
  179. package/dist/core/action-contributors.js +1 -1
  180. package/dist/core/activation-policy.js +49 -0
  181. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  182. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  183. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  184. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  185. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  186. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  187. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  188. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  189. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  190. package/dist/core/adapter/adapters/index.js +80 -0
  191. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  192. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  193. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  194. package/dist/core/adapter/adapters/shared.js +286 -0
  195. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  196. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  197. package/dist/core/adapter/bundle-adapter.js +4 -0
  198. package/dist/core/adapter/detect-adapter.js +17 -0
  199. package/dist/core/adapter/recognize-match.js +44 -0
  200. package/dist/core/adapter/registry.js +56 -0
  201. package/dist/core/adapter/types.js +4 -0
  202. package/dist/core/asset/akm-markdown.js +30 -0
  203. package/dist/core/asset/asset-placement.js +243 -0
  204. package/dist/core/asset/asset-ref.js +110 -79
  205. package/dist/core/asset/asset-serialize.js +20 -0
  206. package/dist/core/asset/frontmatter.js +28 -12
  207. package/dist/core/asset/markdown.js +40 -51
  208. package/dist/core/asset/resolve-ref.js +274 -0
  209. package/dist/core/asset/stash-meta.js +2 -2
  210. package/dist/core/bundle-id.js +51 -0
  211. package/dist/core/common.js +281 -86
  212. package/dist/core/config/config-io.js +42 -128
  213. package/dist/core/config/config-schema.js +233 -834
  214. package/dist/core/config/config-sources.js +162 -39
  215. package/dist/core/config/config-types.js +16 -11
  216. package/dist/core/config/config-version.js +29 -0
  217. package/dist/core/config/config-walker.js +126 -37
  218. package/dist/core/config/config.js +154 -331
  219. package/dist/core/config/deep-merge.js +41 -0
  220. package/dist/core/config/engine-semantics.js +28 -0
  221. package/dist/core/config/experimental.js +21 -0
  222. package/dist/core/config/schema/embedding.js +38 -0
  223. package/dist/core/config/schema/engines.js +116 -0
  224. package/dist/core/config/schema/experimental.js +47 -0
  225. package/dist/core/config/schema/feedback.js +31 -0
  226. package/dist/core/config/schema/improve-processes.js +389 -0
  227. package/dist/core/config/schema/improve.js +94 -0
  228. package/dist/core/config/schema/index-config.js +176 -0
  229. package/dist/core/config/schema/output.js +18 -0
  230. package/dist/core/config/schema/primitives.js +94 -0
  231. package/dist/core/config/schema/search.js +30 -0
  232. package/dist/core/config/schema/setup.js +18 -0
  233. package/dist/core/config/schema/sources-bundles.js +169 -0
  234. package/dist/core/config/schema/workflow.js +29 -0
  235. package/dist/core/env-secret-ref.js +155 -20
  236. package/dist/core/errors.js +17 -15
  237. package/dist/core/events-types.js +4 -0
  238. package/dist/core/events.js +46 -128
  239. package/dist/core/extra-params.js +62 -0
  240. package/dist/core/file-change.js +17 -0
  241. package/dist/core/file-lock.js +202 -57
  242. package/dist/core/fs-txn.js +392 -0
  243. package/dist/core/git-message.js +59 -0
  244. package/dist/core/improve-result.js +167 -0
  245. package/dist/core/json-schema.js +142 -0
  246. package/dist/core/lesson-lint.js +1 -17
  247. package/dist/core/logs-db.js +1 -1
  248. package/dist/core/maintenance-barrier.js +135 -0
  249. package/dist/core/migration-operation.js +44 -0
  250. package/dist/core/mutation-target.js +78 -0
  251. package/dist/core/paths.js +22 -25
  252. package/dist/core/platform.js +10 -0
  253. package/dist/core/recognition-util.js +128 -0
  254. package/dist/core/redaction.js +392 -0
  255. package/dist/core/standards/resolve-standards-context.js +36 -65
  256. package/dist/core/standards/resolve-stash-standards.js +2 -2
  257. package/dist/core/standards/resolve-type-conventions.js +5 -5
  258. package/dist/core/state/migrations.js +242 -11
  259. package/dist/core/state-db.js +98 -10
  260. package/dist/core/structured.js +1 -1
  261. package/dist/core/subprocess.js +303 -0
  262. package/dist/core/text-truncation.js +9 -5
  263. package/dist/core/time.js +20 -0
  264. package/dist/core/type-presentation.js +130 -0
  265. package/dist/core/warn.js +0 -3
  266. package/dist/core/write-source.js +834 -118
  267. package/dist/indexer/bundle-identity-guard.js +92 -0
  268. package/dist/indexer/db/graph-db.js +1 -25
  269. package/dist/indexer/db/llm-cache.js +1 -1
  270. package/dist/indexer/ensure-index.js +30 -9
  271. package/dist/indexer/graph/graph-boost.js +9 -30
  272. package/dist/indexer/graph/graph-extraction.js +41 -27
  273. package/dist/indexer/graph/graph-types.js +4 -0
  274. package/dist/indexer/index-writer-lock.js +93 -49
  275. package/dist/indexer/index-written-assets.js +100 -53
  276. package/dist/indexer/indexer.js +746 -329
  277. package/dist/indexer/init.js +18 -25
  278. package/dist/indexer/installations.js +142 -0
  279. package/dist/indexer/passes/dir-staleness.js +18 -10
  280. package/dist/indexer/passes/memory-inference.js +25 -15
  281. package/dist/indexer/passes/metadata.js +412 -243
  282. package/dist/indexer/scan/doc-to-entry.js +160 -0
  283. package/dist/indexer/scan/drain-dir.js +134 -0
  284. package/dist/indexer/search/db-search.js +292 -108
  285. package/dist/indexer/search/fts-query.js +64 -0
  286. package/dist/indexer/search/ranking-contributors.js +145 -25
  287. package/dist/indexer/search/ranking-types.js +4 -0
  288. package/dist/indexer/search/ranking.js +28 -71
  289. package/dist/indexer/search/search-attribution.js +67 -0
  290. package/dist/indexer/search/search-fields.js +18 -3
  291. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  292. package/dist/indexer/search/search-source.js +157 -111
  293. package/dist/indexer/search/semantic-status.js +4 -1
  294. package/dist/indexer/usage/usage-events.js +10 -30
  295. package/dist/indexer/walk/file-context.js +3 -45
  296. package/dist/indexer/walk/matchers.js +42 -34
  297. package/dist/indexer/walk/path-resolver.js +11 -5
  298. package/dist/indexer/walk/walker.js +42 -14
  299. package/dist/integrations/agent/builder-shared.js +7 -0
  300. package/dist/integrations/agent/builders.js +5 -56
  301. package/dist/integrations/agent/config.js +3 -143
  302. package/dist/integrations/agent/detect.js +17 -2
  303. package/dist/integrations/agent/engine-resolution.js +231 -0
  304. package/dist/integrations/agent/index.js +1 -2
  305. package/dist/integrations/agent/model-aliases.js +16 -2
  306. package/dist/integrations/agent/profiles.js +36 -62
  307. package/dist/integrations/agent/prompts.js +46 -18
  308. package/dist/integrations/agent/runner-dispatch.js +93 -4
  309. package/dist/integrations/agent/runner.js +76 -208
  310. package/dist/integrations/agent/spawn.js +88 -196
  311. package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
  312. package/dist/integrations/harnesses/aider/index.js +48 -0
  313. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  314. package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
  315. package/dist/integrations/harnesses/amazonq/index.js +45 -0
  316. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  317. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  318. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  319. package/dist/integrations/harnesses/claude/index.js +24 -35
  320. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  321. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  322. package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
  323. package/dist/integrations/harnesses/codex/index.js +52 -0
  324. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  325. package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
  326. package/dist/integrations/harnesses/copilot/index.js +48 -0
  327. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  328. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  329. package/dist/integrations/harnesses/gemini/index.js +48 -0
  330. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  331. package/dist/integrations/harnesses/ids.js +24 -0
  332. package/dist/integrations/harnesses/index.js +54 -34
  333. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  334. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  335. package/dist/integrations/harnesses/opencode/index.js +14 -32
  336. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  337. package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
  338. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  339. package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
  340. package/dist/integrations/harnesses/openhands/index.js +48 -0
  341. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  342. package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
  343. package/dist/integrations/harnesses/pi/index.js +45 -0
  344. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  345. package/dist/integrations/harnesses/shared.js +17 -0
  346. package/dist/integrations/harnesses/types.js +43 -32
  347. package/dist/integrations/lockfile.js +211 -24
  348. package/dist/integrations/session-logs/index.js +36 -39
  349. package/dist/integrations/session-logs/provider-base.js +113 -0
  350. package/dist/llm/client.js +182 -110
  351. package/dist/llm/embedders/deterministic.js +2 -2
  352. package/dist/llm/embedders/remote.js +21 -9
  353. package/dist/llm/feature-gate.js +17 -57
  354. package/dist/llm/graph-extract.js +12 -13
  355. package/dist/llm/index-passes.js +8 -42
  356. package/dist/llm/memory-infer.js +144 -1
  357. package/dist/llm/metadata-enhance.js +45 -30
  358. package/dist/llm/structured-call.js +16 -8
  359. package/dist/llm/usage-persist.js +30 -5
  360. package/dist/llm/usage-telemetry.js +59 -6
  361. package/dist/output/cli-hints.js +1 -2
  362. package/dist/output/command-registry.js +27 -0
  363. package/dist/output/context.js +22 -7
  364. package/dist/output/format-exempt.js +80 -0
  365. package/dist/output/generic-render.js +251 -0
  366. package/dist/output/html-render.js +11 -16
  367. package/dist/output/render-registry.js +57 -0
  368. package/dist/output/renderers.js +14 -279
  369. package/dist/output/shapes/curate.js +10 -1
  370. package/dist/output/shapes/events.js +12 -7
  371. package/dist/output/shapes/helpers.js +58 -84
  372. package/dist/output/shapes/passthrough.js +11 -39
  373. package/dist/output/shapes/proposal/producer.js +15 -7
  374. package/dist/output/shapes/registry.js +12 -6
  375. package/dist/output/shapes.js +0 -9
  376. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  377. package/dist/output/text/bundle-show.js +7 -0
  378. package/dist/output/text/command-format.js +562 -0
  379. package/dist/output/text/env.js +1 -3
  380. package/dist/output/text/events.js +8 -7
  381. package/dist/output/text/helpers.js +15 -1164
  382. package/dist/output/text/proposal/producer.js +4 -2
  383. package/dist/output/text/proposal-format.js +202 -0
  384. package/dist/output/text/registry-commands.js +1 -2
  385. package/dist/output/text/registry.js +12 -6
  386. package/dist/output/text/show-directives.js +117 -0
  387. package/dist/output/text/show-format.js +103 -0
  388. package/dist/output/text/sync.js +5 -0
  389. package/dist/output/text/workflow-format.js +332 -0
  390. package/dist/output/text/workflow.js +3 -2
  391. package/dist/output/text.js +10 -19
  392. package/dist/registry/factory.js +4 -6
  393. package/dist/registry/origin-resolve.js +16 -27
  394. package/dist/registry/providers/skills-sh.js +3 -3
  395. package/dist/registry/providers/static-index.js +15 -25
  396. package/dist/registry/resolve.js +43 -94
  397. package/dist/registry/semver.js +43 -0
  398. package/dist/runtime.js +81 -12
  399. package/dist/scripts/akm-migrate.js +35529 -0
  400. package/dist/setup/detect.js +5 -7
  401. package/dist/setup/detected-engines.js +136 -0
  402. package/dist/setup/engine-config.js +100 -0
  403. package/dist/setup/registry-stash-loader.js +3 -3
  404. package/dist/setup/semantic-assets.js +12 -9
  405. package/dist/setup/setup.js +444 -208
  406. package/dist/setup/steps/connection-shared.js +120 -0
  407. package/dist/setup/steps/connection.js +108 -305
  408. package/dist/setup/steps/platforms.js +13 -12
  409. package/dist/setup/steps/semantic.js +15 -3
  410. package/dist/setup/steps/sources.js +21 -15
  411. package/dist/setup/steps/stashdir.js +6 -4
  412. package/dist/setup/steps/tasks.js +236 -119
  413. package/dist/setup/steps.js +3 -2
  414. package/dist/sources/freshness.js +39 -0
  415. package/dist/sources/provider-factory.js +11 -17
  416. package/dist/sources/providers/filesystem.js +2 -3
  417. package/dist/sources/providers/git-install.js +278 -34
  418. package/dist/sources/providers/git-provider.js +54 -56
  419. package/dist/sources/providers/git-stash.js +420 -91
  420. package/dist/sources/providers/git.js +2 -2
  421. package/dist/sources/providers/npm.js +16 -19
  422. package/dist/sources/providers/provider-utils.js +47 -22
  423. package/dist/sources/providers/sync-from-ref.js +3 -9
  424. package/dist/sources/providers/website.js +2 -2
  425. package/dist/sources/resolve.js +11 -10
  426. package/dist/sources/snapshot-fetchers/types.js +4 -0
  427. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  428. package/dist/storage/database.js +60 -4
  429. package/dist/storage/engines/sqlite-migrations.js +156 -5
  430. package/dist/storage/locations.js +1 -2
  431. package/dist/storage/repositories/canaries-repository.js +1 -1
  432. package/dist/storage/repositories/events-repository.js +51 -11
  433. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  434. package/dist/storage/repositories/index-connection.js +79 -0
  435. package/dist/storage/repositories/index-db.js +4 -3
  436. package/dist/storage/repositories/index-entries-repository.js +863 -0
  437. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  438. package/dist/storage/repositories/index-entry-types.js +4 -0
  439. package/dist/storage/repositories/index-fts-repository.js +167 -0
  440. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  441. package/dist/storage/repositories/index-meta-repository.js +49 -0
  442. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  443. package/dist/storage/repositories/index-sql.js +12 -0
  444. package/dist/storage/repositories/index-utility-repository.js +356 -0
  445. package/dist/storage/repositories/index-vec-repository.js +250 -0
  446. package/dist/storage/repositories/outcome-repository.js +119 -0
  447. package/dist/storage/repositories/proposals-repository.js +317 -75
  448. package/dist/storage/repositories/registry-cache.js +1 -1
  449. package/dist/storage/repositories/salience-repository.js +172 -0
  450. package/dist/storage/repositories/task-history-repository.js +110 -3
  451. package/dist/storage/repositories/workflow-runs-repository.js +240 -19
  452. package/dist/tasks/backends/cron.js +169 -46
  453. package/dist/tasks/backends/exec-utils.js +76 -3
  454. package/dist/tasks/backends/index.js +6 -9
  455. package/dist/tasks/backends/launchd.js +292 -55
  456. package/dist/tasks/backends/schtasks.js +557 -70
  457. package/dist/tasks/backends/types.js +4 -0
  458. package/dist/tasks/command-executable.js +93 -0
  459. package/dist/tasks/embedded.js +56 -38
  460. package/dist/tasks/parser.js +156 -64
  461. package/dist/tasks/resolve-akm-bin.js +144 -51
  462. package/dist/tasks/runner.js +377 -209
  463. package/dist/tasks/schedule.js +108 -19
  464. package/dist/tasks/scheduler-invocation.js +296 -0
  465. package/dist/tasks/schema.js +1 -1
  466. package/dist/tasks/task-id.js +35 -0
  467. package/dist/tasks/validator.js +30 -16
  468. package/dist/text-import-hook.mjs +1 -1
  469. package/dist/workflows/authoring/authoring.js +104 -43
  470. package/dist/workflows/authoring/scope-key.js +1 -1
  471. package/dist/workflows/cli.js +0 -16
  472. package/dist/workflows/concurrency-policy.js +15 -0
  473. package/dist/workflows/exec/brief.js +450 -0
  474. package/dist/workflows/exec/frozen-judge.js +47 -0
  475. package/dist/workflows/exec/native-executor.js +1038 -0
  476. package/dist/workflows/exec/param-secrets.js +115 -0
  477. package/dist/workflows/exec/report.js +1460 -0
  478. package/dist/workflows/exec/run-workflow.js +602 -0
  479. package/dist/workflows/exec/scheduler.js +71 -0
  480. package/dist/workflows/exec/step-work.js +1190 -0
  481. package/dist/workflows/exec/unit-writer.js +23 -0
  482. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  483. package/dist/workflows/exec/worktree.js +171 -0
  484. package/dist/workflows/ir/compile.js +246 -0
  485. package/dist/workflows/ir/freeze.js +233 -0
  486. package/dist/workflows/ir/params.js +54 -0
  487. package/dist/workflows/ir/plan-hash.js +68 -0
  488. package/dist/workflows/ir/schema.js +540 -0
  489. package/dist/workflows/parser.js +878 -304
  490. package/dist/workflows/program/expressions.js +181 -0
  491. package/dist/workflows/program/schema.js +51 -0
  492. package/dist/workflows/renderer.js +100 -45
  493. package/dist/workflows/resource-limits.js +22 -0
  494. package/dist/workflows/runtime/agent-identity.js +59 -14
  495. package/dist/workflows/runtime/checkin.js +1 -1
  496. package/dist/workflows/runtime/plan-classifier.js +131 -0
  497. package/dist/workflows/runtime/runs.js +376 -119
  498. package/dist/workflows/runtime/unit-checkin.js +45 -0
  499. package/dist/workflows/runtime/unit-phases.js +20 -0
  500. package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
  501. package/dist/workflows/schema.js +1 -11
  502. package/dist/workflows/validate-summary.js +2 -3
  503. package/dist/workflows/validator.js +52 -30
  504. package/docs/README.md +42 -78
  505. package/docs/migration/README.md +8 -0
  506. package/docs/migration/release-notes/0.6.0.md +1 -1
  507. package/docs/migration/release-notes/0.7.0.md +9 -8
  508. package/docs/migration/release-notes/0.9.0.md +158 -14
  509. package/docs/migration/v0.7-to-v0.8.md +46 -47
  510. package/docs/migration/v0.8-to-v0.9.md +844 -0
  511. package/docs/reference/README.md +12 -0
  512. package/docs/reference/data-and-telemetry.md +333 -0
  513. package/package.json +21 -17
  514. package/schemas/akm-asset-envelope.json +93 -0
  515. package/schemas/akm-config.json +4636 -0
  516. package/schemas/akm-task.json +87 -0
  517. package/schemas/akm-workflow.json +373 -0
  518. package/dist/akm-migrate-storage +0 -38
  519. package/dist/assets/help/help-accept.md +0 -12
  520. package/dist/assets/help/help-improve.md +0 -84
  521. package/dist/assets/help/help-proposals.md +0 -17
  522. package/dist/assets/help/help-propose.md +0 -17
  523. package/dist/assets/help/help-reject.md +0 -11
  524. package/dist/assets/profiles/frequent.json +0 -13
  525. package/dist/assets/profiles/recombine-only.json +0 -21
  526. package/dist/assets/profiles/reflect-distill.json +0 -30
  527. package/dist/assets/profiles/synthesize.json +0 -15
  528. package/dist/assets/prompts/procedural-system.md +0 -44
  529. package/dist/assets/prompts/recombine-system.md +0 -40
  530. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  531. package/dist/assets/tasks/core/backup.yml +0 -4
  532. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  533. package/dist/assets/templates/html/default.html +0 -78
  534. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  535. package/dist/assets/wiki/index-template.md +0 -12
  536. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  537. package/dist/assets/wiki/log-template.md +0 -8
  538. package/dist/assets/wiki/schema-template.md +0 -61
  539. package/dist/cli/config-migrate.js +0 -150
  540. package/dist/cli/config-validate.js +0 -39
  541. package/dist/commands/graph/graph-cli.js +0 -124
  542. package/dist/commands/graph/graph.js +0 -487
  543. package/dist/commands/improve/calibration.js +0 -161
  544. package/dist/commands/improve/dedup.js +0 -482
  545. package/dist/commands/improve/extract-watch.js +0 -140
  546. package/dist/commands/improve/hot-probation.js +0 -45
  547. package/dist/commands/improve/improve-auto-accept.js +0 -276
  548. package/dist/commands/improve/improve-profiles.js +0 -168
  549. package/dist/commands/improve/procedural.js +0 -398
  550. package/dist/commands/improve/recombine.js +0 -818
  551. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  552. package/dist/commands/lint/agent-linter.js +0 -44
  553. package/dist/commands/lint/command-linter.js +0 -44
  554. package/dist/commands/lint/default-linter.js +0 -16
  555. package/dist/commands/lint/fact-linter.js +0 -39
  556. package/dist/commands/lint/knowledge-linter.js +0 -16
  557. package/dist/commands/lint/memory-linter.js +0 -61
  558. package/dist/commands/lint/registry.js +0 -41
  559. package/dist/commands/lint/skill-linter.js +0 -45
  560. package/dist/commands/lint/task-linter.js +0 -50
  561. package/dist/commands/lint/workflow-linter.js +0 -81
  562. package/dist/commands/proposal/legacy-import.js +0 -115
  563. package/dist/commands/sources/history.js +0 -196
  564. package/dist/commands/tasks/default-tasks.js +0 -186
  565. package/dist/commands/wiki-cli.js +0 -292
  566. package/dist/core/asset/asset-registry.js +0 -76
  567. package/dist/core/asset/asset-spec.js +0 -259
  568. package/dist/core/config/config-migration.js +0 -602
  569. package/dist/core/deep-merge.js +0 -38
  570. package/dist/core/eval/rank-metrics.js +0 -113
  571. package/dist/core/ripgrep/install.js +0 -163
  572. package/dist/core/ripgrep/resolve.js +0 -81
  573. package/dist/indexer/db/db.js +0 -1413
  574. package/dist/indexer/manifest.js +0 -170
  575. package/dist/indexer/passes/metadata-contributors.js +0 -31
  576. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  577. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
  578. package/dist/llm/call-ai.js +0 -62
  579. package/dist/llm/memory-infer-impl.js +0 -138
  580. package/dist/output/shapes/distill.js +0 -14
  581. package/dist/output/shapes/history.js +0 -11
  582. package/dist/output/text/distill.js +0 -6
  583. package/dist/output/text/enable-disable.js +0 -8
  584. package/dist/output/text/history.js +0 -6
  585. package/dist/output/text/wiki.js +0 -16
  586. package/dist/registry/build-index.js +0 -386
  587. package/dist/scripts/migrate-storage.js +0 -19108
  588. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
  589. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  590. package/dist/setup/legacy-config.js +0 -106
  591. package/dist/storage/repositories/consolidation-repository.js +0 -38
  592. package/dist/storage/repositories/recombine-repository.js +0 -213
  593. package/dist/wiki/wiki-templates.js +0 -15
  594. package/dist/wiki/wiki.js +0 -1012
  595. package/dist/workflows/db.js +0 -215
  596. package/docs/data-and-telemetry.md +0 -226
  597. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  598. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -10,14 +10,14 @@
10
10
  *
11
11
  * Runtime selection:
12
12
  * - On Bun (the primary/test runtime) we use the built-in `bun:sqlite`.
13
- * - On Node.js (additive, not CI-tested this pass) we use `better-sqlite3`,
14
- * loaded via a runtime-gated dynamic `require` so the Bun path never
13
+ * - On Node.js (CI-tested by the node-smoke job's smoke + compat suites) we
14
+ * use `better-sqlite3`, loaded via a runtime-gated dynamic `require` so the Bun path never
15
15
  * imports it (it is an optionalDependency and may be uninstalled or
16
16
  * uncompiled when running under Bun).
17
17
  *
18
18
  * Both driver handles are structurally compatible across the small surface AKM
19
19
  * uses (`prepare`, `exec`, `run`, `transaction`, `close` on the handle;
20
- * `get`, `all`, `run` on prepared statements). The Bun-specific `db.query()`
20
+ * `get`, `all`, `iterate`, `run` on prepared statements). The Bun-specific `db.query()`
21
21
  * helper is normalised away — callers use `db.prepare(sql).all(...)` instead.
22
22
  *
23
23
  * This file is intentionally NOT an adapter/DI/ports-and-adapters layer. It is
@@ -69,6 +69,50 @@ function selectProvider() {
69
69
  export function openDatabase(path, opts) {
70
70
  return selectProvider().open(path, opts);
71
71
  }
72
+ /**
73
+ * {@link openDatabase} with a finalize-on-close guard (issue #720).
74
+ *
75
+ * bun:sqlite's `Database.close()` is a `sqlite3_close_v2`: with any UNFINALIZED
76
+ * `prepare()` statement outstanding, the underlying connection — and its WAL
77
+ * shared-memory mapping — survives as a zombie until GC finalizes the
78
+ * statements. A later connection in the same process then cannot leave WAL
79
+ * mode (`PRAGMA journal_mode = DELETE` → "database is locked"), which is
80
+ * exactly what silently defeated the migrate-apply single-file conversion.
81
+ * (`db.query()` statements are Database-cached and immune; `prepare()` is the
82
+ * dominant idiom in the migration helpers.)
83
+ *
84
+ * This variant tracks `prepare()` results and finalizes them (idempotently)
85
+ * before the real `close()`, so close always means CLOSED. It is deliberately
86
+ * OPT-IN for the migrate-apply flow's short-lived helper connections and the
87
+ * migration test fixtures — NOT the global default: long-lived/hot paths cache
88
+ * prepared statements per connection (e.g. the entries upsert WeakMap) and
89
+ * worker flows may still be stepping a statement when a sibling close lands;
90
+ * force-finalizing under them changes behavior they were built on.
91
+ */
92
+ export function openDatabaseFinalizing(path, opts) {
93
+ const db = selectProvider().open(path, opts);
94
+ const tracked = new Set();
95
+ const origPrepare = db.prepare.bind(db);
96
+ const origClose = db.close.bind(db);
97
+ db.prepare = ((sql, ...rest) => {
98
+ const stmt = origPrepare(sql, ...rest);
99
+ tracked.add(stmt);
100
+ return stmt;
101
+ });
102
+ db.close = ((...args) => {
103
+ for (const stmt of tracked) {
104
+ try {
105
+ stmt.finalize?.();
106
+ }
107
+ catch {
108
+ // Already finalized (double-finalize is the idempotent no-op case).
109
+ }
110
+ }
111
+ tracked.clear();
112
+ return origClose(...args);
113
+ });
114
+ return db;
115
+ }
72
116
  function openBunDatabase(path, opts) {
73
117
  const { Database: BunDatabase } = loadBunSqlite();
74
118
  // Only pass an options object when an option is actually set. bun:sqlite
@@ -133,5 +177,17 @@ function openNodeDatabase(path, opts) {
133
177
  if (opts?.create === false)
134
178
  options.fileMustExist = true;
135
179
  const db = opts ? new BetterSqlite3(path, options) : new BetterSqlite3(path);
136
- return db;
180
+ return {
181
+ prepare: db.prepare.bind(db),
182
+ exec: db.exec.bind(db),
183
+ // better-sqlite3 exposes mutations on prepared statements, while
184
+ // bun:sqlite also provides db.run(). Normalize the latter at the provider
185
+ // boundary so callers and maintenance wrappers can rely on one contract.
186
+ run: (sql, ...params) => db.prepare(sql).run(...params),
187
+ transaction: db.transaction.bind(db),
188
+ get inTransaction() {
189
+ return db.inTransaction;
190
+ },
191
+ close: db.close.bind(db),
192
+ };
137
193
  }
@@ -1,6 +1,131 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * Shared SQLite migration engine.
6
+ *
7
+ * state.db (`src/core/state-db.ts`) evolves its schema through this idempotent,
8
+ * transaction-per-migration runner backed by a `schema_migrations` ledger. The
9
+ * migrator's frozen pre-cutover workflow-schema roll
10
+ * (`scripts/akm-migrate/migrate/legacy/workflow-migrations-bodies.ts`, driven by
11
+ * `scripts/akm-migrate/config-migrate.ts`) reuses the SAME runner.
12
+ *
13
+ * This module factors that runner out once. Each caller supplies only its own
14
+ * `MIGRATIONS` array.
15
+ *
16
+ * Migration-safety contract:
17
+ * - `id` is permanent and must never be reused.
18
+ * - `up` must be idempotent (use IF NOT EXISTS, INSERT OR IGNORE, etc.).
19
+ * - `up` must not DROP any table that holds durable (non-regenerable) data.
20
+ * - `up` must not RENAME or change the type of an existing column.
21
+ * - To add a column: use `ALTER TABLE … ADD COLUMN … DEFAULT …`.
22
+ * - Applied IDs must be an exact ordered prefix of the registry.
23
+ * - Released migration bodies are sealed by SHA-256 in the same ledger.
24
+ */
25
+ import crypto from "node:crypto";
26
+ export function migrationChecksum(migration) {
27
+ return crypto.createHash("sha256").update(migration.id).update("\0").update(migration.up).digest("hex");
28
+ }
29
+ function migrationsTableExists(db) {
30
+ return !!db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'schema_migrations'").get();
31
+ }
32
+ function ledgerHasChecksum(db) {
33
+ return db.prepare("PRAGMA table_info(schema_migrations)").all().some((column) => column.name === "checksum");
34
+ }
35
+ /**
36
+ * Core ledger inspection against the expected ordered `{ id, checksum }`
37
+ * registry. Both {@link inspectMigrationLedger} (bodies → checksums) and
38
+ * {@link inspectSealedMigrationLedger} (frozen pre-computed checksums) route
39
+ * here so the two entry points can never diverge.
40
+ */
41
+ function inspectLedgerAgainst(db, expected) {
42
+ const registryIds = expected.map((entry) => entry.id);
43
+ if (new Set(registryIds).size !== registryIds.length) {
44
+ return {
45
+ status: "inconsistent",
46
+ migrationIds: [],
47
+ checksums: [],
48
+ detail: "migration registry contains duplicate IDs",
49
+ };
50
+ }
51
+ if (!migrationsTableExists(db))
52
+ return { status: registryIds.length === 0 ? "current" : "old", migrationIds: [], checksums: [] };
53
+ const hasChecksum = ledgerHasChecksum(db);
54
+ const rows = db
55
+ .prepare(`SELECT id${hasChecksum ? ", checksum" : ""} FROM schema_migrations ORDER BY rowid`)
56
+ .all();
57
+ const migrationIds = rows.map((row) => row.id);
58
+ const checksums = rows.map((row) => row.checksum ?? null);
59
+ for (let index = 0; index < rows.length; index += 1) {
60
+ const entry = expected[index];
61
+ const row = rows[index];
62
+ if (!entry) {
63
+ return { status: "newer", migrationIds, checksums, detail: `unknown migration ID ${row.id}` };
64
+ }
65
+ if (row.id !== entry.id) {
66
+ const knownLater = registryIds.includes(row.id);
67
+ return {
68
+ status: knownLater ? "inconsistent" : "newer",
69
+ migrationIds,
70
+ checksums,
71
+ detail: knownLater
72
+ ? `migration ledger is not an exact ordered prefix at position ${index + 1}`
73
+ : `unknown migration ID ${row.id}`,
74
+ };
75
+ }
76
+ if (row.checksum && row.checksum !== entry.checksum) {
77
+ return {
78
+ status: "inconsistent",
79
+ migrationIds,
80
+ checksums,
81
+ detail: `migration ${row.id} checksum does not match the released migration body`,
82
+ };
83
+ }
84
+ }
85
+ const missingChecksum = checksums.indexOf(null);
86
+ if (missingChecksum >= 0) {
87
+ return {
88
+ status: "old",
89
+ migrationIds,
90
+ checksums,
91
+ detail: `migration ${migrationIds[missingChecksum]} has not been sealed with a checksum`,
92
+ };
93
+ }
94
+ return {
95
+ status: rows.length === expected.length ? "current" : "old",
96
+ migrationIds,
97
+ checksums,
98
+ };
99
+ }
100
+ export function inspectMigrationLedger(db, migrations) {
101
+ return inspectLedgerAgainst(db, migrations.map((migration) => ({ id: migration.id, checksum: migrationChecksum(migration) })));
102
+ }
103
+ /**
104
+ * Ledger inspection against a FROZEN `{ id, checksum }` copy of a migration
105
+ * array whose live source is gone (plan §3.3 item 1). Behaviourally identical
106
+ * to {@link inspectMigrationLedger} — the checksums are simply pre-computed
107
+ * rather than derived from `up` bodies.
108
+ */
109
+ export function inspectSealedMigrationLedger(db, sealed) {
110
+ return inspectLedgerAgainst(db, sealed);
111
+ }
112
+ export function assertMigrationLedger(db, migrations) {
113
+ const state = inspectMigrationLedger(db, migrations);
114
+ if (state.status === "newer") {
115
+ throw new Error(`Refusing to open a database with a newer migration ledger: ${state.detail}.`);
116
+ }
117
+ if (state.status === "inconsistent") {
118
+ throw new Error(`Refusing a database whose migrations are not an exact ordered prefix: ${state.detail}.`);
119
+ }
120
+ return state;
121
+ }
122
+ export function assertCurrentMigrationLedger(db, migrations) {
123
+ const state = assertMigrationLedger(db, migrations);
124
+ if (state.status !== "current") {
125
+ throw new Error(`Refusing to open an obsolete writable schema; run \`akm migrate apply\`: ${state.detail ?? "pending migrations"}.`);
126
+ }
127
+ return state;
128
+ }
4
129
  /**
5
130
  * Create the migrations ledger table if it does not exist. Must be called
6
131
  * unconditionally on every open so a fresh database bootstraps correctly.
@@ -9,9 +134,12 @@ export function ensureMigrationsTable(db) {
9
134
  db.exec(`
10
135
  CREATE TABLE IF NOT EXISTS schema_migrations (
11
136
  id TEXT PRIMARY KEY,
12
- applied_at TEXT NOT NULL DEFAULT (datetime('now'))
137
+ applied_at TEXT NOT NULL DEFAULT (datetime('now')),
138
+ checksum TEXT
13
139
  );
14
140
  `);
141
+ if (!ledgerHasChecksum(db))
142
+ db.exec("ALTER TABLE schema_migrations ADD COLUMN checksum TEXT");
15
143
  }
16
144
  /**
17
145
  * Apply every pending migration, one transaction per migration.
@@ -24,19 +152,42 @@ export function ensureMigrationsTable(db) {
24
152
  *
25
153
  * @param db The open SQLite database.
26
154
  * @param migrations The module's ordered, append-only migration list.
27
- * @param opts Optional `bootstrap` hook (see {@link RunMigrationsOptions}).
155
+ * @param opts Migration execution options.
28
156
  */
29
157
  export function runMigrations(db, migrations, opts) {
158
+ if (opts?.applyPending === false) {
159
+ assertMigrationLedger(db, migrations);
160
+ return;
161
+ }
162
+ if (migrationsTableExists(db))
163
+ assertMigrationLedger(db, migrations);
30
164
  ensureMigrationsTable(db);
31
- opts?.bootstrap?.(db);
32
- const appliedRows = db.prepare("SELECT id FROM schema_migrations").all();
165
+ const ledger = assertMigrationLedger(db, migrations);
166
+ db.transaction(() => {
167
+ const update = db.prepare("UPDATE schema_migrations SET checksum = ? WHERE id = ? AND checksum IS NULL");
168
+ for (let index = 0; index < ledger.migrationIds.length; index += 1) {
169
+ update.run(migrationChecksum(migrations[index]), ledger.migrationIds[index]);
170
+ }
171
+ if (opts?.generationMarker) {
172
+ db.exec(`
173
+ CREATE TABLE IF NOT EXISTS akm_migration_generation (
174
+ singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
175
+ operation_id TEXT NOT NULL,
176
+ phase TEXT NOT NULL
177
+ )
178
+ `);
179
+ db.prepare("INSERT INTO akm_migration_generation(singleton, operation_id, phase) VALUES (1, ?, ?) ON CONFLICT(singleton) DO UPDATE SET operation_id=excluded.operation_id, phase=excluded.phase").run(opts.generationMarker.operationId, opts.generationMarker.phase);
180
+ }
181
+ })();
182
+ const appliedRows = db.prepare("SELECT id FROM schema_migrations ORDER BY rowid").all();
33
183
  const applied = new Set(appliedRows.map((r) => r.id));
34
184
  for (const migration of migrations) {
35
185
  if (applied.has(migration.id))
36
186
  continue;
187
+ opts?.beforeMigration?.(migration);
37
188
  db.transaction(() => {
38
189
  db.exec(migration.up);
39
- db.prepare("INSERT INTO schema_migrations (id) VALUES (?)").run(migration.id);
190
+ db.prepare("INSERT INTO schema_migrations (id, checksum) VALUES (?, ?)").run(migration.id, migrationChecksum(migration));
40
191
  })();
41
192
  }
42
193
  }
@@ -1,7 +1,7 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import { getCacheDir, getConfigDir, getDataDir, getDbPath, getDefaultStashDir, getLockfileLockPath, getLockfilePath, getWorkflowDbPath, } from "../core/paths.js";
4
+ import { getCacheDir, getConfigDir, getDataDir, getDbPath, getDefaultStashDir, getLockfileLockPath, getLockfilePath, } from "../core/paths.js";
5
5
  import { getStateDbPath } from "../core/state-db.js";
6
6
  /**
7
7
  * Resolve the current {@link StorageLocations} by delegating to the existing
@@ -14,7 +14,6 @@ export function resolveStorageLocations() {
14
14
  return {
15
15
  indexDb: getDbPath(),
16
16
  stateDb: getStateDbPath(),
17
- workflowDb: getWorkflowDbPath(),
18
17
  lockfile: getLockfilePath(),
19
18
  lockfileSentinel: getLockfileLockPath(),
20
19
  dataDir: getDataDir(),
@@ -45,7 +45,7 @@ export function listActiveCanarySetIds(db) {
45
45
  /**
46
46
  * Deactivate every canary row in a set. Rows are RETAINED (active = 0) so
47
47
  * historical improve_cycle_metrics rows keyed on the old canary_set_id stay
48
- * interpretable; only `akm improve canary --refresh` calls this.
48
+ * interpretable; only `bun scripts/refresh-canary-set.ts --refresh` calls this.
49
49
  */
50
50
  export function deactivateCanarySet(db, canarySetId) {
51
51
  const result = db
@@ -38,12 +38,7 @@ export function eventRowToEnvelope(row) {
38
38
  */
39
39
  export function insertEvent(db, input) {
40
40
  try {
41
- const result = db
42
- .prepare(`INSERT INTO events (event_type, ts, ref, metadata_json)
43
- VALUES (?, ?, ?, ?)
44
- RETURNING id`)
45
- .get(input.eventType, input.ts, input.ref ?? null, JSON.stringify(input.metadata ?? {}));
46
- return result?.id;
41
+ return insertEventStrict(db, input);
47
42
  }
48
43
  catch (err) {
49
44
  const message = err instanceof Error ? err.message : String(err);
@@ -51,12 +46,52 @@ export function insertEvent(db, input) {
51
46
  return undefined;
52
47
  }
53
48
  }
49
+ /** Insert an event without best-effort error swallowing for transaction-coupled mutations. */
50
+ export function insertEventStrict(db, input) {
51
+ const result = db
52
+ .prepare(`INSERT INTO events (event_type, ts, ref, metadata_json)
53
+ VALUES (?, ?, ?, ?)
54
+ RETURNING id`)
55
+ .get(input.eventType, input.ts, input.ref ?? null, JSON.stringify(input.metadata ?? {}));
56
+ if (!result)
57
+ throw new Error(`Failed to persist ${input.eventType} event.`);
58
+ return result.id;
59
+ }
60
+ /** Strict idempotent event insert for durable mutation journals. */
61
+ export function insertEventOnce(db, input) {
62
+ const rows = db
63
+ .prepare("SELECT id, metadata_json FROM events WHERE event_type = ? AND ref IS ? ORDER BY id")
64
+ .all(input.eventType, input.ref ?? null);
65
+ for (const row of rows) {
66
+ try {
67
+ const metadata = JSON.parse(row.metadata_json);
68
+ if (metadata[input.idempotencyMetadataKey ?? "proposalTransactionId"] === input.idempotencyKey)
69
+ return row.id;
70
+ }
71
+ catch {
72
+ // Corrupt unrelated event metadata cannot satisfy this idempotency key.
73
+ }
74
+ }
75
+ const result = db
76
+ .prepare(`INSERT INTO events (event_type, ts, ref, metadata_json)
77
+ VALUES (?, ?, ?, ?)
78
+ RETURNING id`)
79
+ .get(input.eventType, input.ts, input.ref ?? null, JSON.stringify(input.metadata));
80
+ if (!result)
81
+ throw new Error(`Failed to persist ${input.eventType} event.`);
82
+ return result.id;
83
+ }
54
84
  /**
55
85
  * Read events from the database matching the filter. Returns events in
56
- * ascending id order so consumers can process them in emission order.
86
+ * ascending id order so consumers can process them in emission order —
87
+ * true even when `options.limit` selects the most-recent page (see
88
+ * {@link ReadStateEventsOptions.limit}).
57
89
  *
58
90
  * The returned `nextId` is the maximum id seen (or `sinceId` when no rows
59
- * match), suitable as the next `sinceId` cursor value.
91
+ * match), suitable as the next `sinceId` cursor value. This is unaffected by
92
+ * `limit`: it is always the id of the last row actually returned, which —
93
+ * because a `limit` page is the MOST RECENT matching rows — is the same
94
+ * value an unbounded read of the same filter would have produced.
60
95
  */
61
96
  export function readStateEvents(db, options = {}) {
62
97
  const conditions = [];
@@ -78,10 +113,15 @@ export function readStateEvents(db, options = {}) {
78
113
  params.push(options.ref);
79
114
  }
80
115
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
116
+ const hasLimit = options.limit !== undefined && options.limit > 0;
117
+ const orderAndLimit = hasLimit ? "ORDER BY id DESC LIMIT ?" : "ORDER BY id ASC";
118
+ const queryParams = hasLimit ? [...params, options.limit] : params;
81
119
  const rows = db
82
- .prepare(`SELECT id, event_type, ts, ref, metadata_json FROM events ${where} ORDER BY id ASC`)
83
- .all(...params);
84
- const events = rows.map(eventRowToEnvelope);
120
+ .prepare(`SELECT id, event_type, ts, ref, metadata_json FROM events ${where} ${orderAndLimit}`)
121
+ .all(...queryParams);
122
+ // A DESC-ordered LIMIT page comes back newest-first; reverse it so the
123
+ // returned array is always ascending by id, matching the unbounded path.
124
+ const events = (hasLimit ? rows.slice().reverse() : rows).map(eventRowToEnvelope);
85
125
  const nextId = events.length > 0 ? events[events.length - 1].id : (options.sinceId ?? 0);
86
126
  return { events, nextId };
87
127
  }
@@ -2,26 +2,6 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import { classifyImproveAction } from "../../core/improve-types.js";
5
- // ── Per-phase gate threshold store (Migration 012) ───────────────────────────
6
- /**
7
- * Read the persisted auto-tuned threshold for a gate phase.
8
- *
9
- * Returns `undefined` when no row exists yet (first run, or the phase has
10
- * never been tuned). The caller falls back to the global `options.autoAccept`
11
- * in that case.
12
- */
13
- export function getPhaseThreshold(db, phase) {
14
- const row = db.prepare("SELECT threshold FROM improve_gate_thresholds WHERE phase = ?").get(phase);
15
- return row?.threshold;
16
- }
17
- /**
18
- * Persist the auto-tuned threshold for a gate phase.
19
- * Uses INSERT OR REPLACE so the call is idempotent (upsert semantics).
20
- */
21
- export function persistPhaseThreshold(db, phase, threshold) {
22
- db.prepare(`INSERT OR REPLACE INTO improve_gate_thresholds (phase, threshold, updated_at)
23
- VALUES (?, ?, ?)`).run(phase, Math.round(threshold), Date.now());
24
- }
25
5
  /**
26
6
  * Compute the cheap aggregate metrics blob from a full improve result.
27
7
  *
@@ -61,19 +41,13 @@ export function computeImproveRunMetrics(result) {
61
41
  case "noop":
62
42
  break;
63
43
  }
64
- // Legacy: pre-gate action results may carry autoAccepted: true (reflect path).
65
- const r = action.result;
66
- if (r && r.autoAccepted === true)
67
- autoAcceptedCount++;
68
44
  }
69
45
  // Add gate-promoted count from the unified PostPhaseAutoAcceptGate (all phases).
70
46
  autoAcceptedCount += result.gateAutoAcceptedCount ?? 0;
71
47
  // C1 (13-bus-factor): distill-skipped rows are folded into the bounded
72
48
  // `distillSkipped` aggregate and no longer live in `actions`. Add the
73
49
  // aggregate total to the skipped + total-actions counters so metrics_json
74
- // reports the same numbers as before the fold. (Legacy rows that still carry
75
- // per-ref distill-skipped in `actions` have no aggregate, so they are counted
76
- // by the classify loop above — never double-counted.)
50
+ // keeps aggregate metrics aligned with the logical action count.
77
51
  const distillSkippedTotal = result.distillSkipped?.total ?? 0;
78
52
  skippedCount += distillSkippedTotal;
79
53
  return {
@@ -103,10 +77,10 @@ export function recordImproveRun(db, input) {
103
77
  const metricsObj = input.metrics ?? computeImproveRunMetrics(input.result);
104
78
  db.prepare(`
105
79
  INSERT INTO improve_runs
106
- (id, started_at, completed_at, stash_dir, dry_run, profile,
80
+ (id, started_at, completed_at, stash_dir, dry_run, strategy,
107
81
  scope_mode, scope_value, guidance, ok, result_json, metrics_json, metadata_json)
108
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
109
- `).run(input.id, input.startedAt, input.completedAt, input.stashDir, input.dryRun ? 1 : 0, input.profile, input.scopeMode, input.scopeValue, input.guidance, input.ok ? 1 : 0, JSON.stringify(input.result), JSON.stringify(metricsObj), JSON.stringify(input.metadata ?? {}));
82
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
83
+ `).run(input.id, input.startedAt, input.completedAt, input.stashDir, input.dryRun ? 1 : 0, input.strategy, input.scopeMode, input.scopeValue, input.guidance, input.ok ? 1 : 0, JSON.stringify(input.result), JSON.stringify(metricsObj), JSON.stringify(input.metadata ?? {}));
110
84
  }
111
85
  /**
112
86
  * Read real (non-dry-run) improve_runs rows whose `started_at` falls in the
@@ -124,8 +98,8 @@ export function recordImproveRun(db, input) {
124
98
  */
125
99
  export function queryImproveRuns(db, since, until) {
126
100
  const sql = until
127
- ? "SELECT id, started_at, completed_at, ok, scope_mode, scope_value, result_json FROM improve_runs WHERE started_at >= ? AND started_at < ? AND dry_run = 0 ORDER BY started_at DESC"
128
- : "SELECT id, started_at, completed_at, ok, scope_mode, scope_value, result_json FROM improve_runs WHERE started_at >= ? AND dry_run = 0 ORDER BY started_at DESC";
101
+ ? "SELECT id, started_at, completed_at, ok, scope_mode, scope_value, strategy, result_json FROM improve_runs WHERE started_at >= ? AND started_at < ? AND dry_run = 0 ORDER BY started_at DESC"
102
+ : "SELECT id, started_at, completed_at, ok, scope_mode, scope_value, strategy, result_json FROM improve_runs WHERE started_at >= ? AND dry_run = 0 ORDER BY started_at DESC";
129
103
  return (until ? db.prepare(sql).all(since, until) : db.prepare(sql).all(since));
130
104
  }
131
105
  /**
@@ -0,0 +1,79 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * `index.db` connection lifecycle for the storage layer.
6
+ *
7
+ * Opens/closes the index database, arming the sqlite-vec extension and (for the
8
+ * managed open path) running `ensureSchema`. This module lives BELOW the
9
+ * indexer, so the storage loan helpers (`index-db.ts`, `registry-cache.ts`)
10
+ * import their opener from a sibling here instead of reaching up into the
11
+ * indexer — inverting the old storage→indexer arrow.
12
+ */
13
+ import fs from "node:fs";
14
+ import { createRequire } from "node:module";
15
+ import { getDbPath } from "../../core/paths.js";
16
+ import { openDatabase } from "../database.js";
17
+ import { openManagedDatabase } from "../managed-db.js";
18
+ import { ensureSchema } from "./index-schema.js";
19
+ import { loadVecExtension, warnIfVecMissing } from "./index-vec-repository.js";
20
+ export function openIndexDatabase(dbPath, options) {
21
+ return openManagedDatabase({
22
+ path: dbPath ?? getDbPath(),
23
+ init: (db) => {
24
+ // Try to load sqlite-vec extension
25
+ loadVecExtension(db);
26
+ // Dim resolution: explicit option wins; otherwise consult the on-disk
27
+ // config so unparameterised opens (registry providers, graph helpers,
28
+ // ad-hoc CLI subcommands) honour the operator-declared dimension. Only if
29
+ // both are absent do we fall through to the no-clobber path, which keeps
30
+ // ensureSchema from touching `index_meta.embeddingDim` at all.
31
+ const resolvedDim = options?.embeddingDim ?? resolveConfiguredEmbeddingDim();
32
+ ensureSchema(db, resolvedDim);
33
+ // Warn once at init if using JS fallback with many entries
34
+ warnIfVecMissing(db, { once: true });
35
+ },
36
+ });
37
+ }
38
+ /**
39
+ * Read the operator-configured embedding dimension from the on-disk config.
40
+ * Returns `undefined` when no config file is present, when the config has
41
+ * no `embedding.dimension` set, or when reading the config throws (e.g.
42
+ * inside isolated test fixtures with no XDG home). Failure is silent on
43
+ * purpose — every openDatabase() call would otherwise have to handle a
44
+ * config-not-found error path, and the fallback (no-clobber semantics) is
45
+ * already correct.
46
+ */
47
+ function resolveConfiguredEmbeddingDim() {
48
+ try {
49
+ const esmRequire = createRequire(import.meta.url);
50
+ const { loadConfig } = esmRequire("../../core/config/config");
51
+ const dim = loadConfig().embedding?.dimension;
52
+ if (typeof dim === "number" && Number.isInteger(dim) && dim > 0 && dim <= 4096) {
53
+ return dim;
54
+ }
55
+ return undefined;
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ }
61
+ export function openExistingDatabase(dbPath) {
62
+ // Existing-DB callers must not mutate schema or embedding metadata on open,
63
+ // but some paths still need write access to usage_events and other tables —
64
+ // so init only loads the vec extension, it does not run ensureSchema.
65
+ return openManagedDatabase({ path: dbPath ?? getDbPath(), init: loadVecExtension });
66
+ }
67
+ /**
68
+ * Open an existing index for queries without creating directories, a database
69
+ * file, journals, or running write-capable pragmas/schema initialization.
70
+ */
71
+ export function openReadonlyExistingDatabase(dbPath) {
72
+ const resolvedPath = dbPath ?? getDbPath();
73
+ if (!fs.existsSync(resolvedPath))
74
+ return undefined;
75
+ return openDatabase(resolvedPath, { readonly: true, create: false });
76
+ }
77
+ export function closeDatabase(db) {
78
+ db.close();
79
+ }
@@ -1,9 +1,9 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import { openExistingDatabase } from "../../indexer/db/db.js";
5
4
  import { resolveStorageLocations } from "../locations.js";
6
5
  import { withManagedDb } from "../managed-db.js";
6
+ import { openExistingDatabase } from "./index-connection.js";
7
7
  /**
8
8
  * Busy-timeout (ms) for read-path telemetry writers. Small on purpose: a
9
9
  * usage-event insert contending with a background reindex should be dropped,
@@ -13,8 +13,9 @@ export const TELEMETRY_BUSY_TIMEOUT_MS = 250;
13
13
  /**
14
14
  * Scoped-resource (loan pattern) helper for the index database (`index.db`).
15
15
  *
16
- * This is the `index.db` twin of {@link ../../workflows/db withWorkflowDb} /
17
- * {@link ./workflow-runs-repository withWorkflowRunsRepo}: it opens the index
16
+ * This is the `index.db` twin of the state.db loan helpers ({@link
17
+ * ../../core/state-db withStateDb} / {@link ./workflow-runs-repository
18
+ * withWorkflowRunsRepo}): it opens the index
18
19
  * database bound to {@link StorageLocations.indexDb}, runs `fn` against the live
19
20
  * {@link Database}, and closes the connection exactly once when `fn` returns —
20
21
  * even if `fn` throws. Callers no longer hand-roll `open / try / finally / close`