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
package/CHANGELOG.md CHANGED
@@ -6,7 +6,1266 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- ## [0.9.0] 2026-06-30
9
+ ## [0.9.0-rc.13] - 2026-07-31
10
+
11
+ ### Security
12
+
13
+ - **`akm update` no longer deletes a previous install directory without
14
+ confirmation.** When a managed source's resolved content location moves,
15
+ `update` removed the old directory outright, while `akm remove` had always
16
+ required `--yes` in non-interactive mode. Only that destructive branch is
17
+ gated — a normal refresh, where the location does not move, still needs no
18
+ prompt and no flag, so existing CI invocations are unaffected. Pass
19
+ `-y`/`--yes` to allow the deletion non-interactively. A cleanup that fails
20
+ now warns instead of failing silently.
21
+
22
+ - **The dangerous-env-key install gate now scans `env/` recursively.** It
23
+ previously read only the top level, so a stash carrying `LD_PRELOAD` in
24
+ `env/nested/inner.env` installed cleanly with no warning. Files without a
25
+ `.env` suffix are still not scanned — no akm code path loads them as
26
+ environment variables.
27
+
28
+ ### Added
29
+
30
+ - **The `okf` adapter reads OKF v0.2's trust/provenance and lifecycle
31
+ frontmatter families.** `generated: {by, at}` (with `generated.at` taking
32
+ precedence over the legacy `timestamp` field, which remains a valid
33
+ fallback), `verified` (a list, or v0.2's permitted single-mapping
34
+ shorthand), `sources` (an object list — `resource` required; `id`/`title`/
35
+ `author`/`usage_count`/`last_modified` optional), `status`
36
+ (`draft`/`stable`/`deprecated`), and `stale_after` are now parsed leniently
37
+ from any OKF concept's frontmatter and surfaced on new, namespaced
38
+ `IndexDocument` fields (`provenance`, `lifecycleStatus`, `staleAfter`,
39
+ `okfVersion`) that never overload the pre-existing AKM-native `sources`
40
+ (wiki citation strings), `generation` (consolidation depth), or `quality`
41
+ fields. As with every other optional OKF field, a missing or malformed
42
+ value never rejects the document. The `okf` adapter remains consumer-only.
43
+
44
+ - **Accepting a proposal now stamps OKF v0.2 provenance onto the written
45
+ asset's frontmatter**, for AKM-native writes only (never through the `okf`
46
+ adapter, which stays consumer-only and unaffected by this). `promoteProposal`
47
+ projects the proposal system's own `source`/`sourceRun`/`gateDecision`/
48
+ `review` bookkeeping — already tracked in `state.db` but previously never
49
+ written to disk. `generated: {by, at}` and `verified: [{by, at}]` are written
50
+ **bare at the top level**, exactly as OKF v0.2 spells them, so a third-party
51
+ OKF v0.2 reader pointed at an AKM stash sees conformant trust metadata;
52
+ `sources` alone is namespaced as `provenance: {sources}`, because a bare
53
+ `sources:` collides with the pre-existing wiki citation-string convention.
54
+ `generated.by` records whether the content came from an automated pipeline
55
+ (`akm/<version>`) or a human-initiated source (`human:<id>`); `verified`
56
+ records whether the promotion itself was an automated gate decision or a
57
+ direct human accept, and accumulates rather than overwriting across
58
+ re-promotions; `evidenceSources`, when present, projects as
59
+ `provenance.sources`. AKM's own adapter rereads what it wrote, so `akm show`
60
+ surfaces it. Every AKM-native markdown type is stamped, `workflow` included.
61
+
62
+ Two consequences worth knowing: promotion re-serializes the whole frontmatter
63
+ block, so YAML **comments** in a hand-written proposal's frontmatter are not
64
+ preserved (values and body bytes are); and for a human-attributed promotion
65
+ with no configured actor id, `by` falls back to `human:<OS username>`, which
66
+ puts that username into content you may later commit and share.
67
+
68
+ - **Internal: a `capturedAtHead` integrity guard**
69
+ (`scripts/lint-golden-captured-at-head.ts`, wired into `bun run lint`) now
70
+ checks every golden fixture's recorded `capturedAtHead` commit SHA — it must
71
+ exist in the local object database and be reachable from at least one known
72
+ branch. Post-hoc review of this PR found all four new OKF format-family
73
+ goldens pointed at a commit that existed locally but was unreachable from
74
+ any ref (a pre-amend duplicate left behind by an interrupted git operation),
75
+ which would have 404'd on GitHub and vanished under a local `git gc`; a
76
+ human fixed that one by hand because nothing caught it. This guard is that
77
+ catch, going forward. In CI's shallow (`fetch-depth: 1`) checkout, a merely
78
+ *absent* commit object is inconclusive (indistinguishable from "just not
79
+ fetched") and only warns; a commit that *exists but is unreachable from any
80
+ branch* — the actual bug class above — still fails there too, since a
81
+ shallow clone can tell presence apart from absence just fine.
82
+
83
+ - **`akm log list --limit <n>`** returns the most recent N events. The flag was
84
+ documented but silently ignored, and there was no limiting mechanism at all
85
+ in the read path — the command returned the entire events table regardless of
86
+ history size. The default remains unlimited.
87
+
88
+ - **`--track-usage` (default on) on `akm search`, `akm curate`, and `akm show`.**
89
+ Pass `--no-track-usage` for a read-only lookup that does not feed usage
90
+ telemetry or the utility-score ranking signal. Previously a bare `akm search`
91
+ silently wrote a `utility_scores` row that influenced future ranking, with no
92
+ disclosure and no way to opt out.
93
+
94
+ - **`akm show` returns the canonical `ref` in every shape.** It was present only
95
+ under `--shape agent`, so a `--shape summary` consumer had to make a second
96
+ call at a different shape just to learn which asset it was looking at.
97
+
98
+ - **`akm info` gained `stashDir`, `defaultBundle`, and `indexStats.byType`.**
99
+ Answering "which stash is primary" previously required a separate
100
+ `akm sources list`.
101
+
102
+ - **`instruction` is a stash-resident asset type.** It was already in
103
+ `KNOWN_TYPES` and had a presentation entry, but had no placement spec — so
104
+ there was nowhere to put one and the indexer never recognized one. `akm bundle create`
105
+ now creates an `instructions/` directory, `.md` files under it index as
106
+ `instruction`, and `--type instruction` is accepted and tab-completable
107
+ everywhere `--type` is. A compile-time assertion now pins
108
+ `placementTypes() ⊆ KnownType`, so the half-registered state this fixes
109
+ cannot recur silently.
110
+
111
+ - **Schedule tasks from any configured bundle via `--bundle <bundle>`** (#711).
112
+ `akm task add`, `run`, `sync`, and `history` accept `--bundle` to
113
+ operate on a non-default bundle instead of only the primary stash. `add`
114
+ resolves through the normal writable-target rules; `run --bundle X` resolves
115
+ the task file and relative asset refs from bundle X. A non-default bundle is
116
+ recorded in the scheduler entry as `--bundle <bundle>`, so scheduled
117
+ `akm task run` resolves the right bundle. Scheduler ids stay bare and a
118
+ collision with another bundle is a hard error rather than a silent clobber.
119
+
120
+ - **Orphan-GC pass for unresolvable `asset_salience` / `asset_outcome` state
121
+ rows** (#733). A new improve maintenance pass (`runOrphanStateGcPass`, run
122
+ next to the existing orphan-proposal purge) stamps `missing_since` on any
123
+ state row whose ref no longer resolves against `entries.item_ref`, clears
124
+ the stamp the moment the ref resolves again, and — only when
125
+ `improve.stateGc.collect` is set to `true` (**default `false`**) — deletes
126
+ rows whose stamp is older than a fixed 7-day grace window
127
+ (`STATE_GC_GRACE_MS`). The pass always runs and always reports counts via
128
+ the new `asset_state_gc` event (`{pending, collected, byTable}`), emitted
129
+ only when there is something to report, so live data can prove the report
130
+ clean before `collect` is ever turned on. Additive migration
131
+ `021-asset-state-missing-since` adds the `missing_since` column to both
132
+ tables. Deliberately lean by design (Workstream C): no quarantine archive,
133
+ no circuit breaker, no health-advisory plumbing, no new tables — "ref not
134
+ present in `entries.item_ref`" is trusted as the authoritative-deletion
135
+ predicate because the indexer already preserves a source's last-known-good
136
+ rows when its scan is incomplete, so a temporarily unreachable source never
137
+ contributes false candidates. `usage_events` is out of scope (already
138
+ covered by cascade-on-delete plus its own 90-day retention purge).
139
+
140
+ ### Changed
141
+
142
+ - **The two workflow authoring formats — markdown documents and YAML
143
+ orchestration programs — are unified into one format**, per
144
+ `docs/architecture/specs/workflow-format-unification.md`. A workflow is
145
+ now always a single markdown asset: the standard AKM frontmatter envelope
146
+ carries the whole orchestration graph (`params`, `steps` with
147
+ `unit`/`map`/`route`, `inputs`, `output`, `gate`, `defaults`, `budget`),
148
+ and the body carries each step's instructions under a bare `## <step-id>`
149
+ heading, joined to the frontmatter by step id. `.yaml`/`.yml` workflow
150
+ files, the `# Workflow:` / `## Step:` / `Step ID:` markdown headings, and
151
+ `akm workflow create <name>.yaml` are all gone; `akm workflow create`
152
+ always writes the one unified template
153
+ (`src/assets/workflows/workflow-template.md`).
154
+
155
+ **Prose is never interpolated.** The YAML program's `${{ … }}` template
156
+ language, and the markdown format's decorative — and never
157
+ substituted — `{{ … }}` moustaches, are both removed. Data reaches a
158
+ dispatched unit as *attached context* instead: the run's params, its
159
+ item and index for a map unit, and the artifacts its step's new
160
+ `inputs:` key declares. Instructions refer to that context in plain
161
+ language ("clone the repository named by the `repo` parameter") rather
162
+ than splicing a value into the instruction string. Bare reference
163
+ strings (two roots, `params.<name>` and `steps.<id>.output…`) now appear
164
+ only in three frontmatter positions: `map.over`, `route.input`, and
165
+ `inputs:`.
166
+
167
+ **Gate rubrics move to the body.** A step's completion criteria are no
168
+ longer a frontmatter `gate.criteria` list or a `### Completion Criteria`
169
+ bullet section — they live under a step's `### gate` sub-heading, the
170
+ format's one reserved marker, as full prose a judge receives byte-exact.
171
+ Frontmatter `gate:` now carries only optional `max_loops` configuration.
172
+ Omitted or empty rubric text skips validation; a non-empty rubric enables
173
+ fail-open validation, and unavailable or malformed judges are skipped.
174
+
175
+ This is a **pre-1.0 change to an unshipped, opt-in feature** —
176
+ `experimental.workflowEngine` has never been enabled by default, and no
177
+ workflow asset has shipped outside the ten example workflows under
178
+ `scripts/akm-eval/example-stash/workflows/`, all rewritten to the
179
+ unified format in this change. There is nothing on disk to migrate and
180
+ no users to break.
181
+
182
+ - **akm is described as a knowledge toolkit, not a package manager** (R-048).
183
+ The npm one-liner, the README lede, and the `concepts.md` opener all led with
184
+ "a package manager for AI agent capabilities", which misstates the product to
185
+ its distribution channel and sets package-manager expectations for verbs
186
+ (`update` / `upgrade` / `sync`) that don't mean what a package manager's do.
187
+
188
+ - **BREAKING: a command group invoked with no subcommand is now always a usage
189
+ error, exit 2** (owner ruling 12). The eleven `akm <group>` groups did three
190
+ different things when invoked bare: `graph`, `config`, `env`, `secret`,
191
+ `task`, `workflow`, and `proposal` ran an implicit default action and exited
192
+ 0 (bare `akm graph` silently rendered `graph summary`); `registry`, `log`, and
193
+ `lessons` printed citty's human usage banner to stdout; only `migrate` raised
194
+ a structured error. All eleven now emit the same
195
+ `MISSING_REQUIRED_ARGUMENT` envelope on stderr, naming the available
196
+ subcommands, and exit 2 — matching STABILITY.md's exit-code table (2 =
197
+ usage) and the exit code already used for unknown commands. Matching exit
198
+ codes alone was not enough: a script could not parse the failure uniformly
199
+ while three groups answered on stdout in prose.
200
+
201
+ Migration: name the subcommand. `akm graph` → `akm graph summary`,
202
+ `akm config` → `akm config list`, `akm env` → `akm env list`, `akm secret` →
203
+ `akm secret list`, `akm task` → `akm task doctor`, `akm workflow` →
204
+ `akm workflow list --active`, `akm proposal` → `akm proposal list` (which
205
+ takes the same `--status`/`--queue`/`--ref`/`--type` flags the bare form did).
206
+
207
+ - **BREAKING: `akm sync` persists `eventType: "sync"`, not the legacy
208
+ `"save"`.** The event name now matches the command name. Historical
209
+ `state.db` rows are left as-is — `akm log` and `akm log tail` treat `"save"`
210
+ and `"sync"` as synonyms on **read**, so `akm log --type save` keeps
211
+ returning both old and new rows. Only newly written events use `"sync"`.
212
+
213
+ Migration: none for `akm log --type save`. A script matching raw event rows
214
+ by `eventType === "save"` — reading state.db directly, bypassing `akm log` —
215
+ should also match `"sync"` to see new syncs.
216
+
217
+ - **BREAKING: dropped the dead `installedKitCount` field from the `add`,
218
+ `remove`, and `update` JSON envelopes.** It was a raw lockfile-entry count
219
+ that nothing — internal code or test — ever read.
220
+
221
+ Migration: a script parsing `.config.installedKitCount` should stop; the
222
+ field is gone, not renamed. `config.sourceCount` remains and is unaffected.
223
+
224
+ - **BREAKING: dropped the dead `graphPath` field from every `akm graph *` JSON
225
+ envelope** (`summary`, `entities`, `relations`, `export`, `related`, `entity`,
226
+ `orphans`). It always resolved to the shared state.db path, never a
227
+ per-graph artifact, and carried nothing `stashPath` did not already provide.
228
+
229
+ Migration: a script reading `.graphPath` from any `akm graph` subcommand
230
+ should stop; `stashPath` remains.
231
+
232
+ - **BREAKING: `semanticSearchMode` now defaults to `"off"`.** A bare or
233
+ headless install (`akm init`, `akm setup --yes`, `akm setup --config`) was
234
+ silently downloading the ~130 MB local embedding model on its first `akm
235
+ index`, because the fallback used when the key is absent was `"auto"`. The
236
+ interactive `akm setup` wizard still pre-selects semantic search **on** — a
237
+ human is present to decide — and now shows the asset/download warning
238
+ *before* the prompt rather than after, so the pre-checked box is an informed
239
+ choice. When a remote `embedding.endpoint` is configured, enabling semantic
240
+ search downloads nothing.
241
+
242
+ Migration: existing saved configs are unaffected — the flip only changes the
243
+ fallback used when the key is absent. To keep semantic search on for a
244
+ headless or CI install, set `semanticSearchMode: "auto"` explicitly, or point
245
+ `embedding.endpoint` at a remote embedder.
246
+
247
+ - **BREAKING: `akm workflow run|brief|report` refuse to run until
248
+ `experimental.workflowEngine` is set** (0.9.0 decision Q-05). The native
249
+ workflow executor — including fan-out scheduling and worktree isolation —
250
+ is experimental, and shipping it enabled by default would have made an
251
+ unreviewed execution engine reachable from a plain `akm workflow run`. The
252
+ gated surfaces now exit `78` with a `ConfigError` naming the exact key, and
253
+ `akm task doctor` reports the gate's state. Authoring and linting the unified
254
+ markdown format, along with every other `akm workflow` subcommand, remain
255
+ ungated.
256
+
257
+ Migration: `akm config set experimental.workflowEngine true`.
258
+
259
+ - **BREAKING: the `env:<name>` / `secret:<name>` colon ref spelling is
260
+ rejected** (0.9.0 decision Q-08). Refs are slash conceptIds only — `env/foo`,
261
+ `secrets/deploy-key`. The colon form previously resolved as an undocumented
262
+ alias in some places and fell through as a literal filename in others. It now
263
+ fails with a usage error naming the slash replacement, rather than silently
264
+ doing the wrong thing.
265
+
266
+ Migration: rewrite `env:<name>` as `env/<name>` and `secret:<name>` as
267
+ `secrets/<name>`. The error message prints the exact replacement.
268
+
269
+ - **`akm improve` is review-first by default; autonomy is opt-in** (0.9.0
270
+ decision D8). The command stays ON — schedules, reflect/distill proposals, and
271
+ graph extraction are unchanged — but the lanes that mutate assets *without*
272
+ review now require `akm config set experimental.improveAutonomy true`:
273
+ memory-inference writes, the memory-cleanup pass, and triage
274
+ `applyMode: "promote"` (which downgrades to `queue` rather than disabling
275
+ triage). Consolidation remains review-oriented and is not gated.
276
+
277
+ A gated lane is never a silent no-op: it warns on stderr naming the lane and
278
+ the key, appends an `improve_skipped` event with `reason: "autonomy_gated"`,
279
+ and is counted in `akm health`'s improve skip-reason summary.
280
+
281
+ Migration: set `experimental.improveAutonomy: true` to restore the previous
282
+ behavior. `sync.push` is **not** affected — it keeps its `true` default and its
283
+ own `sync.push: false` / `--no-push` controls. Two other direct writes stay
284
+ ungated by design: `extract`'s additive session indexing and distill's
285
+ encoding-salience frontmatter stamp. Because the gate is applied before the LLM
286
+ preflight, a review-first workspace may now need fewer engines configured than
287
+ before.
288
+
289
+ Also: `akm improve` no longer rejects the global `--format`. It emits an
290
+ envelope through `output()` (always under `--dry-run`, otherwise under
291
+ `--json-to-stdout`), so `--format` applies to that envelope; progress output
292
+ stays on stderr. Previously it exited 2 with `INVALID_FLAG_VALUE`, which made
293
+ it the one command that rejected a valid global flag.
294
+
295
+ - **`akm health --report` replaces the html-only full report** (D7
296
+ follow-through). The full health report — per-run rows, trend deltas vs the
297
+ prior window, and the pending proposal queue — is now a **data** flag, not a
298
+ side effect of asking for html: `akm health --report --format html` renders
299
+ the rich report, and the identical dataset comes back under `--format json`
300
+ (previously that data was reachable only as html). The registered md/html
301
+ renderers fire on the shape of the result, and `akm health` no longer reads
302
+ `--format` at all.
303
+
304
+ Migration: `akm health --format html` → `akm health --report --format html`
305
+ (the bare form now renders the plain check generically); the html-only
306
+ `--compare` flag is removed — use `--window-compare`, which with `--report`
307
+ defaults to the `--since` window so trend deltas stay like-for-like.
308
+
309
+ - **Global output flags parse correctly next to positionals.** citty parses
310
+ each command level against only its own declared args, so a root-declared
311
+ global flag was unknown at the leaf and its space-separated value fell
312
+ through as a positional — `akm sync --format json` synced a bundle named
313
+ "json", and `akm env unset env:x KEY --format json` tried to unset a key
314
+ named "json". The global output flags (`--format`, `--detail`, `--shape`,
315
+ `--output`) are now declared on every leaf command so their values are
316
+ consumed by the parser; the two bespoke argv-inspection workarounds this
317
+ replaces are deleted. Three more non-exempt commands (`akm health`, `akm
318
+ index`, `akm lint`) now declare these flags too, purely for `--help`
319
+ visibility — all three already parsed `--format`/`--detail`/`--shape`/
320
+ `--output` correctly, since none of them has a positional a stray value
321
+ could fall into.
322
+
323
+ - **BREAKING: unknown commands and missing required arguments now exit `2`
324
+ (usage), not `1`.** citty's own command-dispatch wrapper unconditionally
325
+ called `process.exit(1)` for any error it raised before a command's own
326
+ body ever ran — `akm totally-bogus` (unknown command), bare `akm log` /
327
+ `akm lessons` (a subcommand group invoked with no subcommand), and a
328
+ command missing a required positional (e.g. bare `akm import`) all exited
329
+ `1`, contradicting the documented exit-code table (`1` = general error /
330
+ not found, `2` = usage / bad input). The CLI now drives command dispatch
331
+ directly instead of going through that wrapper, so it can reclassify this
332
+ one error family as `2` while leaving `--help`, `--version`, and every
333
+ other exit code unchanged.
334
+
335
+ Migration: a script that treated exit `1` as "something went wrong" for a
336
+ mistyped command or missing argument should check for `2` instead (or
337
+ keep treating any non-zero exit as failure, which was already correct).
338
+
339
+ - **BREAKING: `akm completions --shell <unsupported>` now exits `2` with the
340
+ standard JSON error envelope, not `1` with a raw stack trace.**
341
+ `completions` stays format-exempt (its own output is shell-script source,
342
+ not a result envelope — see STABILITY.md), but its body is now wrapped in
343
+ the same error-classification path every other command uses.
344
+
345
+ Migration: a script parsing this failure should now expect
346
+ `{"ok":false,"error":"...","code":"INVALID_FLAG_VALUE","hint":...}` on
347
+ stderr and exit code `2` in place of a stack trace and exit code `1`.
348
+
349
+ - **BREAKING: `akm index --dry-run` without `--clean` now exits `2` instead
350
+ of running a real index.** The flag only ever gated the `--clean`
351
+ stale-entry removal pass — every other phase (walk, LLM enrichment,
352
+ embeddings, FTS, the adapter-detection config write) ran for real
353
+ regardless, so `akm index --dry-run` alone silently performed a full index
354
+ despite its name. The combination is now rejected with the standard usage
355
+ envelope instead of quietly doing something other than what "dry run"
356
+ promised.
357
+
358
+ Migration: a script or cron invoking bare `akm index --dry-run` was
359
+ already getting a real index, so nothing there needs to change in effect —
360
+ but it will now fail loudly instead. Pass `akm index --clean --dry-run` to
361
+ preview the stale-entry removal pass, or `akm index --clean` to apply it;
362
+ drop `--dry-run` entirely to keep running a plain real index.
363
+
364
+ - **BREAKING: a corrupt or unparseable `akm.lock` now makes lockfile WRITES
365
+ throw, instead of silently destroying every entry.** The previous lenient
366
+ reader returned `[]` on unparseable JSON; a write path that upserted a
367
+ single entry onto that `[]` then overwrote the file, permanently deleting
368
+ every other tracked bundle's lock entry. Install/update/remove write paths
369
+ now use a strict reader that throws on the same corruption instead of
370
+ reaching the destructive overwrite.
371
+
372
+ Migration: if a write now fails with a lockfile-parse error, `akm.lock` is
373
+ genuinely corrupt — inspect and repair it by hand, or restore it from a
374
+ backup (e.g. git history), before retrying the write. Reads elsewhere are
375
+ unaffected; the lenient read contract is unchanged.
376
+
377
+ - **BREAKING: `AKM_NPM_REGISTRY` now redirects npm package METADATA lookups,
378
+ not just the trusted-tarball allowlist.** Previously the override only
379
+ widened which tarball hosts were trusted for download while metadata
380
+ queries stayed hardcoded to `registry.npmjs.org`, so a configured private
381
+ mirror was never actually consulted for package info — the error hint that
382
+ points users at this variable was false. The override now also replaces
383
+ the metadata registry base, matching how a private npm registry is meant
384
+ to work (like npm's own `--registry` flag: wholesale replacement, not a
385
+ merge with the public registry).
386
+
387
+ Migration: an operator who set `AKM_NPM_REGISTRY` expecting only tarball
388
+ downloads to be redirected, with metadata still served from the public
389
+ registry, should confirm the mirror actually serves equivalent package
390
+ metadata — `akm add`/`akm update` for npm-sourced bundles now resolve
391
+ entirely against the configured mirror when it is set.
392
+
393
+ - **`akm remember --show-similar` and `akm migrate apply --dry-run` are the
394
+ documented, canonical spellings** (previously `--showSimilar` /
395
+ `--dryRun`), matching every other multi-word flag in the CLI. Not a
396
+ breaking change: citty registers both the camelCase and kebab-case
397
+ spelling of any declared flag name automatically, so `--showSimilar` /
398
+ `--dryRun` keep working — they're now explicit, documented aliases instead
399
+ of an undocumented accident.
400
+
401
+ - **`--detail` and `--shape` help text is scoped honestly.** The per-command
402
+ `--detail` description now names `info`, `list`, and `remember` as the
403
+ commands where it has no effect (verified byte-identical output at every
404
+ level — `akm show` is not one of these; it has three distinct
405
+ brief/normal/full payloads). `--shape`'s per-command help now repeats the
406
+ "`summary` is only valid on `akm show`" caveat the root help already
407
+ documented.
408
+
409
+ - **All six `--format` values work on every command** (0.9.0 decision D7).
410
+ `json|jsonl|yaml|text|md|html` are now universal. Previously there were three
411
+ inconsistent behaviours: `md` silently emitted the JSON envelope everywhere
412
+ except `akm health`, `html` was rejected with exit 2 everywhere except
413
+ `akm health`, and `akm health` reached neither because it intercepted the
414
+ format itself. Rendering is now registry-driven — a command may register a
415
+ renderer for a document format, and anything unregistered falls back to a real
416
+ rendering of its own envelope (headings, tables for arrays of uniform objects,
417
+ lists otherwise). `akm health` keeps its per-run/window-compare tables and its
418
+ full HTML report by registering them; the output is unchanged.
419
+
420
+ Migration: none required for `json|jsonl|yaml|text`. `--format md` on a
421
+ non-health command previously returned JSON and now returns Markdown; a script
422
+ that parsed that JSON should ask for `--format json` explicitly. `--format
423
+ html` previously exited 2 on non-health commands and now succeeds.
424
+
425
+ Also: `akm graph export --format` is **removed** — it declared `--format`
426
+ locally as well as globally (one token, two parsers). The artifact payload
427
+ now follows the `--out` extension (`--out g.jsonl` writes JSONL, anything
428
+ else JSON); the global flag only renders the command's own envelope. A dead
429
+ local `--format` declaration on `akm history` was removed too (it was never
430
+ read). Commands
431
+ whose output is not an envelope (`completions`, `setup`, `env run`,
432
+ `secret run`, `agent`, `workflow template`, `help migrate`) are declared
433
+ format-exempt in `src/output/format-exempt.ts` and now warn when given
434
+ `--format` instead of ignoring it silently. `output.format` in config accepts
435
+ all six values.
436
+
437
+ - **Subtree browse is a conceptId prefix, not `<type>:`** (0.9.0 decision D4).
438
+ `akm search` enumerates on `memories/`, `memories/projecta/`, `bundle//`, and
439
+ `bundle//skills/`; a trailing `/` is still required. The prefix now matches the
440
+ **conceptId** rather than the item name, so a ref copied out of search output
441
+ can be truncated to a prefix and pasted straight back in — previously that
442
+ round-trip degraded silently into a keyword search. Enumeration no longer
443
+ validates against the `akm` adapter's placement types, so items from every
444
+ adapter browse the same way, and `bundle//` lists a whole bundle (the
445
+ replacement for the removed `akm bundle items`).
446
+
447
+ Migration: `akm search "memory:"` → `akm search "memories/"`;
448
+ `akm search "memory:projectA/"` → `akm search "memories/projectA/"`;
449
+ `akm search "session:"` → `akm search "sessions/"`. The retired spelling is
450
+ now an ordinary keyword search; when it returns nothing, the tip names the
451
+ conceptId spelling that replaces it. `scripts/lint-shipped-assets.ts` no
452
+ longer exempts the old spelling, so it is an offense in agent-facing assets.
453
+
454
+ - **`akm task sync [--bundle <bundle>]` reconciles a single bundle.** Sync now
455
+ attributes each installed scheduler entry to its bundle (parsed from the
456
+ `--bundle` token; absent ⇒ primary) and reconciles only the entries for the
457
+ bundle being synced. A plain (primary) sync never installs from, updates, or
458
+ removes another bundle's entries, and sync never scans all bundles — task
459
+ activation stays explicit (`add --bundle` or `sync --bundle`), so registering a bundle
460
+ still never activates code. When the target is the default bundle (or omitted),
461
+ installed scheduler entries are byte-identical to before, so upgrading shows no
462
+ spurious drift.
463
+
464
+ - **The R2 salience ranking boost no longer applies to default `search`/`curate`
465
+ ranking** (#692). `asset_salience.rank_score` (an encoding + outcome +
466
+ retrieval projection, recomputed every `improve` run) previously composed
467
+ into every default search as a bounded multiplicative boost
468
+ (`salience-ranking`, ×[1.0–1.2]), loaded best-effort from `state.db` on the
469
+ hot path. On live data it measured as noise (max observed multiplier
470
+ ×1.071, mean ×1.016): the boost was retrieval-dominated with no source
471
+ filter — double-counting the same `usage_events` the utility-score
472
+ contributor already reinforces — warm-started non-zero with no outcome
473
+ evidence, and had zero pack coverage, so it could only ever favor
474
+ self-generated personal assets over an equally-relevant pack asset.
475
+ Removing the default `state.db` load also fixes a confirmed hot-path
476
+ defect: whenever `state.db` already existed, every default search
477
+ synchronously waited on the maintenance-activity barrier before ranking
478
+ could even start — up to a 5-second stall on a blocking wait loop, plus a
479
+ lock-file create, before the load's own 250ms SQLite `busy_timeout` ever
480
+ applied. No config gate was added: a key for a term being removed would be
481
+ dead surface for the upcoming 1.0 contract freeze to carry forever.
482
+ `rank_score` itself, and everything `improve` computes and does with it
483
+ internally, are unchanged — only its promotion into user-facing ranking is
484
+ removed. The contributor stays in the codebase (unwired) for a future
485
+ gated, outcome-backed experiment.
486
+
487
+ - **Internal: `asset_salience` / `asset_outcome` state.db access moved behind
488
+ `src/storage/repositories/{salience,outcome}-repository.ts`** (#672 part 2).
489
+ Mirrors the existing state.db repository precedents
490
+ (`proposals-repository.ts`, `improve-runs-repository.ts`,
491
+ `events-repository.ts`): the raw SQL, row-mapping, and the #644
492
+ encoding-provenance CASE guards are extracted verbatim, only relocated —
493
+ `commands/improve/salience.ts` and `outcome-loop.ts` re-export the moved
494
+ functions, so no importer or test churns. A new `state-table-sql` rule in
495
+ `scripts/lint-repository-sql.ts` now fails the build if raw
496
+ `asset_salience`/`asset_outcome` SQL reappears outside the repository
497
+ directory (or `core/state/migrations.ts`). Not a user-visible behavior
498
+ change: `rank_score`, `outcome_score`, and everything `improve`/`health`
499
+ compute from them are identical.
500
+
501
+ ### Fixed
502
+
503
+ - **The compiled standalone binary can run `akm migrate`.** Release binaries
504
+ compiled only `src/cli.ts`, and the migrator was resolved as a sibling file
505
+ and spawned — neither candidate exists inside a compiled executable, so the
506
+ documented `./akm-0.9 migrate status/apply` upgrade path always failed with
507
+ `FILE_NOT_FOUND`. Standalone builds now compile `scripts/akm-standalone.ts`,
508
+ a wrapper that embeds both the CLI and the migrator (src never imports
509
+ scripts/ — the dist build's tsc forbids it); `akm migrate` re-execs the
510
+ binary with an `AKM_MIGRATE_ENTRY` marker the wrapper dispatches on. The
511
+ repo and npm layouts keep the subprocess path.
512
+
513
+ - **Quarantined migration rows are retained in full, not reduced to a count.**
514
+ When the 0.8→0.9 cutover met a durable ref it could not map, it recorded
515
+ surface/ref/count in `legacy_state` and then deleted the rows — destroying
516
+ proposal payloads, event and task history, fingerprints, and canary anchors,
517
+ contrary to the migration guide's "quarantined, not dropped". Complete rows
518
+ are now preserved as JSON in `legacy_state_rows` before leaving the live
519
+ tables.
520
+
521
+ - **A failed content migration fails the apply instead of reporting success.**
522
+ Root discovery, sidecar folding, or the legacy-proposal import throwing was
523
+ swallowed and logged; the apply then advanced and cleared its journal, and —
524
+ because 0.9 removed the live `.stash.json` and filesystem-proposal readers —
525
+ the affected metadata and pending proposals became permanently inaccessible
526
+ behind an apparently successful upgrade. The step now fails the apply with
527
+ the journal intact; the committed cutover is untouched and the next apply
528
+ retries.
529
+
530
+ - **Sidecar provenance survives the fold.** Folding a `.stash.json` into
531
+ frontmatter dropped `xrefs` and `sources` entirely and mapped legacy
532
+ `sourceRefs` to a `source_refs` key that could never fire (the validator
533
+ stopped copying the field) and that 0.9 never reads — then deleted the only
534
+ copy. `xrefs`/`sources` now fold through, and legacy `sourceRefs` merge into
535
+ `xrefs`.
536
+
537
+ - **A reserved-filename rename re-keys durable state.** The D-R6 rename of a
538
+ mis-named `index.md`/`log.md` concept ran after the cutover had keyed usage,
539
+ salience, and proposal rows to the old conceptId, stranding that learned
540
+ state. The rename now feeds the same re-key engine the cutover uses, with
541
+ the pairs persisted before re-keying so a crash between the two stays
542
+ retryable.
543
+
544
+ - **v1 tasks in a read-only bundle are surfaced with a remedy instead of being
545
+ silently skipped.** The 0.9 runtime removed the v1 task parser, so silently
546
+ skipping a `writable: false` bundle left tasks that would start failing after
547
+ an upgrade that reported current. The preflight now warns per bundle and
548
+ lists the stranded files in the plan (`readOnlyLegacyTasks`). It does not
549
+ block the apply: the migration deliberately never rewrites a read-only
550
+ bundle, and the fix for a lock-materialized git/npm bundle belongs upstream.
551
+
552
+ - **Lock resolution metadata survives migration.** Merging the migrator's
553
+ sparse lock entries replaced whole rows by id, discarding
554
+ `resolvedVersion`/`resolvedRevision`/`integrity`/`installedAt` recorded by a
555
+ real install. Merge now preserves existing fields the incoming entry does
556
+ not define.
557
+
558
+ - **Migrating a pre-0.9 config no longer silently changes source policy.**
559
+ Three settings were dropped by the config-shape migration: an explicit
560
+ `writable: false` (an omitted filesystem `writable` reads as `true` in the
561
+ new shape, so a source the user deliberately protected became writable), an
562
+ explicit `enabled: false` (resuming refreshes and indexing for content the
563
+ operator had turned off), and a website source's `maxDepth` (silently
564
+ resetting crawl depth). All three now round-trip to the runtime source entry;
565
+ `bundles.<id>.enabled` is a supported key.
566
+
567
+ - **`akm mv` refuses a bundle marked `writable: false`.** It renamed the file
568
+ and rewrote citers anyway, because its preflight checked adapter
569
+ compatibility rather than writability — every other write command already
570
+ refused.
571
+
572
+ - **Memory belief edges written by `--supersedes` are no longer ignored.**
573
+ `writeSupersededEdge` persists a fully-qualified conceptId, but the belief
574
+ analyzer accepted only the internal `memory:<name>` spelling, so every edge
575
+ from `akm remember --supersedes` / `akm import --supersedes` was dropped and
576
+ a superseded memory read back as active.
577
+
578
+ - **`akm env run <ref> -- <cmd> --help` runs the command.** The builtin
579
+ help-flag scan read the child tail after `--` and printed akm's own usage
580
+ instead.
581
+
582
+ - **`akm mv` works under an `AKM_STASH_DIR` override again.** A valid override
583
+ not owned by a configured bundle failed with `No configured bundle owns move
584
+ source`.
585
+
586
+ - **An unexpected internal error exits 70 with the JSON failure envelope.** The
587
+ residual dispatch boundary exited 1 with an unstructured message, so
588
+ automation could not tell an internal defect from an ordinary failure.
589
+
590
+ - **Concurrent `akm config set` processes no longer give up prematurely.** The
591
+ contended-lock wait budget was 500ms total, so several concurrent writers on
592
+ a loaded machine could exhaust it and fail with "Timed out waiting for config
593
+ lock" against a healthy but busy lock. Abandoned locks are still reclaimed by
594
+ the stale probe, which this budget does not gate.
595
+
596
+ - **Config keys named in indexer output and comments now exist.** Four sites
597
+ pointed at a top-level `llm.*` namespace that the config schema has no such
598
+ key for — including the user-facing "Increase llm.timeoutMs" warning on an
599
+ exceeded enrichment budget. The enrichment budget lives at
600
+ `index.enrichment.timeoutMs` (or `index.defaults.timeoutMs`). Indexing
601
+ concurrency is auto-derived (2 remote / 1 local) and currently has no config
602
+ override on that path: `engines.<name>.concurrency` is a valid schema field
603
+ but the engine resolver does not forward it (documented in
604
+ `docs/architecture/internals/indexing.md`).
605
+
606
+ - **The bundle-identity-drift warning stops naming a command that doesn't
607
+ exist.** It told users to "rekey it atomically via the bundle-rename
608
+ command"; 0.9.0 ships no such command. It now gives the two remedies that
609
+ work: restore the previous bundle id in `config.json`, or keep the new id and
610
+ `akm index --full` to re-mint, accepting the loss of learned state keyed to
611
+ the old id.
612
+
613
+ - **The scaffolded `organization.md` convention no longer contradicts `akm
614
+ mv`.** It told authoring agents "there is no command that preserves an
615
+ asset's identity or learned state" across a rename and showed a raw `mv`.
616
+ `akm mv` does exactly that — it rewrites inbound refs and re-keys the index
617
+ row, usage history, and state.db salience/outcome rows. The convention now
618
+ points at it, flagged Experimental.
619
+
620
+ - **`setup.taskSchedules` is no longer documented.** The key was removed from
621
+ the schema in 0.9.0 (nothing ever read or wrote it), but
622
+ `docs/reference/configuration.md` still described its two sub-keys.
623
+
624
+ - **A freshly scaffolded stash passes its own `akm lint`.** All 12 shipped
625
+ `facts/conventions/**` convention templates carry frontmatter but none
626
+ carried an `updated` field, so the first `akm lint` after `akm init` flagged
627
+ 12 `missing-updated` issues on files the user never wrote. The templates now
628
+ ship the field, and a regression test lints a freshly scaffolded stash and
629
+ requires nothing flagged.
630
+
631
+ - **`akm show akm//meta` is the documented spelling for the primary stash.**
632
+ `docs/reference/cli.md` and `docs/guides/concepts.md` showed
633
+ `akm show local//meta`, which errors with `ASSET_NOT_FOUND` — `local//` is no
634
+ longer a scoping prefix, so it reads as a bundle named `local`.
635
+
636
+ - **`akm sync` emits `shape: "sync"`.** The envelope kept the `"save"` shape
637
+ from the command's pre-rename name even after the persisted `eventType` was
638
+ renamed. Unlike the event log, the shape is per-invocation and never
639
+ persisted, so it needs no read-side synonym.
640
+
641
+ - **`akm add <pkg> --provider npm` adds an npm source instead of a broken
642
+ filesystem bundle.** `--provider` was only read inside the remote-URL branch,
643
+ so any non-URL target fell through to the filesystem path with the flag
644
+ ignored, producing a bundle pointed at `<cwd>/<pkg>`. A URL target with
645
+ `--provider npm` is now rejected at add time rather than storing the URL as a
646
+ package spec and failing much later at first sync.
647
+
648
+ - **`akm add --provider` no longer prints `Installed undefined`.** Two
649
+ incompatible result shapes reached one text formatter; each is now rendered
650
+ honestly, including whether a follow-up `akm update` or `akm index` is needed.
651
+
652
+ - **`akm update --all` accounts for every configured source.** It previously
653
+ considered only registry-managed installs and reported `nothing to update`
654
+ for a stash full of plain sources — nothing was updated because nothing was
655
+ looked at. Plain git and npm sources are now synced (npm is promoted to a
656
+ lock-backed install on first sync) and website/filesystem sources are
657
+ reported through a new `skipped` field with the reason. A successful update of
658
+ a plain source no longer renders as `nothing to update` either.
659
+
660
+ - **`akm search` with no query browses**, as `--help` has always documented,
661
+ instead of exiting 2.
662
+
663
+ - **`akm curate --type <t>` curates within the type instead of bypassing
664
+ curation.** The filter skipped ranking, intent nudges, the score floor, and
665
+ family collapse entirely — and could return a hit of the *wrong* type while
666
+ dropping a higher-scoring correct one.
667
+
668
+ - **`akm curate` respects `--limit` for registry hits**, which were capped at a
669
+ hard-coded 2 regardless.
670
+
671
+ - **`akm search --no-project-context` works.** citty strips a leading `--no-`
672
+ before consulting declared args, so a flag *declared* as `no-project-context`
673
+ could never be set — the ranking boost was identical with and without it. The
674
+ flag users type is unchanged.
675
+
676
+ - **`akm env run`, `akm secret run`, `akm migrate`, `akm agent`, `akm proposal new`,
677
+ `akm task run`, and `akm improve` no longer skip cleanup on exit.** They
678
+ called `process.exit()` directly — in two cases even on success — bypassing
679
+ teardown of spawned subprocesses. Exit codes, including forwarded non-zero
680
+ child codes, are unchanged.
681
+
682
+ - **The `blocked` semantic-search warning names the cause.** It emitted one
683
+ fixed string for every failure and discarded the status ledger's reason, so
684
+ "no embedding provider configured" and "the configured endpoint is failing"
685
+ read identically.
686
+
687
+ - **Shell completion for `--source` no longer suggests `stash|registry|both`
688
+ on commands where that enum doesn't apply.** `--source` means a closed
689
+ `stash|registry|both` enum on `akm search`/`akm curate`, but a free-form
690
+ stash name/path on every `akm graph` subcommand and a free-form URL/ref/
691
+ path on `akm remember`. The generated completion script keyed its value
692
+ list by flag name only, so the search/curate enum leaked onto `akm graph
693
+ --source <TAB>` and `akm remember --source <TAB>`. Value completion is now
694
+ scoped per command path; commands without a fixed value set get no
695
+ suggestion instead of the wrong one.
696
+
697
+ - **`akm setup --config <file>` / `--from <file>` no longer silently drops
698
+ six valid config keys** (`index`, `search`, `feedback`,
699
+ `archiveRetentionDays`, `workflow`, `experimental`). The allowlist was a
700
+ hand-copied set that had drifted out of sync with the config schema; a
701
+ user handing setup a config containing any of these keys got a different,
702
+ silently truncated config written back, with only a warning and exit `0`.
703
+ The allowlist is now derived from the schema's own key list so it cannot
704
+ drift again. Keys that remain genuinely retired (`profiles`, `llm`,
705
+ `agent`, `features`, `stashes`, `bindings`, `writable`) still warn-and-drop
706
+ as before.
707
+
708
+ Note: a config that previously relied on one of these six keys being
709
+ ignored (because the drop was silent) will now have it applied — re-check
710
+ `--config`/`--from` inputs if you were unknowingly depending on that gap.
711
+
712
+ - **`akm index` no longer persists adapter auto-detection to `config.json`
713
+ with zero disclosure.** Detecting and writing a bundle component's adapter
714
+ (`bundles.<id>.components.<component>.adapter`) previously happened
715
+ silently on every index run. It is now reported in the result envelope as
716
+ an additive `configUpdated.detectedAdapters` map and on stderr, and only
717
+ when a write actually happened.
718
+
719
+ - **`akm add owner/repo` now resolves as GitHub shorthand instead of failing
720
+ with "Local path not found".** Any ref containing a `/` was treated as an
721
+ explicit local path, so the local-ref resolver threw before the
722
+ GitHub-shorthand fallback ever ran, making the advertised `owner/repo` form
723
+ unreachable. A bare two-segment `owner/repo` (or `owner/repo#ref`) now
724
+ falls through to the registry resolver when no such directory exists on
725
+ disk; `./`, `../`, absolute, and three-or-more-segment paths still resolve
726
+ as explicit local paths exactly as before.
727
+
728
+ - **Internal output-shape command keys renamed `events-list`/`events-tail` →
729
+ `log-list`/`log-tail`**, matching the `akm log` command they back (the
730
+ command group used to be `akm events`, removed in 0.9.0). Internal-only:
731
+ the shape name is a registry lookup key that never reaches the wire (no
732
+ output field, no schema change), so this is not a user-visible behavior
733
+ change and carries no `schemaVersion` bump. The documented `[events-tail]`
734
+ stderr trailer text is deliberately left as-is pending a separate ruling.
735
+
736
+ ### Removed
737
+
738
+ - **BREAKING: `akm upgrade --skip-checksum` is removed.** STABILITY.md has
739
+ always said checksum verification is not optional and that the recovery hatch
740
+ is an environment variable — but the flag shipped anyway, tab-completable,
741
+ while the documented variable existed nowhere in the source. The code now
742
+ matches the spec: set `AKM_UPGRADE_SKIP_CHECKSUM=1` if you must bypass a
743
+ genuinely broken `checksums.txt`. It is deliberately undiscoverable.
744
+
745
+ - **BREAKING: `akm config enable|disable` is removed.** It was a hard-coded
746
+ toggle for one target, the skills.sh registry, and the bare `akm enable` /
747
+ `akm disable` aliases were already removed in 0.9.0. Use
748
+ `akm registry add|remove`.
749
+
750
+ - **BREAKING: `akm mv` is removed.** No alias, no stub — `akm mv …` fails with
751
+ the standard unknown-command error. It claimed to preserve identity across a
752
+ rename, but its inbound-ref rewrite matched bare conceptIds rather than the
753
+ anchored `bundle//conceptId` prose form, so it could rewrite ordinary prose
754
+ while leaving real refs dangling. Renames are delete + create per
755
+ `STABILITY.md`: move the file, `akm index`, `akm lint`. The one capability
756
+ nothing else covered — carrying an asset's earned signal across the rename —
757
+ moves to `bun scripts/rekey-asset-ref.ts <old-ref> <new-ref>` (maintainer
758
+ tooling, `--dry-run` supported, idempotent), which re-keys the index
759
+ `entries` row in place plus the `asset_salience` / `asset_outcome` /
760
+ `usage_events` rows. The `mv` event type and output shape are gone; the
761
+ script emits a `rekey` event instead. A leftover `kind:"mv"` transaction
762
+ journal from an rc build is now swept by the recovery scanner rather than
763
+ failing it — an unregistered journal kind no longer bricks index refresh or
764
+ proposal accept/reject.
765
+
766
+ - **The CHURN alert class is removed from the collapse detector.** Its input was
767
+ a hard-coded `0` from the 0.9.0 confidence-gate deletion onward, so the alert
768
+ could never fire. The other three alert classes are unaffected. The
769
+ `improve_cycle_metrics.accepted_actions` column stays and is written as `0`:
770
+ it lives in a released migration body, and 0.8 ships `state.db`, so a deployed
771
+ ledger can already have sealed that body's checksum.
772
+
773
+ - **`IndexResponse.graphQuality` is removed** from the `akm index` envelope — it
774
+ was declared but never assigned in any code path, so it was always absent.
775
+
776
+ - **`akm secret path` and `akm secret remove` are removed.** The two resolved a
777
+ secret ref through *different* stash-selection logic — `path` through the
778
+ read-side, all-sources resolver and `remove` through the write-target
779
+ resolver — so for a ref present in more than one stash they could name
780
+ different files: you could inspect one secret and delete another. Rather than
781
+ reconcile the resolvers, both subcommands are gone; `akm secret` now exposes
782
+ only `list`, `run`, and `set`. Both spellings exit 2 with `Unknown command`.
783
+
784
+ Migration: a ref's file lives at `<stash>/secrets/<name>` (run `akm sources
785
+ list` for stash roots) — locate or delete it directly, or use `akm secret run
786
+ <ref> <VAR> -- <command>` to consume the value without it touching disk. `akm
787
+ env path` and `akm env remove` are unaffected.
788
+
789
+ - Removed the dead `"backup"` output-shape registration left over from the
790
+ removed `akm backup` command (superseded by `akm-migrate backup`). Already
791
+ unreachable; no user-visible effect.
792
+
793
+ - **`akm task list`, `akm task show`, and `akm task remove` are removed** as
794
+ redundant with the generic asset commands. List and inspect tasks with `akm
795
+ search` / `akm show <bundle//tasks/id>` (both already cross-bundle); to remove a
796
+ scheduled task, delete its file in the owning bundle and run `akm task sync`
797
+ (sync uninstalls the orphaned scheduler entry). Run `akm task doctor` for
798
+ scheduler diagnostics — bare `akm task` is a usage error, see the canonical
799
+ bare-group change above.
800
+
801
+ - **The `akm show <ref> toc|section|lines|frontmatter|full` view-mode grammar is
802
+ removed** (0.9.0 decision D2). `#fragment` is now the only section selector,
803
+ and a positional after the ref is a usage error that names it. Migration:
804
+
805
+ | Old | New |
806
+ | --- | --- |
807
+ | `akm show knowledge/guide section "Auth"` | `akm show knowledge/guide#auth` |
808
+ | `akm show knowledge/guide full` | `akm show knowledge/guide` |
809
+ | `akm show knowledge/guide toc` | `akm show knowledge/guide#<unmatched>` — the error lists the available fragment slugs |
810
+ | `akm show knowledge/guide lines 10 30` | no replacement — every response carries `path`, so slice the file yourself |
811
+ | `akm show knowledge/guide frontmatter` | no replacement — if a raw-YAML projection proves necessary it returns as a `--shape` value |
812
+
813
+ The undocumented `--akmView` / `--akmHeading` / `--akmStart` / `--akmEnd`
814
+ flags the grammar injected into argv are gone with it.
815
+
816
+ ## [0.9.0] (planned)
817
+
818
+ 0.9.0 is the format-neutral **bundle / adapter** refactor: it replaces the flat
819
+ asset-type registry with per-format adapters, adopts one canonical ref grammar,
820
+ and consolidates the durable databases and config. This section supersedes the
821
+ earlier `0.9.0-rc.1` / `0.9.0-beta.*` development entries below.
822
+
823
+ ### Breaking changes & migration
824
+
825
+ - **Installed non-akm bundles reclassify on your next `akm index`.** The
826
+ indexer now dispatches each installed bundle's *detected* adapter (Claude
827
+ tool dirs, LLM wikis, website snapshots, agent-skills packs, …) instead of
828
+ recognizing everything with the akm-stash adapter. Entries in such bundles
829
+ change type and ref spelling to the owning adapter's own scheme the first
830
+ time you reindex. No action needed — the index is a regenerable cache and
831
+ rebuilds itself — but searches/saved refs into those bundles may resolve to
832
+ the new spellings afterwards.
833
+ - **Ref grammar cutover — `type:name` → `[bundle//]conceptId`.** Every ref is
834
+ now a subdir-qualified concept id inside its bundle (`skills/code-review`,
835
+ `memories/vpn-note`, `env/prod`), optionally prefixed with a `bundle//`
836
+ installation slug and suffixed with `#fragment`. Durable state stores the
837
+ fully-qualified `bundle//conceptId`; the short bundle-omitted form is accepted
838
+ input only (resolved against `defaultBundle`, then installation-priority
839
+ order). The pre-0.9.0 `[origin//]type:name` grammar is removed — there is no
840
+ compatibility parser; the frozen migrator in `scripts/akm-migrate/migrate/`
841
+ is the only place it survives.
842
+ - **Explicit, journaled, crash-resumable cutover (`akm migrate apply`).** The
843
+ migrator re-keys all durable state to the new spelling, folds the former
844
+ `workflow.db` into `state.db` (four databases down to three: `state.db` /
845
+ `index.db` / a separate `logs.db`), and migrates config from the flat
846
+ `stashDir` / `sources` / `installed` / `wikiName` keys to `bundles` /
847
+ `defaultBundle`. A verified, installation-scoped **backup manifest v3**
848
+ (covering the pre-rescue `index.db`) is taken before any ledger is sealed;
849
+ expected orphans are quarantined, integrity failures fail closed, and the
850
+ whole cutover resumes idempotently after a crash. Normal commands refuse an
851
+ un-migrated or divergent durable schema rather than migrating as a side effect.
852
+ The retired `stashDir` / `sources` / `installed` keys are **hard-rejected** by
853
+ the 0.9.0 config schema whenever present (the error names `akm migrate apply`);
854
+ registry-installed bundles keep only their desired locator (`git`/`npm` +
855
+ `registryId`) in config, with resolved cache state living exclusively in the
856
+ lockfile.
857
+ - **`index.md` / `log.md` are reserved structural files.** Per the Open
858
+ Knowledge Format, `index.md` (directory listing) and `log.md` (update history)
859
+ are never indexed as concepts and are never valid write / `mv` targets at any
860
+ bundle depth. Existing stash files with those names are excluded from the
861
+ index (and renamed by the content migration when they hold a real concept).
862
+ - **`vault` asset type removed.** Use `env` (a whole `.env` group; key names
863
+ surfaced, values never) and `secret` (a single sensitive value), addressed as
864
+ `env/<name>` and `secrets/<name>`. `akm-migrate storage` performs the
865
+ non-destructive `vaults/` → `env/` copy for older stashes.
866
+ - **0.8-era CLI aliases removed.** The flat proposal verbs (`akm proposals`,
867
+ `akm accept`, `akm reject`, `akm diff`, `akm revert`, `akm show proposal`),
868
+ `akm save`, top-level `akm enable` / `akm disable`, `akm events`,
869
+ `--detail summary|agent`, `--for-agent`, `--note`, and `--source` (on
870
+ accept/reject/history) are gone — use the canonical spellings documented in
871
+ `STABILITY.md`.
872
+
873
+ See `docs/migration/v0.8-to-v0.9.md` and
874
+ `docs/migration/release-notes/0.9.0.md` for the full upgrade procedure.
875
+
876
+ ### Added
877
+
878
+ - **Local downstream value attribution for memory inference and graph
879
+ extraction.** Private search-hit sidecars now write versioned, source-qualified
880
+ per-entry `usage_events.metadata` for emitted MI direct/surface value and the
881
+ active graph contributor's positive applied/capped contribution. Current plain
882
+ traffic is marked as control, brief/replaced MI surfaces and graph ablations do
883
+ not claim attribution, and nested curate reads avoid duplicate show rows. The
884
+ read-only `akm-eval-attribution-rollup` separates user-only exposure,
885
+ selection/show consumption, current controls, and historical unattributed rows
886
+ without emitting bodies, query text, or provenance content. Graph contribution
887
+ is an input attribution signal, not a causal claim that rank changed. No table,
888
+ migration, dashboard, or health schema was added.
889
+ - **Explicit, crash-resumable 0.9 migration coordination.** `akm migrate
890
+ status` classifies config, `state.db`, and `workflow.db` independently;
891
+ `akm migrate apply [--config <prepared>]` creates a verified,
892
+ installation-scoped backup before sealing ledgers or applying pending
893
+ migrations. Apply and restore use authenticated phase journals, exact
894
+ artifact fingerprints, bounded streaming I/O, SQLite integrity checks,
895
+ active-writer barriers, WAL/SHM-safe publication, and idempotent recovery.
896
+ Routine reads and current database opens no longer depend on a historical
897
+ cutover bundle. See `docs/migration/release-notes/0.9.0.md`.
898
+ - **Workflow orchestration engine (experimental).** akm can now execute
899
+ multi-step workflows through a native engine or any agent session. Workflow
900
+ assets use the unified markdown format described above; the stable manual
901
+ CLI contract (`start`/`next`/`complete`/`status`/`list`) and the experimental
902
+ engine consume the same asset. What ships:
903
+ - **Authoring.** A workflow is a markdown asset whose frontmatter graph is
904
+ validated against `schemas/akm-workflow.json` and whose `## <step-id>` body
905
+ sections carry instructions and gate rubrics. `akm workflow create`
906
+ scaffolds that format; `akm lint --type workflows` parses and compiles it.
907
+ Bare references (`params.<name>` and `steps.<id>.output.<path>`) wire
908
+ `map.over`, `route.input`, and `inputs`; prose is never interpolated.
909
+ - **Compilation + frozen plans.** `akm workflow start` compiles the workflow
910
+ into a backend-agnostic Workflow Plan Graph IR (`src/workflows/ir/`) and
911
+ freezes it on the run row (`plan_json` + `plan_hash`); a run executes the
912
+ plan compiled at start, and edits to the source file require a new run.
913
+ - **Per-step orchestration.** A step can declare an engine, model, timeout,
914
+ fan-out (`map`/`over` with a `concurrency` cap and a `collect` | `vote`
915
+ reducer), a typed `output` JSON Schema (validated via a `runStructured`
916
+ retry-with-feedback loop), `env` bindings (resolved through the existing
917
+ `akm env run` machinery — secret tokens, dangerous-key policy, keys-only
918
+ audit events), and classify-and-dispatch `route` steps.
919
+ - **Determinism + replay.** Journaled unit identity is content-derived
920
+ (`<step>:<sha256(item)[:12]>`, `:solo` for a single unit), so cached
921
+ results survive item-list reordering; a completed unit whose recorded
922
+ inputs differ on replan is a hard **replay-divergence** failure naming the
923
+ unit, never a silent re-dispatch. Every unit is recorded in the new
924
+ `workflow_run_units` table behind a serialized writer queue.
925
+ - **Execution (`akm workflow run`).** A semaphore-bounded scheduler fans a
926
+ step's units out (concurrency defaults to 1 per the local-model
927
+ LLM-defaults rule and is the minimum of the map request, frozen workflow
928
+ limit, selected frozen LLM engine limit, and current host safety limit),
929
+ enforces per-unit
930
+ timeouts (default 10 m) and run **budget ceilings** (`budget.max_tokens` /
931
+ `budget.max_units`, seeded from the journal so they span resumes), and
932
+ advances the run **strictly through `completeWorkflowStep`** so completion
933
+ gates are never bypassed. Every dispatched unit gets a standard akm
934
+ preamble (run/unit ids, knowledge + env/secret + reporting contract).
935
+ - **Typed artifacts + honest gates.** A step's promoted artifact is
936
+ validated against its declared `output` schema before completion; a
937
+ criteria-bearing gate judges that **artifact** (canonical JSON, clipped)
938
+ rather than machine prose, and each engine-driven evaluation is journaled
939
+ as a gate unit row. `gate.max_loops` bounds an evaluator-optimizer retry
940
+ loop (feedback threaded into re-dispatched unit prompts). Gates are
941
+ optional validation: omitted/empty rubrics and unavailable or malformed
942
+ judges skip validation.
943
+ - **Failure policy.** Per-unit `on_error: fail | continue` (fail-fast
944
+ default) plus bounded `retry: { max, on: [<failure_reason>…] }` keyed on
945
+ the persisted failure taxonomy.
946
+ - **Isolation + leases.** `isolation: worktree` runs each file-mutating unit
947
+ in a fresh detached git worktree (journaled path; clean trees
948
+ auto-removed, dirty ones retained). A run **lease** (`engine_lease_*`)
949
+ ensures a run is driven by exactly one engine or one external driver at a
950
+ time; manual `complete` is refused while a live engine lease is held.
951
+ - **Harness-neutral driver protocol.** An orchestrated run can be driven by
952
+ ANY agent session (Claude Code, opencode, Codex, a human at a shell), not
953
+ only the native engine. **`akm workflow brief <run>`** is read-only (takes
954
+ no lease, mutates nothing) and emits the active step's expected work-list —
955
+ per-unit content-derived id, resolved instructions + input hash
956
+ (byte-identical to the engine's dispatch), output schema, env binding
957
+ NAMES only, and the exact `report` command lines. **`akm workflow report
958
+ <run> --unit <id> --status completed|failed|running`** is the one mutating
959
+ verb, ingesting a unit's result through the SAME shared step semantics the
960
+ engine uses (idempotent same-hash re-report, replay-divergence on a
961
+ differing hash, budget enforcement, schema validation, and the
962
+ artifact-judged gate/`max_loops` completion path). `--status running`
963
+ claims/heartbeats a unit for stale-driver detection without advancing the
964
+ spine; `--rerun` records a fresh attempt for a failed unit (carrying its
965
+ prior token total forward). Every report command carries `--expect-step`
966
+ (refused if the spine has moved since the brief), and `report --settle`
967
+ (no `--unit`) advances a step that dispatches no reportable units — a
968
+ params-only route, an empty fan-out, or an all-unresolvable work-list — so
969
+ a driver is never wedged. The engine and the brief/report surfaces are
970
+ proven to produce **identical unit graphs**
971
+ (`tests/workflows/conformance/driver-parity.test.ts`).
972
+ - **Observability.** `akm workflow watch <run>` tails the run's `workflow_*`
973
+ / `workflow_unit_*` events as NDJSON (`--stream` foreground-polls to a
974
+ terminal status, no daemon); `akm workflow status --units` lists per-unit
975
+ diagnostics (failure reason + result/error text) without feeding them into
976
+ the deterministic artifact graph; unit lifecycle emits
977
+ `workflow_unit_started` / `workflow_unit_finished` events carrying
978
+ ids/status/enums only. `akm show workflow:<name>` summarizes each step's
979
+ orchestration.
980
+ - **Harness adapters.** Seven local coding-agent CLIs are first-class
981
+ dispatch targets — Codex, Copilot CLI, Pi, Gemini, Aider, Amazon Q, and
982
+ OpenHands — each registered in `HARNESS_REGISTRY` with a command builder +
983
+ result extractor; agent-identity detection and the session-log provider
984
+ list are derived from the registry, and harness-native session ids are
985
+ journaled opportunistically for future session reuse.
986
+ - **Storage.** Additive `workflow.db` migrations 004–010 (unit journal,
987
+ harness session ids, frozen plans + run leases, check-in heartbeats,
988
+ attempt counter, unit claims); migrations 001–003 are untouched and linear
989
+ workflows behave exactly as before.
990
+
991
+ See "Orchestrated steps" and "Driving a run from any agent" in
992
+ `docs/features/workflows.md`, the redesign addendum in
993
+ `docs/archive/akm-workflows-orchestration-plan.md`, and `STABILITY.md`
994
+ (Experimental).
995
+ - **`fable` built-in model alias** — resolves to `claude-fable-5`
996
+ (`opencode/claude-fable-5` on opencode); recommended resolution target for
997
+ the `deep` workflow model tier.
998
+ - **`akm lint` now checks the frontmatter xref channels for broken refs.**
999
+ The existing `missing-ref` check additionally scans the `xrefs:`,
1000
+ `supersededBy:`, and `contradictedBy:` frontmatter keys of non-wiki markdown
1001
+ assets (memories, knowledge, lessons, facts, agents, commands, skills,
1002
+ workflows) — the channels the stash back-linking conventions route
1003
+ provenance and correction links through, and previously the only ref channel
1004
+ with zero checking. Dangling refs are flagged with a detail naming the key
1005
+ (`missing ref: <ref> (frontmatter <key>; resolved to <relPath>)`). The
1006
+ `refs: []` body-scan carve-out does not suppress the new pass; `lint_skip:
1007
+ [missing-ref]` suppresses both; non-ref values (URLs, `raw/<slug>`,
1008
+ `<placeholder>` templates, shell vars) are ignored; refs resolving in a
1009
+ configured extra stash root stay clean. **Note for `--fail-on-flagged` CI
1010
+ users:** stashes with already-dangling xrefs (e.g. from past renames) will
1011
+ gain new `missing-ref` findings on upgrade — fix the refs or add
1012
+ `lint_skip: [missing-ref]` per file. `sources:`, `source_refs:`, and
1013
+ `evidenceSources:` are deliberately not checked (wiki `sources:` is covered
1014
+ by `akm wiki lint`; the latter two legitimately point at merged-away
1015
+ assets).
1016
+ - **`--xref <ref>` on `akm remember` and `akm import` — write-time
1017
+ cross-references with validation.** The stash back-linking conventions route
1018
+ provenance and associative links through `xrefs:` frontmatter, but neither
1019
+ CLI write flow could express them (remember always generated its own
1020
+ frontmatter block; import wrote content verbatim). The new repeatable flag
1021
+ records refs in the written asset's `xrefs:` frontmatter list, which the
1022
+ indexer folds into search hints — the new asset becomes findable from
1023
+ searches for its source. `remember` merges the refs into its generated
1024
+ frontmatter (composes with `--tag`/scope flags; does not trigger the
1025
+ tags-required check); `import` dedupe-appends into the document's existing
1026
+ frontmatter, or adds a block when the document has none — never a nested
1027
+ second block. A document whose existing frontmatter is not a parseable YAML
1028
+ mapping aborts the import (exit 2, nothing written) rather than being
1029
+ rewritten lossily; importing it without `--xref` still preserves it
1030
+ verbatim. Every ref is validated before anything is written, against the
1031
+ write target plus all configured sources (read-only cross-stash sources
1032
+ count): an unresolvable ref fails with the standard usage envelope (exit 2)
1033
+ and leaves the stash untouched. The conventions' ~5-xref cap stays soft —
1034
+ exceeding it warns on stderr but still writes. Additionally, a type-root
1035
+ write (no `--path`, flat name) into a stash carrying convention facts now
1036
+ returns an additive `hint` output key pointing at the stash's placement
1037
+ conventions (`facts/conventions/organization` when that fact exists), so CLI
1038
+ writers see the conventions that LLM flows already receive by injection.
1039
+ - **`--supersedes <ref>` on `akm remember` and `akm import` — atomic
1040
+ correction + demotion of the superseded asset.** The stash conventions'
1041
+ corrections pattern needs TWO writes (the new correction asset with an xref
1042
+ to what it corrects, plus a metadata edit demoting the old asset), which
1043
+ previously meant hand-editing the old file's frontmatter and remembering to
1044
+ reindex it. The new repeatable flag does both: the correction is written
1045
+ with the old ref folded into its `xrefs:` (correction provenance), and the
1046
+ old asset gains `beliefState: superseded` +
1047
+ `supersededBy: [<new ref>]` via the shared `writeSupersededEdge` primitive
1048
+ (sibling of `writeContradictEdge`) — a metadata-only frontmatter edit that
1049
+ preserves every other key and the body byte-for-byte, sorted-set-appended
1050
+ and idempotent across re-runs. The mutated old file is reindexed by the
1051
+ write path, so `--belief current` hides it and ranking demotes it
1052
+ immediately. An unresolvable ref is input validation: exit 2 with the
1053
+ standard `{ok:false,error,code}` envelope and NOTHING written or demoted
1054
+ (no partial correction); a ref resolving to the asset being written itself
1055
+ (self-supersede via `--force` overwrite) is rejected the same way instead
1056
+ of letting a correction demote itself. An old asset that resolves only
1057
+ outside the write target and the working stash (in a read-only source, or
1058
+ in a writable source that is not this write's target) is not mutated: the
1059
+ correction still writes, stderr warns, and the JSON output reports the
1060
+ additive `superseded: [{ref, applied: false, reason}]` key (`applied: true`
1061
+ on success) — the reason names the `--target` remedy when one exists. An
1062
+ old asset whose existing frontmatter is not parseable YAML is likewise
1063
+ skipped (`applied: false`) rather than rewritten through the lossy lenient
1064
+ parser. On a git write target the demotion is ordered before the
1065
+ batch-at-boundary commit, so the correction and the demoted old asset land
1066
+ in one commit.
1067
+ - **Ref-prefix search queries — `akm search "<subdir>/<prefix>/"` now enumerates
1068
+ that subtree.** A query shaped like a ref prefix (trailing slash required:
1069
+ `memories/projectA/`; a bare `memories/` lists the whole type) translates to a
1070
+ typed index enumeration narrowed to entry names under the prefix, instead of
1071
+ degenerating into the AND-token FTS query its sanitized form used to produce
1072
+ (`"memory projectA"` — noise, since `entry_type` is not an FTS column). The
1073
+ listing is recursive and `/`-boundary exact (`projectA/` cannot leak a
1074
+ sibling `projectAlpha/…` scope), matches names case-insensitively (the CLI
1075
+ lowercases queries; on-disk scope directories may carry mixed case), and
1076
+ composes with `--limit`, `--belief`, `--filter`, and named `--source`
1077
+ narrowing exactly like the existing empty-query enumeration — hits carry the
1078
+ fixed browse score `1` in deterministic listing order, not a relevance
1079
+ ranking. The parsed type is explicit intent: a bare `sessions/` enumerates
1080
+ sessions just like `--type session` (the default session exclusion is an
1081
+ untyped-path policy), while an explicit `--type` flag always wins over the
1082
+ type parsed from the query (the branch fires only on untyped searches). A
1083
+ full ref without the trailing slash (`memories/projectA/auth-tip`) stays an
1084
+ ordinary keyword search — resolving a single ref is `akm show`'s job.
1085
+ **Stable-surface note:** `akm search` is Stable; this changes results for a
1086
+ query shape that previously returned noise or nothing. A user literally
1087
+ keyword-searching for the string `memories/x/` loses the old fuzzy token
1088
+ behavior — accepted as negligible.
1089
+ - **The `category:` frontmatter key is now captured into the index** as
1090
+ `entry.category` (entry_json only — no schema migration). The key already
1091
+ drives convention-fact prompt injection (`resolveStashStandards`) and the
1092
+ fact linter, but the indexer never captured it, so no category-keyed search
1093
+ or ranking policy was implementable. Captured for all markdown asset types
1094
+ alongside `beliefState` (trimmed; blank/non-string values ignored; no
1095
+ default invented), captured directly onto the index entry. Search results
1096
+ and ranking are unchanged — this is capture
1097
+ only (a unit test pins that `category` never enters the FTS search
1098
+ fields). **Requires a reindex to take effect** for existing entries. The
1099
+ companion rank-time demotion of `category: convention` facts on untyped
1100
+ queries was NOT shipped: the prescribed measurement (full skeleton
1101
+ convention facts plus a real `knowledge/auth` asset, untyped `auth` query,
1102
+ semantic off) shows no crowding — FTS is exact-first, so prefix expansion
1103
+ onto the facts' tokens only happens when nothing matches the query exactly,
1104
+ and a real domain asset always outranks the facts. That invariant is pinned
1105
+ by `tests/search-convention-fact-demotion.test.ts`, which becomes the
1106
+ regression guard if a demotion contributor is ever revisited.
1107
+ - **Config-gated indexing of the self-situating body opening —
1108
+ `index.indexBodyOpening` (default `false`).** Body prose is not indexed
1109
+ (the FTS `content` column carries only TOC headings and parameters), which
1110
+ is why the stash conventions route orientation into
1111
+ `description:`/`when_to_use:`. With the new flag enabled, the metadata pass
1112
+ captures the first prose paragraph of each markdown asset body — skipping
1113
+ headings (ATX and setext), fenced code blocks, thematic breaks, and a
1114
+ leading nested frontmatter block (only when its content is actually
1115
+ frontmatter-shaped: prose wrapped in decorative `---` lines is captured,
1116
+ not discarded); capped at 280 chars with word-boundary truncation and a
1117
+ trailing ellipsis — into `entry.bodyOpening`, which folds into the
1118
+ lowest-weight `content` FTS column (bm25 weight 1.0, so a name match always
1119
+ outranks a body-opening-only match) and into the search/embedding text.
1120
+ Secret and env files are never read for it, and session-kind memories
1121
+ (`akm_memory_kind` in outer or nested inner frontmatter) are excluded —
1122
+ their bodies are raw transcripts. Both indexing walks and write-path
1123
+ indexing honor the flag (the metadata pass reads the user config directly).
1124
+ With the flag absent or `false`, entries and search fields stay
1125
+ byte-identical to before. **Costs of toggling (either direction):** indexed
1126
+ text changes, so collapse-detector canary recall baselines shift — re-mint
1127
+ via `akm improve canary --refresh` — and embeddings are NOT regenerated for
1128
+ entries that already have one, while incremental runs re-extract only
1129
+ changed files. Run `akm index --full` after toggling: it re-extracts every
1130
+ entry and wipes embeddings so they rebuild from the new text; until then
1131
+ `akm index` warns that the flag differs from the state the index was built
1132
+ with. The conventions' `description:`/`when_to_use:` orientation routing
1133
+ remains primary — this flag makes body openings additionally pay retrieval
1134
+ rent, it does not replace structured metadata. See `docs/configuration.md`.
1135
+ - **`akm mv <ref> <new-name>` — rename with inbound-xref rewrite and
1136
+ utility-history preservation (Experimental).** The stash conventions'
1137
+ forced-rename procedure ("grep and fix inbound xrefs in the same pass") was
1138
+ agent-executable except for the part only the CLI can do: a rename used to
1139
+ mint a new index row, orphaning the `utility_scores` /
1140
+ `utility_scores_scoped` / embeddings / salience rows keyed by entry id —
1141
+ the "rename resets learned ranking" cost the conventions warn about. The
1142
+ new verb does the whole pass: it moves the file (a memory's `.derived.md`
1143
+ twin moves together, keeping the `entry_key + ".derived"` belief-inheritance
1144
+ coupling), rewrites inbound refs across the writable stash's markdown files
1145
+ — body prose, frontmatter ref-list keys (`xrefs:`/`refs:`/`supersededBy:`/
1146
+ …), and fenced code blocks — with complete-ref boundary matching (a longer
1147
+ ref sharing the old ref as a prefix is untouched), and re-keys the index
1148
+ row **in place** so the row id and every id-keyed ranking table survive;
1149
+ the moved row and rewritten citers are FTS-refreshed so search reflects the
1150
+ new name immediately. Scope v1: flat-markdown asset types (`memory`,
1151
+ `knowledge`, `command`, `agent`, `workflow`, `lesson`, `session`, `fact`)
1152
+ in the primary writable stash only, and the source ref must be the
1153
+ canonical spelling — a ref that resolves only through one of lint's
1154
+ fallback resolutions (knowledge-subdir alias, direct-path) is rejected
1155
+ naming the canonical ref, since a fallback-keyed move would strand the
1156
+ index row and dangle canonical citers. Wiki refs, cross-type targets,
1157
+ existing targets, unresolvable refs, type-root escapes, `.derived` twin
1158
+ refs as the source (rename the base — the twin follows), and target names
1159
+ ending in `.derived` (reserved twin suffix) are rejected with the
1160
+ standard envelope (exit 2, nothing moved). Read-only sources are scanned
1161
+ but never written — their citing files are reported in `readOnlyCiters` as
1162
+ manual follow-ups. Output:
1163
+ `{ok, from, to, rewrote: [{file, count}], readOnlyCiters, utilityPreserved}`;
1164
+ a successful move appends an exactly-once `mv` event. A durable mutation
1165
+ journal stages citer rewrites and the asset publication, preserves
1166
+ source-qualified utility/salience history, and resumes index/state
1167
+ finalization after interruption. Divergent citers and late-created targets
1168
+ fail closed instead of being overwritten. Added to the v1 §9.4 command
1169
+ surface as an Experimental-tier additive entry (see `STABILITY.md`).
1170
+
1171
+ ### Changed
1172
+
1173
+ - **Improve-stage extraction and proactive maintenance now ship opt-in.** The
1174
+ built-in `default` and `frequent` strategies resolve extract off, while
1175
+ `default` and `reflect-distill` resolve `proactiveMaintenance` off. The
1176
+ dedicated `proactive-maintenance` strategy remains enabled. Built-ins such as
1177
+ `thorough` that omit these fields inherit the new `default` off values; user
1178
+ overrides are merged last, so explicit `enabled: true` values still win.
1179
+ Standalone extraction remains independent of the improve-stage toggle but
1180
+ still requires `--type <harness>` or `--auto`. The bundled, unselected
1181
+ `core/extract` task now uses `akm extract --auto`; existing scheduled tasks
1182
+ with invalid bare `akm extract` commands must be updated explicitly.
1183
+ - **Indexing dispatches each bundle's detected adapter.** The indexer's per-
1184
+ directory scan now resolves the component's adapter (`adapterForId`) and runs
1185
+ THAT adapter's `recognize`, instead of always using the `akm` adapter. A
1186
+ component whose adapter id is unknown is skipped with a warning. Adapter-owned
1187
+ filtering moves the AKM-stash sensitive/infra exclusions (env/secret
1188
+ `.sensitive`-marker skips, the legacy `vaults/` skip, wiki infra files) out of
1189
+ the core scan and into the `akm` adapter's own recognition, so each adapter
1190
+ owns its bundle's filtering. **Reindex note:** any non-`akm` bundle that was
1191
+ previously probed as one adapter id but still recognized by `akm` will
1192
+ re-index under its own adapter on the next `akm index` — the index is a
1193
+ regenerable cache, so no migration is required.
1194
+ - **Improve target identity is now end-to-end and source-qualified.** Explicit
1195
+ targets govern reads, generated proposals, triage promotion, consolidation,
1196
+ retrieval signals, cooldowns, and replay state. Duplicate bare refs in other
1197
+ sources no longer affect the selected corpus. Generated lessons and
1198
+ provenance follow stash placement conventions and canonical `xrefs`.
1199
+ - **Writable Git boundaries commit only operation-owned paths.** Improve,
1200
+ proposal, supersedes, and direct write flows preserve unrelated staged or
1201
+ dirty work, including files beside generated assets in `content/` layouts.
1202
+
1203
+ - **Directory (scope/domain) tokens now always merge into `tags` at index
1204
+ time**, even when an asset sets explicit `tags:` frontmatter. Previously
1205
+ explicit tags suppressed all path-derived tags, so a nested asset like
1206
+ `memories/projectA/auth-tip` with `tags: [auth]` silently lost the exact
1207
+ tag-match ranking boost for its scope token unless the author restated it.
1208
+ The merged tokens come from the canonical ref subpath
1209
+ (`extractDirTagsFromName`), which also fixes the flat-walk indexing path
1210
+ losing directory segments in the empty-tags fallback. Filename tokens are
1211
+ still auto-derived only when `tags` is empty (they already live in the FTS
1212
+ name column and aliases), and the empty-tags fallback itself is unchanged.
1213
+ **Operator notes:** the change takes effect on the next reindex and alters
1214
+ indexed tag text for nested assets with explicit tags, so collapse-detector
1215
+ canary recall baselines may shift — re-mint them with `akm improve canary
1216
+ --refresh`. Embeddings are not regenerated when indexed text changes; the
1217
+ drift here is small (the merged tokens already appear in the name field),
1218
+ but a purge/re-embed picks up the new text exactly.
1219
+ - **Demoting belief states now cap an entry's final search score**
1220
+ (superseded ≤ 0.25, contradicted ≤ 0.2, archived ≤ 0.15, deprecated ≤
1221
+ 0.28). The existing additive belief penalties are applied inside the
1222
+ multiplicative boost sum on a min-max-normalized FTS base (rank-1 vs rank-2
1223
+ base can differ by up to 0.7), so a superseded incumbent that was the best
1224
+ keyword match stayed clamp-pinned at 1.0 above its own correction — the
1225
+ demotion was invisible exactly when the corrections pattern needs it. The
1226
+ ceiling is applied once at the end of the single scoring pipeline (sort
1227
+ order and displayed scores stay consistent); demoted entries remain listed
1228
+ under the default `--belief all`, keep their relative ordering, and the
1229
+ `--belief` filter axis is unchanged. Semantic-only hits are judged against
1230
+ the `search.minScore` floor by their pre-ceiling score, so a ceiling below
1231
+ the floor (archived 0.15 < default 0.2) ranks the hit last instead of
1232
+ silently dropping it. Ordering changes only for stashes containing
1233
+ belief-flagged assets.
1234
+ - **`mutateFrontmatter` (belief-edge writers: supersede/contradict edges,
1235
+ belief refresh) now preserves the body bytes verbatim** when the file
1236
+ already has a frontmatter block, instead of re-normalizing the
1237
+ fence-to-body separator through `assembleAsset`. A metadata edit is no
1238
+ longer a (whitespace-level) content edit; files gaining their first
1239
+ frontmatter block still use the canonical shape.
1240
+
1241
+ ### Fixed
1242
+
1243
+ - **Improve RC stabilization.** Restored one ownership-safe whole-run lock from
1244
+ triage through final sync; `--skip-if-locked` is a true no-op; the run deadline
1245
+ now starts before indexing and reaches index waits, generation, reindexing, and
1246
+ quality judges; reflect judges the sanitized final candidate with bounded
1247
+ changed-region context; write-target selectors no longer replace durable source
1248
+ identity; and vLLM thinking controls cannot be overridden through `extraParams`.
1249
+ - **Proposal promotion, reversion, and rejection are durable and recoverable.**
1250
+ Acceptance and reversion persist target ownership and content fingerprints,
1251
+ publish atomically across filesystem layouts, index immediately, commit exact
1252
+ Git paths, and emit idempotent lifecycle events. Crash recovery and legacy
1253
+ accepted proposals fail closed on ambiguous targets instead of clobbering
1254
+ another source.
1255
+ - **Engine/setup/health behavior now matches the effective improve plan.**
1256
+ Built-in strategies compose over one baseline, setup preserves independent
1257
+ general and LLM defaults, native OpenCode SDK execution does not require an
1258
+ unused fallback, and health checks each enabled process and credential.
1259
+ - **Check-in directives now survive plain-text output and `workflow
1260
+ status`** (check-in review C2/M1): `formatWorkflowNextPlain` and
1261
+ `formatWorkflowStatusPlain` render the `CONTINUE` directive, and every
1262
+ run-detail response (status/start/complete) evaluates the check-in instead
1263
+ of only `workflow next`.
1264
+ - Workflow frontmatter validator error message now lists the actually-allowed
1265
+ keys (`name`, `updated` were missing); removed the documented-but-nonexistent
1266
+ `akm workflow step` alias from `docs/features/workflows.md`.
1267
+
1268
+ ## [0.9.0-rc.1] - 2026-06-30
10
1269
 
11
1270
  ### Fixed
12
1271
 
@@ -145,7 +1404,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
145
1404
  convention, or `.meta/index.md` files. Seeding stays absent-only and never
146
1405
  overwrites a user-edited file. (#646)
147
1406
 
148
- ## [0.9.0-beta.36] 2026-06-22
1407
+ ## [0.9.0-beta.36] - 2026-06-22
149
1408
 
150
1409
  ### Added
151
1410
 
@@ -180,7 +1439,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
180
1439
  - Corrected a prompt/validator drift where the distill system prompt asked for an
181
1440
  80–200 char description while the gate enforced 20–400. (#645)
182
1441
 
183
- ## [0.9.0-beta.35] 2026-06-21
1442
+ ## [0.9.0-beta.35] - 2026-06-21
184
1443
 
185
1444
  ### Fixed
186
1445
 
@@ -208,7 +1467,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
208
1467
  LLM call per processed session (the session summary); set it to `false` to halve
209
1468
  per-session extract cost. Unchanged/skipped sessions still cost zero.
210
1469
 
211
- ## [0.9.0-beta.34] 2026-06-21
1470
+ ## [0.9.0-beta.34] - 2026-06-21
212
1471
 
213
1472
  ### Fixed
214
1473
 
@@ -223,7 +1482,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
223
1482
  and falls back to the JSON layout. Verified end-to-end through the plugin's
224
1483
  `session.idle` hook.
225
1484
 
226
- ## [0.9.0-beta.33] 2026-06-21
1485
+ ## [0.9.0-beta.33] - 2026-06-21
227
1486
 
228
1487
  ### Fixed
229
1488
 
@@ -239,7 +1498,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
239
1498
  already-extracted session with zero LLM calls) and only `--force` re-extracts. This
240
1499
  makes a session-end hook firing `extract --session-id <id>` precise AND idempotent.
241
1500
 
242
- ## [0.9.0-beta.32] 2026-06-21
1501
+ ## [0.9.0-beta.32] - 2026-06-21
243
1502
 
244
1503
  ### Added
245
1504
 
@@ -265,7 +1524,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
265
1524
  with freshly-read timestamp maps INSIDE the lock (`filterProactiveDue`), dropping
266
1525
  refs a concurrent run already reflected.
267
1526
 
268
- ## [0.9.0-beta.31] 2026-06-20
1527
+ ## [0.9.0-beta.31] - 2026-06-20
269
1528
 
270
1529
  ### Changed
271
1530
 
@@ -278,7 +1537,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
278
1537
  On the live stash this turns the recombine cluster set from generic 66–171-member
279
1538
  buckets into tight topical clusters (`auth`, `architecture`, `patterns`, …).
280
1539
 
281
- ## [0.9.0-beta.30] 2026-06-20
1540
+ ## [0.9.0-beta.30] - 2026-06-20
282
1541
 
283
1542
  ### Changed / Fixed
284
1543
 
@@ -297,7 +1556,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
297
1556
  membership-overlap (≥ 0.7) and reuses its stable ref, so the streak accumulates
298
1557
  through membership drift. First/non-overlapping induction is unchanged.
299
1558
 
300
- ## [0.9.0-beta.29] 2026-06-20
1559
+ ## [0.9.0-beta.29] - 2026-06-20
301
1560
 
302
1561
  ### Reverted
303
1562
 
@@ -305,7 +1564,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
305
1564
  `akm fact` CLI shipped in beta.28 was reverted pending rework. Phase 1 (#629, the
306
1565
  `fact` asset type itself) remains in place.
307
1566
 
308
- ## [0.9.0-beta.27] 2026-06-20
1567
+ ## [0.9.0-beta.27] - 2026-06-20
309
1568
 
310
1569
  All new behavior is **opt-in / default-preserving** — default runs are byte-identical.
311
1570
 
@@ -351,7 +1610,7 @@ All new behavior is **opt-in / default-preserving** — default runs are byte-id
351
1610
  hang/timeout** (the busy-spin can rarely fire even at `--parallel=1`) and never
352
1611
  on a real test failure, so genuine red tests still fail fast and are never masked.
353
1612
 
354
- ## [0.9.0-beta.26] 2026-06-20
1613
+ ## [0.9.0-beta.26] - 2026-06-20
355
1614
 
356
1615
  ### Added
357
1616
 
@@ -368,7 +1627,7 @@ All new behavior is **opt-in / default-preserving** — default runs are byte-id
368
1627
  Azure Container Apps). New docs section "Hosting AKM databases on a network share
369
1628
  (NFS/SMB)" in `docs/configuration.md`.
370
1629
 
371
- ## [0.9.0-beta.25] 2026-06-19
1630
+ ## [0.9.0-beta.25] - 2026-06-19
372
1631
 
373
1632
  Completes the recombine / extract-efficiency / graph thread. All new improve
374
1633
  passes are **opt-in (default off)**, so default behavior is unchanged.
@@ -406,20 +1665,20 @@ passes are **opt-in (default off)**, so default behavior is unchanged.
406
1665
  sandbox dirs left by force-killed workers — eliminating the tmpfs accumulation
407
1666
  that caused intermittent `EEXIST: epoll_ctl` test flakes.
408
1667
 
409
- ## [0.9.0-beta.20] 2026-06-18
1668
+ ## [0.9.0-beta.20] - 2026-06-18
410
1669
 
411
1670
  ### Fixed
412
1671
 
413
1672
  - **`akm update --all` no longer fails for writable `github:` entries stored as `source:"git"`**. `updateRegistryEntry` was using `synced.source` (re-derived from the ref scheme as `"github"`) instead of the existing `entry.source`, causing the config validator to reject `writable:true` on every update cycle.
414
1673
 
415
- ## [0.9.0-beta.19] 2026-06-17
1674
+ ## [0.9.0-beta.19] - 2026-06-17
416
1675
 
417
1676
  ### Fixed
418
1677
 
419
1678
  - **`akm feedback` now completes in ~0.3s** (was 3+ minutes). Root cause: the command was calling `ensureIndex` with `mode: "blocking"` inside `withIndexWriterLease`, triggering a full reindex on every feedback call. Fix: removed the `ensureIndex` call entirely (feedback only needs the index to exist, not be current — a stale index is fine for ref lookup); removed the application-level writer lock (SQLite WAL + `busy_timeout=30s` handles concurrent access with `akm improve`); added a fast DB-exists guard with a clear error for first-time users.
420
1679
  - **`akm health --format html` now completes in ~11s** (was ~18s). Root cause: `akmHealth()` was called twice — once for the main result and once to get `deltas`. Fix: merged into a single call passing both `groupBy: "run"` and `windowCompare` together.
421
1680
 
422
- ## [0.9.0-beta.18] 2026-06-17
1681
+ ## [0.9.0-beta.18] - 2026-06-17
423
1682
 
424
1683
  ### Changed
425
1684
 
@@ -871,14 +2130,16 @@ proposal and log storage, `--format html` output, and per-stage LLM telemetry.
871
2130
 
872
2131
  ### Added
873
2132
 
874
- - **Cross-runtime: akm now runs on Node.js (≥ 20) in addition to Bun** (#560,
2133
+ - **Cross-runtime: akm now runs on Node.js >= 22 in addition to Bun** (#560,
875
2134
  #465). A two-file runtime boundary (`src/storage/database.ts` owns SQLite via
876
2135
  `bun:sqlite` on Bun / `better-sqlite3` on Node; `src/runtime.ts` owns every
877
2136
  `Bun.*` API) contains all runtime-specific code, enforced by a lint guard so it
878
2137
  cannot leak back out. A CI `node-smoke` matrix runs the built CLI under Node
879
- 20 and 22. **Minimum Node is 20** — the prompts dependency (`@clack/core`) uses
880
- `node:util.styleText`, added in Node 20.12; Node 18 is EOL and unsupported.
881
- Bun remains the primary/default runtime.
2138
+ 20 and 22. The prompts dependency (`@clack/core`) uses `node:util.styleText`,
2139
+ added in Node 20.12; Node 18 is EOL and unsupported. The npm package uses Node
2140
+ as its bootstrap and prefers a working Bun >= 1.0 for execution when both are
2141
+ available. Old, unusable, or absent Bun installations fall back to Node.js;
2142
+ standalone binaries remain runtime-free.
882
2143
  - **`session` asset type — agent sessions are now searchable** (#561). The
883
2144
  `extract` pass, after distilling memory proposals from a session, additionally
884
2145
  writes the session itself as a first-class `session` asset
@@ -1487,7 +2748,7 @@ behind an interactive prompt (or `-y` / `--yes` in non-interactive use).
1487
2748
 
1488
2749
  ### Changed
1489
2750
 
1490
- - **Rebrand**: the full name "Agent Kit Manager" is now **Agent Knowledge Management** — `akm` stands for Agent Knowledge Management going forward. The binary name, npm package (`akm-cli`), and all APIs remain unchanged.
2751
+ - **Rebrand**: the full name "Agent Kit Manager" is now **Agent Knowledge Manager** — `akm` stands for Agent Knowledge Manager going forward. The binary name, npm package (`akm-cli`), and all APIs remain unchanged.
1491
2752
 
1492
2753
  - **Config layer rewrite** — single-source-of-truth Zod schema in
1493
2754
  `src/core/config-schema.ts` replaces the per-field parse switch AND
@@ -1675,7 +2936,7 @@ See `docs/migration/v0.7-to-v0.8.md` for the user-facing migration guide.
1675
2936
 
1676
2937
  ### Migration
1677
2938
 
1678
- - See [`docs/migration/release-notes/0.7.0.md`](docs/migration/release-notes/0.7.0.md) for the operator summary and [`docs/migration/v1.md`](docs/migration/v1.md) for the canonical per-surface delta from any 0.6.x baseline.
2939
+ - See [`docs/migration/release-notes/0.7.0.md`](docs/migration/release-notes/0.7.0.md) for the operator summary and the [archived pre-1.0 plan](docs/archive/pre-1.0-migration.md) for the historical per-surface delta from any 0.6.x baseline.
1679
2940
 
1680
2941
  ## [0.6.0] - 2026-04-23
1681
2942
 
@@ -1694,7 +2955,7 @@ See `docs/migration/v0.7-to-v0.8.md` for the user-facing migration guide.
1694
2955
 
1695
2956
  ### Changed (breaking)
1696
2957
 
1697
- - **v1 architecture refactor.** The internal architecture was rebuilt around a single minimal `SourceProvider` interface (`{ name, kind, init, path, sync? }`), a unified FTS5 index that owns search and show, and a single `writeAssetToSource` helper that owns all writes. The CLI command surface and all user-visible config keys are unchanged. See `docs/migration/v1.md` for the full guide.
2958
+ - **v1 architecture refactor.** The internal architecture was rebuilt around a single minimal `SourceProvider` interface (`{ name, kind, init, path, sync? }`), a unified FTS5 index that owns search and show, and a single `writeAssetToSource` helper that owns all writes. The CLI command surface and all user-visible config keys are unchanged. See `docs/archive/pre-1.0-migration.md` for the historical guide.
1698
2959
  - **Config key `stashes[]` renamed to `sources[]`.** Configs with the legacy key load with one deprecation warning and are auto-migrated in memory; the new key is persisted on the next `akm config` write. New configs should use `sources[]`. Configs that contain both keys are rejected with `ConfigError`.
1699
2960
  - **Error hints surface without `--verbose`.** Error classes own their `hint()` text; the regex-on-message hint chain in `cli.ts` is removed. Hints print to stderr inline alongside the error message.
1700
2961
  - **Registry providers loop through a uniform interface.** Context Hub is no longer a special-cased provider type. Add it as a regular git source (`akm add github:andrewyng/context-hub`) or include it as a kit in your registry index. Legacy `type: "context-hub"` entries normalize to `type: "git"` at load time.