akm-cli 0.9.0-rc.8 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (450) hide show
  1. package/CHANGELOG.md +1063 -44
  2. package/README.md +51 -25
  3. package/SECURITY.md +14 -1
  4. package/STABILITY.md +497 -0
  5. package/dist/akm +148 -35
  6. package/dist/{akm-migrate-storage → akm-migrate} +6 -9
  7. package/dist/assets/hints/cli-hints-full.md +223 -95
  8. package/dist/assets/hints/cli-hints-short.md +85 -22
  9. package/dist/assets/improve-strategies/default.json +1 -1
  10. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  11. package/dist/assets/prompts/memory-infer-user.md +2 -3
  12. package/dist/assets/stash-skeleton/README.md +6 -5
  13. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
  14. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
  15. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
  17. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
  18. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
  19. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
  21. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
  22. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
  23. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
  24. package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
  25. package/dist/assets/tasks/core/extract.yml +1 -1
  26. package/dist/assets/tasks/core/version-check.yml +1 -1
  27. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  28. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  29. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  30. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  31. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  32. package/dist/assets/templates/html/health.html +1 -3
  33. package/dist/assets/workflows/workflow-template.md +32 -15
  34. package/dist/cli/invocation.js +40 -15
  35. package/dist/cli/parse-args.js +0 -22
  36. package/dist/cli/retired-commands.js +121 -0
  37. package/dist/cli/shared.js +154 -22
  38. package/dist/cli/unknown-flags.js +236 -0
  39. package/dist/cli-node.mjs +2 -1
  40. package/dist/cli.js +696 -258
  41. package/dist/commands/agent/agent-dispatch.js +14 -3
  42. package/dist/commands/agent/contribute-cli.js +73 -88
  43. package/dist/commands/completions.js +79 -22
  44. package/dist/commands/config-cli.js +17 -150
  45. package/dist/commands/env/env-cli.js +59 -143
  46. package/dist/commands/env/env.js +12 -163
  47. package/dist/commands/env/marker-path.js +6 -0
  48. package/dist/commands/env/secret-cli.js +36 -66
  49. package/dist/commands/env/secret.js +24 -57
  50. package/dist/commands/feedback-cli.js +141 -87
  51. package/dist/commands/health/accept-rate.js +58 -0
  52. package/dist/commands/health/advisories.js +3 -4
  53. package/dist/commands/health/checks.js +85 -23
  54. package/dist/commands/health/html-report.js +7 -10
  55. package/dist/commands/health/improve-metrics.js +25 -83
  56. package/dist/commands/health/md-report.js +5 -9
  57. package/dist/commands/health/metrics.js +62 -20
  58. package/dist/commands/health/renderers.js +47 -0
  59. package/dist/commands/health/report-view-model.js +4 -5
  60. package/dist/commands/health/stash-exposure.js +1 -1
  61. package/dist/commands/health/surfaces.js +3 -48
  62. package/dist/commands/health/task-runs.js +3 -67
  63. package/dist/commands/health/types-improve.js +7 -0
  64. package/dist/commands/health.js +99 -28
  65. package/dist/commands/improve/anti-collapse.js +2 -2
  66. package/dist/commands/improve/autonomy-gate.js +68 -0
  67. package/dist/commands/improve/collapse-detector.js +41 -40
  68. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  69. package/dist/commands/improve/consolidate/merge.js +4 -0
  70. package/dist/commands/improve/consolidate.js +140 -1000
  71. package/dist/commands/improve/distill/promote-memory.js +12 -12
  72. package/dist/commands/improve/distill/quality-gate.js +6 -6
  73. package/dist/commands/improve/distill.js +58 -69
  74. package/dist/commands/improve/eligibility.js +105 -57
  75. package/dist/commands/improve/extract-cli.js +14 -133
  76. package/dist/commands/improve/improve-cli.js +98 -114
  77. package/dist/commands/improve/improve-result-file.js +1 -28
  78. package/dist/commands/improve/improve-strategies.js +8 -5
  79. package/dist/commands/improve/improve.js +128 -91
  80. package/dist/commands/improve/loop-stages.js +182 -20
  81. package/dist/commands/improve/memory/derived-ref.js +45 -43
  82. package/dist/commands/improve/memory/memory-belief.js +1 -1
  83. package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
  84. package/dist/commands/improve/memory/memory-improve.js +6 -5
  85. package/dist/commands/improve/outcome-loop.js +22 -65
  86. package/dist/commands/improve/preparation.js +114 -123
  87. package/dist/commands/improve/proactive-maintenance.js +2 -5
  88. package/dist/commands/improve/reflect.js +56 -160
  89. package/dist/commands/improve/salience.js +11 -122
  90. package/dist/commands/improve/source-identity.js +10 -38
  91. package/dist/commands/lint/base-linter.js +20 -124
  92. package/dist/commands/lint/env-key-rules.js +31 -47
  93. package/dist/commands/lint/index.js +249 -43
  94. package/dist/commands/{events.js → log.js} +33 -38
  95. package/dist/commands/migrate-cli.js +92 -12
  96. package/dist/commands/migration-tool.js +46 -0
  97. package/dist/commands/observability-cli.js +70 -209
  98. package/dist/commands/proposal/drain.js +101 -29
  99. package/dist/commands/proposal/proposal-cli.js +76 -48
  100. package/dist/commands/proposal/proposal.js +54 -18
  101. package/dist/commands/proposal/propose-cli.js +88 -0
  102. package/dist/commands/proposal/propose.js +23 -15
  103. package/dist/commands/proposal/repository.js +701 -278
  104. package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
  105. package/dist/commands/proposal/validators/proposal-validators.js +55 -7
  106. package/dist/commands/proposal/validators/proposals.js +4 -7
  107. package/dist/commands/read/curate.js +34 -53
  108. package/dist/commands/read/knowledge.js +150 -95
  109. package/dist/commands/read/registry-search.js +2 -2
  110. package/dist/commands/read/remember-cli.js +42 -15
  111. package/dist/commands/read/search-cli.js +180 -78
  112. package/dist/commands/read/search.js +58 -43
  113. package/dist/commands/read/show.js +197 -141
  114. package/dist/commands/registry-cli.js +12 -51
  115. package/dist/commands/remember.js +14 -57
  116. package/dist/commands/sources/add-cli.js +100 -31
  117. package/dist/commands/sources/bundle-cli.js +166 -0
  118. package/dist/commands/sources/bundle-config-ops.js +7 -2
  119. package/dist/commands/sources/info.js +18 -5
  120. package/dist/commands/sources/init.js +12 -12
  121. package/dist/commands/sources/installed-stashes.js +382 -98
  122. package/dist/commands/sources/schema-repair.js +3 -2
  123. package/dist/commands/sources/self-update.js +131 -38
  124. package/dist/commands/sources/source-add.js +72 -17
  125. package/dist/commands/sources/source-clone.js +129 -45
  126. package/dist/commands/sources/source-manage.js +43 -23
  127. package/dist/commands/sources/sources-cli.js +57 -208
  128. package/dist/commands/sources/stash-cli.js +46 -53
  129. package/dist/commands/tasks/tasks-cli.js +91 -97
  130. package/dist/commands/tasks/tasks.js +276 -421
  131. package/dist/commands/workflow-cli.js +175 -450
  132. package/dist/core/adapter/adapters/akm-adapter.js +47 -28
  133. package/dist/core/adapter/adapters/akm-lint.js +42 -27
  134. package/dist/core/adapter/adapters/akm-metadata.js +15 -44
  135. package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
  136. package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
  137. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
  138. package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
  139. package/dist/core/adapter/adapters/index.js +6 -6
  140. package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
  141. package/dist/core/adapter/adapters/okf-adapter.js +187 -19
  142. package/dist/core/adapter/adapters/shared.js +3 -19
  143. package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
  144. package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
  145. package/dist/core/adapter/detect-adapter.js +17 -0
  146. package/dist/core/adapter/recognize-match.js +6 -4
  147. package/dist/core/adapter/validate-context.js +214 -0
  148. package/dist/core/asset/akm-markdown.js +63 -0
  149. package/dist/core/asset/asset-placement.js +20 -6
  150. package/dist/core/asset/asset-ref.js +11 -9
  151. package/dist/core/asset/frontmatter-lint.js +30 -0
  152. package/dist/core/asset/frontmatter.js +37 -9
  153. package/dist/core/asset/markdown.js +40 -51
  154. package/dist/core/asset/resolve-ref.js +89 -18
  155. package/dist/core/asset/stash-meta.js +1 -1
  156. package/dist/core/bundle-id.js +51 -0
  157. package/dist/core/common.js +152 -38
  158. package/dist/core/config/config-io.js +12 -1
  159. package/dist/core/config/config-schema.js +35 -8
  160. package/dist/core/config/config-sources.js +55 -11
  161. package/dist/core/config/config-walker.js +25 -9
  162. package/dist/core/config/config.js +9 -48
  163. package/dist/core/config/experimental.js +21 -0
  164. package/dist/core/config/schema/embedding.js +5 -1
  165. package/dist/core/config/schema/experimental.js +30 -0
  166. package/dist/core/config/schema/improve-processes.js +0 -6
  167. package/dist/core/config/schema/improve.js +21 -3
  168. package/dist/core/config/schema/index-config.js +8 -15
  169. package/dist/core/config/schema/output.js +4 -1
  170. package/dist/core/config/schema/setup.js +9 -18
  171. package/dist/core/config/schema/sources-bundles.js +49 -33
  172. package/dist/core/config/schema/workflow.js +3 -3
  173. package/dist/core/env-secret-ref.js +76 -46
  174. package/dist/core/errors.js +18 -12
  175. package/dist/core/events.js +46 -128
  176. package/dist/core/file-change.js +6 -5
  177. package/dist/core/fs-txn.js +83 -7
  178. package/dist/core/git-message.js +2 -2
  179. package/dist/core/improve-result.js +1 -100
  180. package/dist/core/lesson-lint.js +1 -17
  181. package/dist/core/logs-db.js +2 -1
  182. package/dist/core/migration-operation.js +16 -0
  183. package/dist/core/mutation-target.js +78 -0
  184. package/dist/core/parse.js +4 -1
  185. package/dist/core/paths.js +17 -20
  186. package/dist/core/recognition-util.js +12 -14
  187. package/dist/core/redaction.js +34 -0
  188. package/dist/core/standards/resolve-standards-context.js +2 -14
  189. package/dist/core/standards/resolve-stash-standards.js +2 -2
  190. package/dist/core/standards/resolve-type-conventions.js +2 -2
  191. package/dist/core/state/migrations.js +41 -18
  192. package/dist/core/state-db.js +5 -14
  193. package/dist/core/structured.js +1 -1
  194. package/dist/core/subprocess.js +6 -4
  195. package/dist/core/text-truncation.js +9 -5
  196. package/dist/core/type-presentation.js +3 -3
  197. package/dist/core/warn.js +0 -3
  198. package/dist/core/write-source.js +771 -95
  199. package/dist/indexer/bundle-identity-guard.js +3 -2
  200. package/dist/indexer/db/graph-db.js +0 -24
  201. package/dist/indexer/ensure-index.js +1 -0
  202. package/dist/indexer/graph/graph-boost.js +9 -34
  203. package/dist/indexer/graph/graph-extraction.js +8 -5
  204. package/dist/indexer/index-writer-lock.js +53 -17
  205. package/dist/indexer/index-written-assets.js +16 -22
  206. package/dist/indexer/indexer.js +497 -239
  207. package/dist/indexer/installations.js +14 -96
  208. package/dist/indexer/passes/dir-staleness.js +16 -9
  209. package/dist/indexer/passes/memory-inference.js +11 -9
  210. package/dist/indexer/passes/metadata.js +113 -47
  211. package/dist/indexer/scan/doc-to-entry.js +38 -1
  212. package/dist/indexer/scan/drain-dir.js +13 -23
  213. package/dist/indexer/search/db-search.js +99 -54
  214. package/dist/indexer/search/fts-query.js +47 -24
  215. package/dist/indexer/search/ranking-contributors.js +42 -20
  216. package/dist/indexer/search/ranking.js +18 -99
  217. package/dist/indexer/search/search-fields.js +7 -2
  218. package/dist/indexer/search/search-source.js +82 -93
  219. package/dist/indexer/usage/usage-events.js +0 -89
  220. package/dist/indexer/walk/file-context.js +2 -1
  221. package/dist/indexer/walk/matchers.js +30 -43
  222. package/dist/indexer/walk/path-resolver.js +7 -2
  223. package/dist/indexer/walk/walker.js +38 -12
  224. package/dist/integrations/agent/builders.js +0 -6
  225. package/dist/integrations/agent/config.js +2 -2
  226. package/dist/integrations/agent/detect.js +49 -19
  227. package/dist/integrations/agent/engine-fallback.js +76 -0
  228. package/dist/integrations/agent/profiles.js +14 -0
  229. package/dist/integrations/agent/prompts.js +12 -8
  230. package/dist/integrations/agent/runner-dispatch.js +4 -2
  231. package/dist/integrations/agent/runner.js +0 -1
  232. package/dist/integrations/agent/spawn.js +5 -6
  233. package/dist/integrations/github.js +1 -1
  234. package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
  235. package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
  236. package/dist/integrations/harnesses/claude/session-log.js +0 -10
  237. package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
  238. package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
  239. package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
  240. package/dist/integrations/harnesses/index.js +3 -7
  241. package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
  242. package/dist/integrations/harnesses/opencode/session-log.js +0 -15
  243. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
  244. package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
  245. package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
  246. package/dist/integrations/lockfile.js +101 -6
  247. package/dist/integrations/session-logs/index.js +3 -28
  248. package/dist/llm/client.js +136 -100
  249. package/dist/llm/embedders/remote.js +13 -5
  250. package/dist/llm/feature-gate.js +4 -12
  251. package/dist/llm/graph-extract.js +5 -11
  252. package/dist/llm/memory-infer.js +144 -1
  253. package/dist/llm/metadata-enhance.js +5 -7
  254. package/dist/llm/structured-call.js +1 -1
  255. package/dist/llm/usage-persist.js +26 -5
  256. package/dist/llm/usage-telemetry.js +25 -2
  257. package/dist/output/cli-hints.js +1 -2
  258. package/dist/output/context.js +22 -7
  259. package/dist/output/format-exempt.js +80 -0
  260. package/dist/output/generic-render.js +259 -0
  261. package/dist/output/render-registry.js +57 -0
  262. package/dist/output/renderers.js +14 -36
  263. package/dist/output/shapes/curate.js +10 -1
  264. package/dist/output/shapes/events.js +12 -7
  265. package/dist/output/shapes/helpers.js +56 -83
  266. package/dist/output/shapes/migrate.js +8 -0
  267. package/dist/output/shapes/passthrough.js +7 -41
  268. package/dist/output/shapes/proposal/producer.js +15 -7
  269. package/dist/output/shapes.js +2 -9
  270. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  271. package/dist/output/text/bundle-show.js +7 -0
  272. package/dist/output/text/command-format.js +164 -96
  273. package/dist/output/text/env.js +1 -3
  274. package/dist/output/text/events.js +8 -7
  275. package/dist/output/text/health-format.js +103 -0
  276. package/dist/output/text/health.js +7 -0
  277. package/dist/output/text/helpers.js +10 -8
  278. package/dist/output/text/lint-format.js +43 -0
  279. package/dist/output/text/{save.js → lint.js} +2 -2
  280. package/dist/output/text/migrate.js +88 -0
  281. package/dist/output/text/proposal/producer.js +4 -2
  282. package/dist/output/text/proposal-format.js +44 -72
  283. package/dist/output/text/registry-commands.js +1 -2
  284. package/dist/output/text/show-directives.js +15 -7
  285. package/dist/output/text/status-list.js +32 -0
  286. package/dist/output/text/sync.js +5 -0
  287. package/dist/output/text/workflow-format.js +24 -203
  288. package/dist/output/text/workflow.js +1 -7
  289. package/dist/output/text.js +16 -17
  290. package/dist/registry/factory.js +4 -6
  291. package/dist/registry/origin-resolve.js +16 -27
  292. package/dist/registry/providers/skills-sh.js +3 -3
  293. package/dist/registry/providers/static-index.js +13 -23
  294. package/dist/registry/resolve.js +42 -7
  295. package/dist/registry/semver.js +34 -84
  296. package/dist/runtime.js +2 -23
  297. package/dist/scripts/akm-migrate-node.js +60290 -0
  298. package/dist/scripts/akm-migrate.js +59628 -0
  299. package/dist/setup/detect.js +42 -15
  300. package/dist/setup/registry-stash-loader.js +2 -2
  301. package/dist/setup/setup.js +236 -136
  302. package/dist/setup/steps/connection.js +7 -9
  303. package/dist/setup/steps/platforms.js +9 -9
  304. package/dist/setup/steps/semantic.js +15 -3
  305. package/dist/setup/steps/sources.js +12 -13
  306. package/dist/setup/steps/stashdir.js +2 -3
  307. package/dist/setup/steps/tasks.js +237 -120
  308. package/dist/sources/freshness.js +1 -1
  309. package/dist/sources/provider-factory.js +11 -17
  310. package/dist/sources/providers/filesystem.js +2 -3
  311. package/dist/sources/providers/git-install.js +278 -34
  312. package/dist/sources/providers/git-provider.js +25 -23
  313. package/dist/sources/providers/git-stash.js +395 -106
  314. package/dist/sources/providers/git.js +2 -2
  315. package/dist/sources/providers/npm.js +16 -19
  316. package/dist/sources/providers/provider-utils.js +7 -4
  317. package/dist/sources/providers/sync-from-ref.js +3 -9
  318. package/dist/sources/providers/website.js +6 -1
  319. package/dist/sources/resolve.js +6 -5
  320. package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
  321. package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
  322. package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
  323. package/dist/sources/snapshot-fetchers/github.js +100 -0
  324. package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
  325. package/dist/sources/snapshot-fetchers/registry.js +17 -1
  326. package/dist/sources/snapshot-fetchers/robots.js +348 -0
  327. package/dist/sources/snapshot-fetchers/rss.js +282 -0
  328. package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
  329. package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
  330. package/dist/sources/snapshot-fetchers/x.js +910 -0
  331. package/dist/storage/database.js +7 -0
  332. package/dist/storage/engines/sqlite-migrations.js +23 -111
  333. package/dist/storage/managed-db.js +2 -2
  334. package/dist/storage/repositories/canaries-repository.js +1 -1
  335. package/dist/storage/repositories/events-repository.js +27 -11
  336. package/dist/storage/repositories/improve-runs-repository.js +6 -12
  337. package/dist/storage/repositories/index-connection.js +17 -6
  338. package/dist/storage/repositories/index-entries-repository.js +151 -240
  339. package/dist/storage/repositories/index-entry-mapper.js +15 -11
  340. package/dist/storage/repositories/index-fts-repository.js +5 -2
  341. package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
  342. package/dist/storage/repositories/index-meta-repository.js +2 -3
  343. package/dist/storage/repositories/index-schema.js +10 -25
  344. package/dist/storage/repositories/index-utility-repository.js +15 -28
  345. package/dist/storage/repositories/index-vec-repository.js +6 -1
  346. package/dist/storage/repositories/outcome-repository.js +119 -0
  347. package/dist/storage/repositories/proposals-repository.js +296 -59
  348. package/dist/storage/repositories/registry-cache.js +19 -0
  349. package/dist/storage/repositories/salience-repository.js +172 -0
  350. package/dist/storage/repositories/task-history-repository.js +15 -13
  351. package/dist/storage/repositories/workflow-runs-repository.js +52 -40
  352. package/dist/tasks/backends/cron.js +105 -15
  353. package/dist/tasks/backends/index.js +1 -1
  354. package/dist/tasks/backends/launchd.js +85 -38
  355. package/dist/tasks/backends/schtasks.js +135 -15
  356. package/dist/tasks/embedded.js +56 -40
  357. package/dist/tasks/parser.js +7 -157
  358. package/dist/tasks/resolve-akm-bin.js +137 -59
  359. package/dist/tasks/runner.js +79 -42
  360. package/dist/tasks/scheduler-invocation.js +220 -10
  361. package/dist/tasks/schema.js +24 -1
  362. package/dist/tasks/task-id.js +1 -3
  363. package/dist/tasks/validator.js +20 -6
  364. package/dist/workflows/authoring/authoring.js +94 -143
  365. package/dist/workflows/authoring/scope-key.js +1 -1
  366. package/dist/workflows/exec/frozen-judge.js +28 -2
  367. package/dist/workflows/exec/native-executor.js +77 -57
  368. package/dist/workflows/exec/param-secrets.js +9 -9
  369. package/dist/workflows/exec/run-workflow.js +133 -79
  370. package/dist/workflows/exec/step-work.js +219 -346
  371. package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
  372. package/dist/workflows/ir/compile.js +141 -270
  373. package/dist/workflows/ir/freeze.js +40 -30
  374. package/dist/workflows/ir/params.js +135 -11
  375. package/dist/workflows/ir/plan-hash.js +1 -1
  376. package/dist/workflows/ir/schema.js +25 -26
  377. package/dist/workflows/parser.js +872 -307
  378. package/dist/workflows/program/expressions.js +20 -208
  379. package/dist/workflows/program/schema.js +7 -10
  380. package/dist/workflows/renderer.js +95 -68
  381. package/dist/workflows/resource-limits.js +2 -0
  382. package/dist/workflows/runtime/checkin.js +3 -3
  383. package/dist/workflows/runtime/plan-classifier.js +16 -75
  384. package/dist/workflows/runtime/runs.js +186 -127
  385. package/dist/workflows/runtime/unit-checkin.js +1 -1
  386. package/dist/workflows/runtime/unit-phases.js +2 -2
  387. package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
  388. package/dist/workflows/schema.js +1 -11
  389. package/dist/workflows/validate-summary.js +30 -36
  390. package/dist/workflows/validator.js +21 -62
  391. package/docs/README.md +68 -0
  392. package/docs/migration/README.md +8 -0
  393. package/docs/migration/release-notes/0.7.0.md +11 -11
  394. package/docs/migration/release-notes/0.9.0.md +208 -27
  395. package/docs/migration/v0.7-to-v0.8.md +46 -47
  396. package/docs/migration/v0.8-to-v0.9.md +564 -208
  397. package/docs/migration/v0.9.0-troubleshooting.md +561 -0
  398. package/docs/reference/README.md +12 -0
  399. package/docs/reference/cli.md +2253 -0
  400. package/docs/reference/configuration.md +358 -0
  401. package/docs/reference/data-and-telemetry.md +105 -42
  402. package/docs/reference/workflows.md +647 -0
  403. package/package.json +22 -11
  404. package/schemas/akm-asset-envelope.json +93 -0
  405. package/schemas/akm-config.json +81 -128
  406. package/schemas/akm-workflow.json +74 -73
  407. package/dist/assets/tasks/core/backup.yml +0 -5
  408. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  409. package/dist/cli/config-migrate.js +0 -1806
  410. package/dist/cli/config-validate.js +0 -41
  411. package/dist/commands/backup-cli.js +0 -56
  412. package/dist/commands/bundle/bundle-cli.js +0 -68
  413. package/dist/commands/bundle/bundle.js +0 -219
  414. package/dist/commands/graph/graph-cli.js +0 -124
  415. package/dist/commands/graph/graph.js +0 -489
  416. package/dist/commands/improve/extract-watch.js +0 -140
  417. package/dist/commands/mv-cli.js +0 -1221
  418. package/dist/commands/sources/history.js +0 -201
  419. package/dist/commands/tasks/default-tasks.js +0 -186
  420. package/dist/core/migration-backup.js +0 -1234
  421. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
  422. package/dist/llm/memory-infer-impl.js +0 -138
  423. package/dist/migrate/legacy/config-source-migration.js +0 -223
  424. package/dist/migrate/legacy/content-migration.js +0 -305
  425. package/dist/migrate/legacy/legacy-layout.js +0 -779
  426. package/dist/migrate/legacy/legacy-paths.js +0 -25
  427. package/dist/migrate/legacy/legacy-stash-json.js +0 -72
  428. package/dist/migrate/legacy/proposal-fs-import.js +0 -168
  429. package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
  430. package/dist/migrate/legacy/three-db-cutover.js +0 -841
  431. package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
  432. package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
  433. package/dist/migrate/legacy-ref-grammar.js +0 -214
  434. package/dist/output/shapes/distill.js +0 -14
  435. package/dist/output/shapes/history.js +0 -11
  436. package/dist/output/text/distill.js +0 -6
  437. package/dist/output/text/enable-disable.js +0 -8
  438. package/dist/output/text/history.js +0 -6
  439. package/dist/registry/build-index.js +0 -382
  440. package/dist/schemas/akm-config.json +0 -4704
  441. package/dist/schemas/akm-task.json +0 -87
  442. package/dist/schemas/akm-workflow.json +0 -372
  443. package/dist/scripts/migrate-storage.js +0 -3816
  444. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  445. package/dist/workflows/cli.js +0 -53
  446. package/dist/workflows/exec/brief.js +0 -481
  447. package/dist/workflows/exec/report.js +0 -1460
  448. package/dist/workflows/exec/watch.js +0 -116
  449. package/dist/workflows/program/parser.js +0 -813
  450. package/dist/workflows/program/project.js +0 -104
package/CHANGELOG.md CHANGED
@@ -4,12 +4,14 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
- ## [0.9.0] - 2026-07-20
7
+ ## [Unreleased]
8
+
9
+ ## [0.9.0] - 2026-08-06
8
10
 
9
11
  0.9.0 is the format-neutral **bundle / adapter** refactor: it replaces the flat
10
12
  asset-type registry with per-format adapters, adopts one canonical ref grammar,
11
- and consolidates the durable databases and config. This section supersedes the
12
- earlier `0.9.0-rc.1` / `0.9.0-beta.*` development entries below.
13
+ and consolidates the durable databases and config. This section consolidates and
14
+ supersedes the `0.9.0-rc.*` / `0.9.0-beta.*` development entries below.
13
15
 
14
16
  ### Breaking changes & migration
15
17
 
@@ -28,17 +30,18 @@ earlier `0.9.0-rc.1` / `0.9.0-beta.*` development entries below.
28
30
  fully-qualified `bundle//conceptId`; the short bundle-omitted form is accepted
29
31
  input only (resolved against `defaultBundle`, then installation-priority
30
32
  order). The pre-0.9.0 `[origin//]type:name` grammar is removed — there is no
31
- compatibility parser; the frozen migrator in `src/migrate/legacy/` is the only
32
- place it survives.
33
- - **Explicit, journaled, crash-resumable cutover (`akm migrate apply`).** The
33
+ compatibility parser; the frozen migrator in `scripts/akm-migrate/migrate/`
34
+ is the only place it survives.
35
+ - **Explicit, crash-resumable cutover (`akm migrate apply`).** The
34
36
  migrator re-keys all durable state to the new spelling, folds the former
35
37
  `workflow.db` into `state.db` (four databases down to three: `state.db` /
36
38
  `index.db` / a separate `logs.db`), and migrates config from the flat
37
39
  `stashDir` / `sources` / `installed` / `wikiName` keys to `bundles` /
38
- `defaultBundle`. A verified, installation-scoped **backup manifest v3**
39
- (covering the pre-rescue `index.db`) is taken before any ledger is sealed;
40
- expected orphans are quarantined, integrity failures fail closed, and the
41
- whole cutover resumes idempotently after a crash. Normal commands refuse an
40
+ `defaultBundle`. A semantically verified, installation-scoped **backup manifest v4**
41
+ (covering the pre-rescue `index.db`) is taken before mutation. One phase-free
42
+ incomplete sentinel retains that backup and target; expected orphans are
43
+ quarantined, integrity failures fail closed, and the whole cutover reruns
44
+ idempotently after a crash. Normal commands refuse an
42
45
  un-migrated or divergent durable schema rather than migrating as a side effect.
43
46
  The retired `stashDir` / `sources` / `installed` keys are **hard-rejected** by
44
47
  the 0.9.0 config schema whenever present (the error names `akm migrate apply`);
@@ -52,7 +55,7 @@ earlier `0.9.0-rc.1` / `0.9.0-beta.*` development entries below.
52
55
  index (and renamed by the content migration when they hold a real concept).
53
56
  - **`vault` asset type removed.** Use `env` (a whole `.env` group; key names
54
57
  surfaced, values never) and `secret` (a single sensitive value), addressed as
55
- `env/<name>` and `secrets/<name>`. `akm-migrate-storage` still performs the
58
+ `env/<name>` and `secrets/<name>`. `akm-migrate storage` performs the
56
59
  non-destructive `vaults/` → `env/` copy for older stashes.
57
60
  - **0.8-era CLI aliases removed.** The flat proposal verbs (`akm proposals`,
58
61
  `akm accept`, `akm reject`, `akm diff`, `akm revert`, `akm show proposal`),
@@ -64,8 +67,95 @@ earlier `0.9.0-rc.1` / `0.9.0-beta.*` development entries below.
64
67
  See `docs/migration/v0.8-to-v0.9.md` and
65
68
  `docs/migration/release-notes/0.9.0.md` for the full upgrade procedure.
66
69
 
70
+ ### Removed
71
+
72
+ - **The experimental `akm workflow brief` / `akm workflow report`
73
+ external-driver protocol is removed**, along with the
74
+ `experimental.workflowEngine` config key that gated it, its
75
+ `WORKFLOW_ENGINE_NOT_ENABLED` error code, and the `workflowEngine` block in
76
+ `akm task doctor`. `akm workflow run` is now the single execution surface.
77
+
78
+ The protocol let a calling agent session execute a run's units itself
79
+ instead of akm dispatching them. Its stated justification was harness
80
+ neutrality, which measurement did not support: native dispatch already
81
+ covers **ten** harnesses (opencode, claude, opencode-sdk, codex, copilot,
82
+ pi, gemini, aider, amazonq, openhands) in 2,214 LOC total, while the
83
+ protocol cost 2,690 LOC on its own — more than supporting every harness
84
+ natively — and an eleventh harness is ~220 lines, not a protocol. Removing
85
+ it also drops the second consumer of `workflow_run_units` and the
86
+ cross-surface parity obligation on `step-work.ts`, both of which
87
+ constrained every future engine change. The analysis is recorded in
88
+ `docs/architecture/specs/driver-protocol-keep-or-cut.md`.
89
+
90
+ Legacy configs setting `experimental.workflowEngine` remain valid — the
91
+ config schema is `.passthrough()`, so the key is accepted and ignored.
92
+
67
93
  ### Added
68
94
 
95
+ - **`akm workflow run` and prompt tasks fall back to `opencode-sdk` instead of
96
+ refusing when no engine is configured.** A clean install that never ran
97
+ `akm setup` — a bare container, a CI image, an agent-operated session — used
98
+ to fail closed with `INVALID_CONFIG_FILE` (exit 78). When the `opencode`
99
+ binary is on PATH, akm now synthesizes a **config-free** `opencode-sdk`
100
+ engine: it carries no model, endpoint, or credential, so provider, model,
101
+ and auth all resolve from opencode's own configuration and akm never mirrors
102
+ or validates it. With `opencode` absent the failure is unchanged, and its
103
+ remedy now names both routes. An operator-configured `opencode-sdk` engine
104
+ always wins over the synthesized one.
105
+
106
+ The requirement is the **binary**, not the npm package: `@opencode-ai/sdk`
107
+ is an HTTP client that declares no dependencies and whose own
108
+ `createOpencodeServer` spawns `opencode serve`, so a host with the package
109
+ and no binary has no server to reach. Install it with `npm i -g opencode-ai`
110
+ or opencode's own installer.
111
+
112
+ The fallback is **announced, never silent** on every surface that applies
113
+ it: a workflow run surfaces it once at run creation in the result's
114
+ `warnings`, a prompt task writes it to the task run log, `akm agent`
115
+ carries it in its result `warnings` and on stderr, and `propose` and
116
+ `improve` reflect warn on stderr. The frozen plan records the engine
117
+ actually used, so a resume never re-announces a decision it did not make.
118
+
119
+ - **RSS, Bluesky, and X sources.** `akm bundle add` now recognizes three new
120
+ kinds of URL and snapshots them as knowledge assets instead of crawling
121
+ them as ordinary web pages:
122
+
123
+ ```sh
124
+ akm bundle add https://blog.example/feed # RSS 2.0 / Atom / RDF
125
+ akm bundle add https://bsky.app/profile/<handle> # public, no auth
126
+ akm bundle add https://x.com/<user> # see token note below
127
+ ```
128
+
129
+ Any of these falling through — a `/feed` URL that actually serves HTML, an
130
+ unresolvable Bluesky handle — degrades to the normal website crawl rather
131
+ than failing the command.
132
+
133
+ X needs credentials: set `X_BEARER_TOKEN` for the X API v2, or
134
+ `X_RSS_TEMPLATE` to an RSS bridge URL containing `{username}`. To keep the
135
+ token out of your shell history, store it as an akm secret and inject it
136
+ per-invocation:
137
+
138
+ ```sh
139
+ akm secret set x-bearer-token
140
+ akm secret run secrets/x-bearer-token X_BEARER_TOKEN -- akm bundle add https://x.com/<user>
141
+ ```
142
+
143
+ With neither set, the X fetcher emits one warning and falls through.
144
+
145
+ - **`akm-migrate` derives the 0.9 config from your 0.8 keys instead of
146
+ demanding one.** Upgrading used to require hand-authoring a complete 0.9
147
+ config before `migrate apply` would act. The first `apply` with no
148
+ `--config` now writes a validated starter config — `bundles`/`defaultBundle`
149
+ derived from the 0.8 `stashDir` / `sources` / `installed` keys — to a
150
+ predictable path under the backup root and stops, with config and durable
151
+ state byte-for-byte untouched; a second `apply` picks it up and performs the
152
+ cutover. Engine settings are never guessed: `profiles.*` and
153
+ `defaults.llm|agent|improve` are stripped and reported individually in
154
+ `droppedKeys` by their exact 0.8 dotted path. `status` and `apply --dry-run`
155
+ preview the same plan, and an explicit `--config` always wins and is never
156
+ overwritten. `akm migrate --format` now renders text/md/html/yaml through
157
+ the normal output pipeline instead of warning and printing JSON anyway.
158
+
69
159
  - **Local downstream value attribution for memory inference and graph
70
160
  extraction.** Private search-hit sidecars now write versioned, source-qualified
71
161
  per-entry `usage_events.metadata` for emitted MI direct/surface value and the
@@ -79,33 +169,25 @@ See `docs/migration/v0.8-to-v0.9.md` and
79
169
  migration, dashboard, or health schema was added.
80
170
  - **Explicit, crash-resumable 0.9 migration coordination.** `akm migrate
81
171
  status` classifies config, `state.db`, and `workflow.db` independently;
82
- `akm migrate apply [--config <prepared>]` creates a verified,
83
- installation-scoped backup before sealing ledgers or applying pending
84
- migrations. Apply and restore use authenticated phase journals, exact
85
- artifact fingerprints, bounded streaming I/O, SQLite integrity checks,
86
- active-writer barriers, WAL/SHM-safe publication, and idempotent recovery.
87
- Routine reads and current database opens no longer depend on a historical
88
- cutover bundle. See `docs/migration/release-notes/0.9.0.md`.
172
+ `akm migrate apply [--config <prepared>]` creates a semantically verified,
173
+ installation-scoped config/database backup before applying pending migrations.
174
+ Apply and restore use one phase-free incomplete sentinel, bounded control-file
175
+ reads, SQLite integrity and ordered-ledger checks, active-writer barriers,
176
+ WAL/SHM-safe publication, and idempotent replay. Legacy checksum columns are
177
+ inert. Routine reads and current database opens no longer depend on a
178
+ historical cutover bundle. See `docs/migration/release-notes/0.9.0.md`.
89
179
  - **Workflow orchestration engine (experimental).** akm can now execute
90
- multi-step workflows as deterministic **YAML programs**, driven either by a
91
- native engine or by any agent session. This is a new, self-contained
92
- surface; classic linear **markdown workflows and the stable workflow CLI
93
- contract (`start`/`next`/`complete`/`status`/`list`) are unchanged**. What
94
- ships:
95
- - **Authoring.** Orchestrated workflows are YAML programs
96
- (`workflows/*.yaml`, `version: 2`) validated against a published JSON
97
- Schema (`schemas/akm-workflow.json`) by `akm workflow validate`; scaffold
98
- one with `akm workflow template --yaml` or `akm workflow create
99
- <name>.yaml`. A closed `${{ }}` expression language (exactly
100
- `params.<name>`, `steps.<id>.output.<path>`, `item`, `item_index`, parsed
101
- once into an AST) wires steps together. `validate` also surfaces non-fatal
102
- **warnings** (a step with no typed `output:` schema; a `${{ params.<name> }}`
103
- reference to a param the declared `params:` block omits) that never change
104
- the frozen plan or its hash. Creating a workflow whose canonical name
105
- collides with an existing asset of a **different** extension (`foo.yaml`
106
- while `foo.md` exists, or vice-versa) is refused, since the two would
107
- silently shadow each other.
108
- - **Compilation + frozen plans.** `akm workflow start` compiles the program
180
+ multi-step workflows through a native engine or any agent session. Workflow
181
+ assets use the unified markdown format described above; the stable manual
182
+ CLI contract (`start`/`next`/`complete`/`status`/`list`) and the experimental
183
+ engine consume the same asset. What ships:
184
+ - **Authoring.** A workflow is a markdown asset whose frontmatter graph is
185
+ validated against `schemas/akm-workflow.json` and whose `## <step-id>` body
186
+ sections carry instructions and gate rubrics. `akm workflow create`
187
+ scaffolds that format; `akm lint --type workflows` parses and compiles it.
188
+ Bare references (`params.<name>` and `steps.<id>.output.<path>`) wire
189
+ `map.over`, `route.input`, and `inputs`; prose is never interpolated.
190
+ - **Compilation + frozen plans.** `akm workflow start` compiles the workflow
109
191
  into a backend-agnostic Workflow Plan Graph IR (`src/workflows/ir/`) and
110
192
  freezes it on the run row (`plan_json` + `plan_hash`); a run executes the
111
193
  plan compiled at start, and edits to the source file require a new run.
@@ -114,8 +196,7 @@ See `docs/migration/v0.8-to-v0.9.md` and
114
196
  reducer), a typed `output` JSON Schema (validated via a `runStructured`
115
197
  retry-with-feedback loop), `env` bindings (resolved through the existing
116
198
  `akm env run` machinery — secret tokens, dangerous-key policy, keys-only
117
- audit events), classify-and-dispatch `route` steps, and `depends_on`
118
- ordering.
199
+ audit events), and classify-and-dispatch `route` steps.
119
200
  - **Determinism + replay.** Journaled unit identity is content-derived
120
201
  (`<step>:<sha256(item)[:12]>`, `:solo` for a single unit), so cached
121
202
  results survive item-list reordering; a completed unit whose recorded
@@ -137,9 +218,9 @@ See `docs/migration/v0.8-to-v0.9.md` and
137
218
  criteria-bearing gate judges that **artifact** (canonical JSON, clipped)
138
219
  rather than machine prose, and each engine-driven evaluation is journaled
139
220
  as a gate unit row. `gate.max_loops` bounds an evaluator-optimizer retry
140
- loop (feedback threaded into re-dispatched unit prompts); `gate.required`
141
- (or the run-wide `--require-gates`) makes a gate with no available judge
142
- **block** for a human instead of failing open.
221
+ loop (feedback threaded into re-dispatched unit prompts). Gates are
222
+ optional validation: omitted/empty rubrics and unavailable or malformed
223
+ judges skip validation.
143
224
  - **Failure policy.** Per-unit `on_error: fail | continue` (fail-fast
144
225
  default) plus bounded `retry: { max, on: [<failure_reason>…] }` keyed on
145
226
  the persisted failure taxonomy.
@@ -370,6 +451,62 @@ See `docs/migration/v0.8-to-v0.9.md` and
370
451
 
371
452
  ### Changed
372
453
 
454
+ - **X source tokens now resolve from the secret store during bundle update.**
455
+ The `secrets/x-bearer-token` akm secret is honored on the provider
456
+ `sync()` / bundle-update path, not just when adding or importing a URL —
457
+ closing a gap where a refresh saw only the `X_BEARER_TOKEN` environment
458
+ variable. Implemented as a `SecretResolver` capability injected from above
459
+ the source-provider import cycle; internals are documented in
460
+ `docs/architecture/reviews/env-secret-access.md`.
461
+
462
+ - **`website` crawls now have a hard time limit.** `crawlTimeoutMs` (default
463
+ 600000 — 10 minutes) bounds the entire crawl, and unlike the previous
464
+ between-page check it aborts work already in flight: a `Retry-After` sleep
465
+ could previously park `akm bundle add` for as long as a rate-limiting server
466
+ asked, well past the advertised cap. Raise it for a large site, or set
467
+ `"crawlTimeoutMs": 0` to disable the cap. Relatedly, `fetchWithRetry` now
468
+ honors its caller's `AbortSignal` during retry backoff, so any operation that
469
+ passes a signal can actually interrupt a long wait.
470
+
471
+ - **Website snapshots now extract the page's main content.** Conversion moved
472
+ from a hand-rolled regex converter to a DOM parse plus Turndown, scoped to
473
+ the page's content region (`<main>`, `<article>`, `[role=main]`, then common
474
+ content ids/classes, falling back to `<body>` minus nav/header/footer/aside).
475
+ Navigation, ads, and boilerplate no longer land in snapshots, and tables,
476
+ nested lists, and fenced code blocks with language hints now survive
477
+ conversion. **Existing website snapshots will change on their next refresh**
478
+ — expect them to get shorter and cleaner. Link discovery still scans the
479
+ whole page, so crawl coverage is unchanged.
480
+
481
+
482
+ - **`website` sources now respect `robots.txt` by default.** Before crawling
483
+ an origin, akm fetches and parses that origin's `/robots.txt` and skips
484
+ paths disallowed for the `akm`/`akm-cli` product tokens (or `*`), honoring
485
+ `Crawl-delay` (clamped to 10s) between page fetches. This is a deliberate
486
+ behavior change: **existing website sources may return fewer pages, or
487
+ fail with an error if the start URL itself is disallowed, after
488
+ upgrading.** Re-running `akm bundle update` on a website source is what
489
+ surfaces it. Opt out with `"respectRobots": false` on the website
490
+ descriptor to restore the exact pre-upgrade behavior (no `/robots.txt`
491
+ request at all):
492
+
493
+ ```json
494
+ { "bundles": { "docs": { "website": { "url": "https://docs.example.com", "respectRobots": false } } } }
495
+ ```
496
+
497
+ - **`akm lint` now routes through each bundle adapter's own `validate()`.**
498
+ `validate()` was a required member of the adapter interface that nothing
499
+ called: `akm lint` branched on adapter id and re-implemented OKF's checks
500
+ inline (with drifted semantics for `missing-type`), OKF's `missing-ref`
501
+ never ran at all (a bundle with a dangling link reported nothing), and
502
+ llm-wiki's `uncited-raw` / `broken-xref` / `broken-source` /
503
+ `missing-description` checks were unreachable dead code. **Existing OKF and
504
+ llm-wiki bundles may surface new lint findings after upgrading.** akm-bundle
505
+ lint output is byte-identical. Proposal promotion also runs the adapter
506
+ check immediately before the write — advisory-only: it warns and never
507
+ rejects, because the adapter resolver and the legacy promotion gate still
508
+ disagree on foreign-typed cross-bundle refs.
509
+
373
510
  - **Improve-stage extraction and proactive maintenance now ship opt-in.** The
374
511
  built-in `default` and `frequent` strategies resolve extract off, while
375
512
  `default` and `reflect-distill` resolve `proactiveMaintenance` off. The
@@ -440,6 +577,61 @@ See `docs/migration/v0.8-to-v0.9.md` and
440
577
 
441
578
  ### Fixed
442
579
 
580
+ - **Fresh 0.8 installs can actually upgrade.** A config that 0.8.x wrote
581
+ itself carries no `configVersion` key at all (0.8 stamped it only when a
582
+ 0.7-era migration did substantive work), and the migrator read the absent
583
+ key as `inconsistent` — an unconditional blocker. `migrate status` reported
584
+ `blocked` and `migrate apply` refused with exit 78 for every fresh 0.8
585
+ install; reproduced end to end against the published `akm-cli@0.8.14`. An
586
+ absent `configVersion` on a positively pre-cutover-shaped config now
587
+ classifies as `old`; a present-but-unparseable version still fails closed.
588
+ Relatedly, `migrate` reports `not-applicable` (exit 0) instead of `blocked`
589
+ when there is no akm installation to migrate at all, and `apply` warns when
590
+ an active workflow run targets an asset that fails 0.9 structural
591
+ validation, naming the asset and `akm workflow abandon <run-id>`.
592
+
593
+ - **`akm lint` fails closed on mistyped invocations.** A nonexistent `--dir`,
594
+ or an unknown `--type` on an akm bundle (the classic singular/plural typo,
595
+ `--type workflow`), used to scan nothing and report a clean
596
+ `ok:true, flagged:0` — silently passing scripted `--fail-on-flagged`
597
+ gates. Both are now usage errors (exit 2), the `--type` error listing the
598
+ valid values.
599
+ - **Registry search survives a briefly unreachable registry.** Once the
600
+ cached registry index aged past its refresh TTL, a failed fetch
601
+ hard-failed the command even though a serviceable index sat in the cache.
602
+ A failed fetch now serves the last cached index — past its TTL — with a
603
+ warning naming the fetch error.
604
+ - **`akm upgrade` verifies the package manager actually delivered the new
605
+ version.** A lagging `@latest` dist-tag (partial publish, registry mirror
606
+ lag) exits 0 while leaving the old version on PATH; upgrade used to report
607
+ success anyway — and then run `migrate apply` against the old binary. It
608
+ now re-reads `akm --version` after the install: a confirmed mismatch
609
+ reports `upgraded: false` with an exact-version pin command, and a
610
+ verified match is named in the success message.
611
+ - **`akm info` no longer overstates semantic-search health.** After a run
612
+ with partial sqlite-vec fast-path insert failures, the verification
613
+ reported `ready-vec` ("sqlite-vec active") even though search had already
614
+ routed to the slower JS-cosine fallback. The status now reflects the path
615
+ search actually takes, with an `akm index --full` hint when the fast path
616
+ is degraded. Relatedly, `embedding.dimension` is now bounded to the
617
+ vec table's own 1–4096 limit at config validation, so an out-of-range
618
+ value fails at `akm config set` with a clear message instead of crashing
619
+ `akm index` mid-run.
620
+ - **Standalone `akm remember --enrich` actually enriches.** With no other
621
+ metadata flag, `--enrich` fell through to the zero-flag raw-write hot path
622
+ and never attempted the LLM call — an unenriched memory with no warning.
623
+ `--enrich` now routes to the enrichment dispatch exactly like `--auto`;
624
+ the fail-soft contract is unchanged (no configured LLM still warns and
625
+ writes without enrichment).
626
+ - **Read paths no longer plant a broken `index.db` on a fresh install.**
627
+ The fire-and-forget usage telemetry behind `search` / `show` / `curate`
628
+ opened `index.db` with create-on-open: with no index built yet, the open
629
+ itself left an empty, schema-less `index.db` behind, and every later
630
+ command then saw an existing-but-broken index ("no such table: entries") —
631
+ hard-failing proposal acceptance among others. `openExistingDatabase` now
632
+ refuses to create the file (a missing index throws, naming `akm index` as
633
+ the remedy) and the telemetry paths skip cleanly instead.
634
+
443
635
  - **Improve RC stabilization.** Restored one ownership-safe whole-run lock from
444
636
  triage through final sync; `--skip-if-locked` is a true no-op; the run deadline
445
637
  now starts before indexing and reaches index waits, generation, reindexing, and
@@ -465,6 +657,833 @@ See `docs/migration/v0.8-to-v0.9.md` and
465
657
  keys (`name`, `updated` were missing); removed the documented-but-nonexistent
466
658
  `akm workflow step` alias from `docs/features/workflows.md`.
467
659
 
660
+ ## [0.9.0-rc.13] - 2026-07-31
661
+
662
+ ### Security
663
+
664
+ - **`akm update` no longer deletes a previous install directory without
665
+ confirmation.** When a managed source's resolved content location moves,
666
+ `update` removed the old directory outright, while `akm remove` had always
667
+ required `--yes` in non-interactive mode. Only that destructive branch is
668
+ gated — a normal refresh, where the location does not move, still needs no
669
+ prompt and no flag, so existing CI invocations are unaffected. Pass
670
+ `-y`/`--yes` to allow the deletion non-interactively. A cleanup that fails
671
+ now warns instead of failing silently.
672
+
673
+ - **The dangerous-env-key install gate now scans `env/` recursively.** It
674
+ previously read only the top level, so a stash carrying `LD_PRELOAD` in
675
+ `env/nested/inner.env` installed cleanly with no warning. Files without a
676
+ `.env` suffix are still not scanned — no akm code path loads them as
677
+ environment variables.
678
+
679
+ ### Added
680
+
681
+ - **The `okf` adapter reads OKF v0.2's trust/provenance and lifecycle
682
+ frontmatter families.** `generated: {by, at}` (with `generated.at` taking
683
+ precedence over the legacy `timestamp` field, which remains a valid
684
+ fallback), `verified` (a list, or v0.2's permitted single-mapping
685
+ shorthand), `sources` (an object list — `resource` required; `id`/`title`/
686
+ `author`/`usage_count`/`last_modified` optional), `status`
687
+ (`draft`/`stable`/`deprecated`), and `stale_after` are now parsed leniently
688
+ from any OKF concept's frontmatter and surfaced on new, namespaced
689
+ `IndexDocument` fields (`provenance`, `lifecycleStatus`, `staleAfter`,
690
+ `okfVersion`) that never overload the pre-existing AKM-native `sources`
691
+ (wiki citation strings), `generation` (consolidation depth), or `quality`
692
+ fields. As with every other optional OKF field, a missing or malformed
693
+ value never rejects the document. The `okf` adapter remains consumer-only.
694
+
695
+ - **Accepting a proposal now stamps OKF v0.2 provenance onto the written
696
+ asset's frontmatter**, for AKM-native writes only (never through the `okf`
697
+ adapter, which stays consumer-only and unaffected by this). `promoteProposal`
698
+ projects the proposal system's own `source`/`sourceRun`/`gateDecision`/
699
+ `review` bookkeeping — already tracked in `state.db` but previously never
700
+ written to disk. `generated: {by, at}` and `verified: [{by, at}]` are written
701
+ **bare at the top level**, exactly as OKF v0.2 spells them, so a third-party
702
+ OKF v0.2 reader pointed at an AKM stash sees conformant trust metadata;
703
+ `sources` alone is namespaced as `provenance: {sources}`, because a bare
704
+ `sources:` collides with the pre-existing wiki citation-string convention.
705
+ `generated.by` records whether the content came from an automated pipeline
706
+ (`akm/<version>`) or a human-initiated source (`human:<id>`); `verified`
707
+ records whether the promotion itself was an automated gate decision or a
708
+ direct human accept, and accumulates rather than overwriting across
709
+ re-promotions; `evidenceSources`, when present, projects as
710
+ `provenance.sources`. AKM's own adapter rereads what it wrote, so `akm show`
711
+ surfaces it. Every AKM-native markdown type is stamped, `workflow` included.
712
+
713
+ Two consequences worth knowing: promotion re-serializes the whole frontmatter
714
+ block, so YAML **comments** in a hand-written proposal's frontmatter are not
715
+ preserved (values and body bytes are); and for a human-attributed promotion
716
+ with no configured actor id, `by` falls back to `human:<OS username>`, which
717
+ puts that username into content you may later commit and share.
718
+
719
+ - **Internal: a `capturedAtHead` integrity guard**
720
+ (`scripts/lint-golden-captured-at-head.ts`, wired into `bun run lint`) now
721
+ checks every golden fixture's recorded `capturedAtHead` commit SHA — it must
722
+ exist in the local object database and be reachable from at least one known
723
+ branch. Post-hoc review of this PR found all four new OKF format-family
724
+ goldens pointed at a commit that existed locally but was unreachable from
725
+ any ref (a pre-amend duplicate left behind by an interrupted git operation),
726
+ which would have 404'd on GitHub and vanished under a local `git gc`; a
727
+ human fixed that one by hand because nothing caught it. This guard is that
728
+ catch, going forward. In CI's shallow (`fetch-depth: 1`) checkout, a merely
729
+ *absent* commit object is inconclusive (indistinguishable from "just not
730
+ fetched") and only warns; a commit that *exists but is unreachable from any
731
+ branch* — the actual bug class above — still fails there too, since a
732
+ shallow clone can tell presence apart from absence just fine.
733
+
734
+ - **`akm log list --limit <n>`** returns the most recent N events. The flag was
735
+ documented but silently ignored, and there was no limiting mechanism at all
736
+ in the read path — the command returned the entire events table regardless of
737
+ history size. The default remains unlimited.
738
+
739
+ - **`--track-usage` (default on) on `akm search`, `akm curate`, and `akm show`.**
740
+ Pass `--no-track-usage` for a read-only lookup that does not feed usage
741
+ telemetry or the utility-score ranking signal. Previously a bare `akm search`
742
+ silently wrote a `utility_scores` row that influenced future ranking, with no
743
+ disclosure and no way to opt out.
744
+
745
+ - **`akm show` returns the canonical `ref` in every shape.** It was present only
746
+ under `--shape agent`, so a `--shape summary` consumer had to make a second
747
+ call at a different shape just to learn which asset it was looking at.
748
+
749
+ - **`akm info` gained `stashDir`, `defaultBundle`, and `indexStats.byType`.**
750
+ Answering "which stash is primary" previously required a separate
751
+ `akm sources list`.
752
+
753
+ - **`instruction` is a stash-resident asset type.** It was already in
754
+ `KNOWN_TYPES` and had a presentation entry, but had no placement spec — so
755
+ there was nowhere to put one and the indexer never recognized one. `akm bundle create`
756
+ now creates an `instructions/` directory, `.md` files under it index as
757
+ `instruction`, and `--type instruction` is accepted and tab-completable
758
+ everywhere `--type` is. A compile-time assertion now pins
759
+ `placementTypes() ⊆ KnownType`, so the half-registered state this fixes
760
+ cannot recur silently.
761
+
762
+ - **Schedule tasks from any configured bundle via `--bundle <bundle>`** (#711).
763
+ `akm task add`, `run`, `sync`, and `history` accept `--bundle` to
764
+ operate on a non-default bundle instead of only the primary stash. `add`
765
+ resolves through the normal writable-target rules; `run --bundle X` resolves
766
+ the task file and relative asset refs from bundle X. A non-default bundle is
767
+ recorded in the scheduler entry as `--bundle <bundle>`, so scheduled
768
+ `akm task run` resolves the right bundle. Scheduler ids stay bare and a
769
+ collision with another bundle is a hard error rather than a silent clobber.
770
+
771
+ - **Orphan-GC pass for unresolvable `asset_salience` / `asset_outcome` state
772
+ rows** (#733). A new improve maintenance pass (`runOrphanStateGcPass`, run
773
+ next to the existing orphan-proposal purge) stamps `missing_since` on any
774
+ state row whose ref no longer resolves against `entries.item_ref`, clears
775
+ the stamp the moment the ref resolves again, and — only when
776
+ `improve.stateGc.collect` is set to `true` (**default `false`**) — deletes
777
+ rows whose stamp is older than a fixed 7-day grace window
778
+ (`STATE_GC_GRACE_MS`). The pass always runs and always reports counts via
779
+ the new `asset_state_gc` event (`{pending, collected, byTable}`), emitted
780
+ only when there is something to report, so live data can prove the report
781
+ clean before `collect` is ever turned on. Additive migration
782
+ `021-asset-state-missing-since` adds the `missing_since` column to both
783
+ tables. Deliberately lean by design (Workstream C): no quarantine archive,
784
+ no circuit breaker, no health-advisory plumbing, no new tables — "ref not
785
+ present in `entries.item_ref`" is trusted as the authoritative-deletion
786
+ predicate because the indexer already preserves a source's last-known-good
787
+ rows when its scan is incomplete, so a temporarily unreachable source never
788
+ contributes false candidates. `usage_events` is out of scope (already
789
+ covered by cascade-on-delete plus its own 90-day retention purge).
790
+
791
+ ### Changed
792
+
793
+ - **Workflow execution is consolidated on stable `akm workflow run`.** The
794
+ public `workflow start`, `next`, and `complete` commands are removed with
795
+ explicit `UNKNOWN_COMMAND` migration hints; `run <ref|run-id>` now owns
796
+ creation, active-run continuation, native dispatch, completion, and durable
797
+ replay. It is no longer gated by `experimental.workflowEngine`; only the
798
+ experimental `brief`/`report` external-driver protocol retains that opt-in.
799
+ Workflow parameters move from the opaque `--params '<json>'` bag to exact
800
+ declared flags (`--version 1.2.3`, repeated array flags, JSON object/array
801
+ values) coerced through the frozen parameter schemas. New invocation controls
802
+ add bounded failed-step retries (`--max-retries`) and a whole-run timeout
803
+ (`--timeout N|Nms|Ns|Nm`); failures, gate rejection, timeout, and signals now
804
+ produce non-zero process statuses while leaving interrupted work resumable.
805
+
806
+ Criteria-bearing gates now require `workflow.judgeEngine`, which may name a
807
+ configured LLM or agent engine and is frozen into the run. Verification is
808
+ fail-closed: a missing/failing verifier or malformed verdict rejects instead
809
+ of silently advancing. Scheduled workflow tasks now execute through the same
810
+ native orchestrator rather than stopping after run creation. Migration:
811
+ replace `workflow start/next/complete` loops with `workflow run`, replace
812
+ `--params` with exact declared flags, and configure `workflow.judgeEngine`
813
+ before running a workflow with a non-empty `### gate` rubric.
814
+
815
+ - **The two workflow authoring formats — markdown documents and YAML
816
+ orchestration programs — are unified into one format**, per
817
+ `docs/architecture/specs/workflow-format-unification.md`. A workflow is
818
+ now always a single markdown asset: the standard AKM frontmatter envelope
819
+ carries the whole orchestration graph (`params`, `steps` with
820
+ `unit`/`map`/`route`, `inputs`, `output`, `gate`, `defaults`, `budget`),
821
+ and the body carries each step's instructions under a bare `## <step-id>`
822
+ heading, joined to the frontmatter by step id. `.yaml`/`.yml` workflow
823
+ files, the `# Workflow:` / `## Step:` / `Step ID:` markdown headings, and
824
+ `akm workflow create <name>.yaml` are all gone; `akm workflow create`
825
+ always writes the one unified template
826
+ (`src/assets/workflows/workflow-template.md`).
827
+
828
+ **Prose is never interpolated.** The YAML program's `${{ … }}` template
829
+ language, and the markdown format's decorative — and never
830
+ substituted — `{{ … }}` moustaches, are both removed. Data reaches a
831
+ dispatched unit as *attached context* instead: the run's params, its
832
+ item and index for a map unit, and the artifacts its step's new
833
+ `inputs:` key declares. Instructions refer to that context in plain
834
+ language ("clone the repository named by the `repo` parameter") rather
835
+ than splicing a value into the instruction string. Bare reference
836
+ strings (two roots, `params.<name>` and `steps.<id>.output…`) now appear
837
+ only in three frontmatter positions: `map.over`, `route.input`, and
838
+ `inputs:`.
839
+
840
+ **Gate rubrics move to the body.** A step's completion criteria are no
841
+ longer a frontmatter `gate.criteria` list or a `### Completion Criteria`
842
+ bullet section — they live under a step's `### gate` sub-heading, the
843
+ format's one reserved marker, as full prose a judge receives byte-exact.
844
+ Frontmatter `gate:` now carries only optional `max_loops` configuration.
845
+ Omitted or empty rubric text skips validation; a non-empty rubric requires
846
+ the frozen `workflow.judgeEngine`, and unavailable or malformed judges reject
847
+ the gate.
848
+
849
+ This is a **pre-1.0 format change**. The ten example workflows under
850
+ `scripts/akm-eval/example-stash/workflows/` are rewritten to the unified
851
+ format in this change; existing user-authored workflow assets must be updated
852
+ manually before execution.
853
+
854
+ - **akm is described as a knowledge toolkit, not a package manager** (R-048).
855
+ The npm one-liner, the README lede, and the `concepts.md` opener all led with
856
+ "a package manager for AI agent capabilities", which misstates the product to
857
+ its distribution channel and sets package-manager expectations for verbs
858
+ (`update` / `upgrade` / `sync`) that don't mean what a package manager's do.
859
+
860
+ - **BREAKING: a command group invoked with no subcommand is now always a usage
861
+ error, exit 2** (owner ruling 12). The eleven `akm <group>` groups did three
862
+ different things when invoked bare: `graph`, `config`, `env`, `secret`,
863
+ `task`, `workflow`, and `proposal` ran an implicit default action and exited
864
+ 0 (bare `akm graph` silently rendered `graph summary`); `registry`, `log`, and
865
+ `lessons` printed citty's human usage banner to stdout; only `migrate` raised
866
+ a structured error. All eleven now emit the same
867
+ `MISSING_REQUIRED_ARGUMENT` envelope on stderr, naming the available
868
+ subcommands, and exit 2 — matching STABILITY.md's exit-code table (2 =
869
+ usage) and the exit code already used for unknown commands. Matching exit
870
+ codes alone was not enough: a script could not parse the failure uniformly
871
+ while three groups answered on stdout in prose.
872
+
873
+ Migration: name the subcommand. `akm graph` → `akm graph summary`,
874
+ `akm config` → `akm config list`, `akm env` → `akm env list`, `akm secret` →
875
+ `akm secret list`, `akm task` → `akm task doctor`, `akm workflow` →
876
+ `akm workflow list --active`, `akm proposal` → `akm proposal list` (which
877
+ takes the same `--status`/`--queue`/`--ref`/`--type` flags the bare form did).
878
+
879
+ - **BREAKING: `akm sync` persists `eventType: "sync"`, not the legacy
880
+ `"save"`.** The event name now matches the command name. Historical
881
+ `state.db` rows are left as-is — `akm log` and `akm log tail` treat `"save"`
882
+ and `"sync"` as synonyms on **read**, so `akm log --type save` keeps
883
+ returning both old and new rows. Only newly written events use `"sync"`.
884
+
885
+ Migration: none for `akm log --type save`. A script matching raw event rows
886
+ by `eventType === "save"` — reading state.db directly, bypassing `akm log` —
887
+ should also match `"sync"` to see new syncs.
888
+
889
+ - **BREAKING: dropped the dead `installedKitCount` field from the `add`,
890
+ `remove`, and `update` JSON envelopes.** It was a raw lockfile-entry count
891
+ that nothing — internal code or test — ever read.
892
+
893
+ Migration: a script parsing `.config.installedKitCount` should stop; the
894
+ field is gone, not renamed. `config.sourceCount` remains and is unaffected.
895
+
896
+ - **BREAKING: dropped the dead `graphPath` field from every `akm graph *` JSON
897
+ envelope** (`summary`, `entities`, `relations`, `export`, `related`, `entity`,
898
+ `orphans`). It always resolved to the shared state.db path, never a
899
+ per-graph artifact, and carried nothing `stashPath` did not already provide.
900
+
901
+ Migration: a script reading `.graphPath` from any `akm graph` subcommand
902
+ should stop; `stashPath` remains.
903
+
904
+ - **BREAKING: `semanticSearchMode` now defaults to `"off"`.** A bare or
905
+ headless install (`akm init`, `akm setup --yes`, `akm setup --config`) was
906
+ silently downloading the ~130 MB local embedding model on its first `akm
907
+ index`, because the fallback used when the key is absent was `"auto"`. The
908
+ interactive `akm setup` wizard still pre-selects semantic search **on** — a
909
+ human is present to decide — and now shows the asset/download warning
910
+ *before* the prompt rather than after, so the pre-checked box is an informed
911
+ choice. When a remote `embedding.endpoint` is configured, enabling semantic
912
+ search downloads nothing.
913
+
914
+ Migration: existing saved configs are unaffected — the flip only changes the
915
+ fallback used when the key is absent. To keep semantic search on for a
916
+ headless or CI install, set `semanticSearchMode: "auto"` explicitly, or point
917
+ `embedding.endpoint` at a remote embedder.
918
+
919
+ - **BREAKING: `akm workflow run|brief|report` refuse to run until
920
+ `experimental.workflowEngine` is set** (0.9.0 decision Q-05). The native
921
+ workflow executor — including fan-out scheduling and worktree isolation —
922
+ is experimental, and shipping it enabled by default would have made an
923
+ unreviewed execution engine reachable from a plain `akm workflow run`. The
924
+ gated surfaces now exit `78` with a `ConfigError` naming the exact key, and
925
+ `akm task doctor` reports the gate's state. Authoring and linting the unified
926
+ markdown format, along with every other `akm workflow` subcommand, remain
927
+ ungated.
928
+
929
+ Migration: `akm config set experimental.workflowEngine true`.
930
+
931
+ - **BREAKING: the `env:<name>` / `secret:<name>` colon ref spelling is
932
+ rejected** (0.9.0 decision Q-08). Refs are slash conceptIds only — `env/foo`,
933
+ `secrets/deploy-key`. The colon form previously resolved as an undocumented
934
+ alias in some places and fell through as a literal filename in others. It now
935
+ fails with a usage error naming the slash replacement, rather than silently
936
+ doing the wrong thing.
937
+
938
+ Migration: rewrite `env:<name>` as `env/<name>` and `secret:<name>` as
939
+ `secrets/<name>`. The error message prints the exact replacement.
940
+
941
+ - **`akm improve` is review-first by default; autonomy is opt-in** (0.9.0
942
+ decision D8). The command stays ON — schedules, reflect/distill proposals, and
943
+ graph extraction are unchanged — but the lanes that mutate assets *without*
944
+ review now require `akm config set experimental.improveAutonomy true`:
945
+ memory-inference writes, the memory-cleanup pass, and triage
946
+ `applyMode: "promote"` (which downgrades to `queue` rather than disabling
947
+ triage). Consolidation remains review-oriented and is not gated.
948
+
949
+ A gated lane is never a silent no-op: it warns on stderr naming the lane and
950
+ the key, appends an `improve_skipped` event with `reason: "autonomy_gated"`,
951
+ and is counted in `akm health`'s improve skip-reason summary.
952
+
953
+ Migration: set `experimental.improveAutonomy: true` to restore the previous
954
+ behavior. `sync.push` is **not** affected — it keeps its `true` default and its
955
+ own `sync.push: false` / `--no-push` controls. Two other direct writes stay
956
+ ungated by design: `extract`'s additive session indexing and distill's
957
+ encoding-salience frontmatter stamp. Because the gate is applied before the LLM
958
+ preflight, a review-first workspace may now need fewer engines configured than
959
+ before.
960
+
961
+ Also: `akm improve` no longer rejects the global `--format`. It emits an
962
+ envelope through `output()` (always under `--dry-run`, otherwise under
963
+ `--json-to-stdout`), so `--format` applies to that envelope; progress output
964
+ stays on stderr. Previously it exited 2 with `INVALID_FLAG_VALUE`, which made
965
+ it the one command that rejected a valid global flag.
966
+
967
+ - **`akm health --report` replaces the html-only full report** (D7
968
+ follow-through). The full health report — per-run rows, trend deltas vs the
969
+ prior window, and the pending proposal queue — is now a **data** flag, not a
970
+ side effect of asking for html: `akm health --report --format html` renders
971
+ the rich report, and the identical dataset comes back under `--format json`
972
+ (previously that data was reachable only as html). The registered md/html
973
+ renderers fire on the shape of the result, and `akm health` no longer reads
974
+ `--format` at all.
975
+
976
+ Migration: `akm health --format html` → `akm health --report --format html`
977
+ (the bare form now renders the plain check generically); the html-only
978
+ `--compare` flag is removed — use `--window-compare`, which with `--report`
979
+ defaults to the `--since` window so trend deltas stay like-for-like.
980
+
981
+ - **Global output flags parse correctly next to positionals.** citty parses
982
+ each command level against only its own declared args, so a root-declared
983
+ global flag was unknown at the leaf and its space-separated value fell
984
+ through as a positional — `akm sync --format json` synced a bundle named
985
+ "json", and `akm env unset env:x KEY --format json` tried to unset a key
986
+ named "json". The global output flags (`--format`, `--detail`, `--shape`,
987
+ `--output`) are now declared on every leaf command so their values are
988
+ consumed by the parser; the two bespoke argv-inspection workarounds this
989
+ replaces are deleted. Three more non-exempt commands (`akm health`, `akm
990
+ index`, `akm lint`) now declare these flags too, purely for `--help`
991
+ visibility — all three already parsed `--format`/`--detail`/`--shape`/
992
+ `--output` correctly, since none of them has a positional a stray value
993
+ could fall into.
994
+
995
+ - **BREAKING: unknown commands and missing required arguments now exit `2`
996
+ (usage), not `1`.** citty's own command-dispatch wrapper unconditionally
997
+ called `process.exit(1)` for any error it raised before a command's own
998
+ body ever ran — `akm totally-bogus` (unknown command), bare `akm log` /
999
+ `akm lessons` (a subcommand group invoked with no subcommand), and a
1000
+ command missing a required positional (e.g. bare `akm import`) all exited
1001
+ `1`, contradicting the documented exit-code table (`1` = general error /
1002
+ not found, `2` = usage / bad input). The CLI now drives command dispatch
1003
+ directly instead of going through that wrapper, so it can reclassify this
1004
+ one error family as `2` while leaving `--help`, `--version`, and every
1005
+ other exit code unchanged.
1006
+
1007
+ Migration: a script that treated exit `1` as "something went wrong" for a
1008
+ mistyped command or missing argument should check for `2` instead (or
1009
+ keep treating any non-zero exit as failure, which was already correct).
1010
+
1011
+ - **BREAKING: `akm completions --shell <unsupported>` now exits `2` with the
1012
+ standard JSON error envelope, not `1` with a raw stack trace.**
1013
+ `completions` stays format-exempt (its own output is shell-script source,
1014
+ not a result envelope — see STABILITY.md), but its body is now wrapped in
1015
+ the same error-classification path every other command uses.
1016
+
1017
+ Migration: a script parsing this failure should now expect
1018
+ `{"ok":false,"error":"...","code":"INVALID_FLAG_VALUE","hint":...}` on
1019
+ stderr and exit code `2` in place of a stack trace and exit code `1`.
1020
+
1021
+ - **BREAKING: `akm index --dry-run` without `--clean` now exits `2` instead
1022
+ of running a real index.** The flag only ever gated the `--clean`
1023
+ stale-entry removal pass — every other phase (walk, LLM enrichment,
1024
+ embeddings, FTS, the adapter-detection config write) ran for real
1025
+ regardless, so `akm index --dry-run` alone silently performed a full index
1026
+ despite its name. The combination is now rejected with the standard usage
1027
+ envelope instead of quietly doing something other than what "dry run"
1028
+ promised.
1029
+
1030
+ Migration: a script or cron invoking bare `akm index --dry-run` was
1031
+ already getting a real index, so nothing there needs to change in effect —
1032
+ but it will now fail loudly instead. Pass `akm index --clean --dry-run` to
1033
+ preview the stale-entry removal pass, or `akm index --clean` to apply it;
1034
+ drop `--dry-run` entirely to keep running a plain real index.
1035
+
1036
+ - **BREAKING: a corrupt or unparseable `akm.lock` now makes lockfile WRITES
1037
+ throw, instead of silently destroying every entry.** The previous lenient
1038
+ reader returned `[]` on unparseable JSON; a write path that upserted a
1039
+ single entry onto that `[]` then overwrote the file, permanently deleting
1040
+ every other tracked bundle's lock entry. Install/update/remove write paths
1041
+ now use a strict reader that throws on the same corruption instead of
1042
+ reaching the destructive overwrite.
1043
+
1044
+ Migration: if a write now fails with a lockfile-parse error, `akm.lock` is
1045
+ genuinely corrupt — inspect and repair it by hand, or restore it from a
1046
+ backup (e.g. git history), before retrying the write. Reads elsewhere are
1047
+ unaffected; the lenient read contract is unchanged.
1048
+
1049
+ - **BREAKING: `AKM_NPM_REGISTRY` now redirects npm package METADATA lookups,
1050
+ not just the trusted-tarball allowlist.** Previously the override only
1051
+ widened which tarball hosts were trusted for download while metadata
1052
+ queries stayed hardcoded to `registry.npmjs.org`, so a configured private
1053
+ mirror was never actually consulted for package info — the error hint that
1054
+ points users at this variable was false. The override now also replaces
1055
+ the metadata registry base, matching how a private npm registry is meant
1056
+ to work (like npm's own `--registry` flag: wholesale replacement, not a
1057
+ merge with the public registry).
1058
+
1059
+ Migration: an operator who set `AKM_NPM_REGISTRY` expecting only tarball
1060
+ downloads to be redirected, with metadata still served from the public
1061
+ registry, should confirm the mirror actually serves equivalent package
1062
+ metadata — `akm add`/`akm update` for npm-sourced bundles now resolve
1063
+ entirely against the configured mirror when it is set.
1064
+
1065
+ - **`akm remember --show-similar` and `akm migrate apply --dry-run` are the
1066
+ documented, canonical spellings** (previously `--showSimilar` /
1067
+ `--dryRun`), matching every other multi-word flag in the CLI. Not a
1068
+ breaking change: citty registers both the camelCase and kebab-case
1069
+ spelling of any declared flag name automatically, so `--showSimilar` /
1070
+ `--dryRun` keep working — they're now explicit, documented aliases instead
1071
+ of an undocumented accident.
1072
+
1073
+ - **`--detail` and `--shape` help text is scoped honestly.** The per-command
1074
+ `--detail` description now names `info`, `list`, and `remember` as the
1075
+ commands where it has no effect (verified byte-identical output at every
1076
+ level — `akm show` is not one of these; it has three distinct
1077
+ brief/normal/full payloads). `--shape`'s per-command help now repeats the
1078
+ "`summary` is only valid on `akm show`" caveat the root help already
1079
+ documented.
1080
+
1081
+ - **All six `--format` values work on every command** (0.9.0 decision D7).
1082
+ `json|jsonl|yaml|text|md|html` are now universal. Previously there were three
1083
+ inconsistent behaviours: `md` silently emitted the JSON envelope everywhere
1084
+ except `akm health`, `html` was rejected with exit 2 everywhere except
1085
+ `akm health`, and `akm health` reached neither because it intercepted the
1086
+ format itself. Rendering is now registry-driven — a command may register a
1087
+ renderer for a document format, and anything unregistered falls back to a real
1088
+ rendering of its own envelope (headings, tables for arrays of uniform objects,
1089
+ lists otherwise). `akm health` keeps its per-run/window-compare tables and its
1090
+ full HTML report by registering them; the output is unchanged.
1091
+
1092
+ Migration: none required for `json|jsonl|yaml|text`. `--format md` on a
1093
+ non-health command previously returned JSON and now returns Markdown; a script
1094
+ that parsed that JSON should ask for `--format json` explicitly. `--format
1095
+ html` previously exited 2 on non-health commands and now succeeds.
1096
+
1097
+ Also: `akm graph export --format` is **removed** — it declared `--format`
1098
+ locally as well as globally (one token, two parsers). The artifact payload
1099
+ now follows the `--out` extension (`--out g.jsonl` writes JSONL, anything
1100
+ else JSON); the global flag only renders the command's own envelope. A dead
1101
+ local `--format` declaration on `akm history` was removed too (it was never
1102
+ read). Commands
1103
+ whose output is not an envelope (`completions`, `setup`, `env run`,
1104
+ `secret run`, `agent`, `workflow template`, `help migrate`) are declared
1105
+ format-exempt in `src/output/format-exempt.ts` and now warn when given
1106
+ `--format` instead of ignoring it silently. `output.format` in config accepts
1107
+ all six values.
1108
+
1109
+ - **Subtree browse is a conceptId prefix, not `<type>:`** (0.9.0 decision D4).
1110
+ `akm search` enumerates on `memories/`, `memories/projecta/`, `bundle//`, and
1111
+ `bundle//skills/`; a trailing `/` is still required. The prefix now matches the
1112
+ **conceptId** rather than the item name, so a ref copied out of search output
1113
+ can be truncated to a prefix and pasted straight back in — previously that
1114
+ round-trip degraded silently into a keyword search. Enumeration no longer
1115
+ validates against the `akm` adapter's placement types, so items from every
1116
+ adapter browse the same way, and `bundle//` lists a whole bundle (the
1117
+ replacement for the removed `akm bundle items`).
1118
+
1119
+ Migration: `akm search "memory:"` → `akm search "memories/"`;
1120
+ `akm search "memory:projectA/"` → `akm search "memories/projectA/"`;
1121
+ `akm search "session:"` → `akm search "sessions/"`. The retired spelling is
1122
+ now an ordinary keyword search; when it returns nothing, the tip names the
1123
+ conceptId spelling that replaces it. `scripts/lint-shipped-assets.ts` no
1124
+ longer exempts the old spelling, so it is an offense in agent-facing assets.
1125
+
1126
+ - **`akm task sync [--bundle <bundle>]` reconciles a single bundle.** Sync now
1127
+ attributes each installed scheduler entry to its bundle (parsed from the
1128
+ `--bundle` token; absent ⇒ primary) and reconciles only the entries for the
1129
+ bundle being synced. A plain (primary) sync never installs from, updates, or
1130
+ removes another bundle's entries, and sync never scans all bundles — task
1131
+ activation stays explicit (`add --bundle` or `sync --bundle`), so registering a bundle
1132
+ still never activates code. When the target is the default bundle (or omitted),
1133
+ installed scheduler entries are byte-identical to before, so upgrading shows no
1134
+ spurious drift.
1135
+
1136
+ - **The R2 salience ranking boost no longer applies to default `search`/`curate`
1137
+ ranking** (#692). `asset_salience.rank_score` (an encoding + outcome +
1138
+ retrieval projection, recomputed every `improve` run) previously composed
1139
+ into every default search as a bounded multiplicative boost
1140
+ (`salience-ranking`, ×[1.0–1.2]), loaded best-effort from `state.db` on the
1141
+ hot path. On live data it measured as noise (max observed multiplier
1142
+ ×1.071, mean ×1.016): the boost was retrieval-dominated with no source
1143
+ filter — double-counting the same `usage_events` the utility-score
1144
+ contributor already reinforces — warm-started non-zero with no outcome
1145
+ evidence, and had zero pack coverage, so it could only ever favor
1146
+ self-generated personal assets over an equally-relevant pack asset.
1147
+ Removing the default `state.db` load also fixes a confirmed hot-path
1148
+ defect: whenever `state.db` already existed, every default search
1149
+ synchronously waited on the maintenance-activity barrier before ranking
1150
+ could even start — up to a 5-second stall on a blocking wait loop, plus a
1151
+ lock-file create, before the load's own 250ms SQLite `busy_timeout` ever
1152
+ applied. No config gate was added: a key for a term being removed would be
1153
+ dead surface for the upcoming 1.0 contract freeze to carry forever.
1154
+ `rank_score` itself, and everything `improve` computes and does with it
1155
+ internally, are unchanged — only its promotion into user-facing ranking is
1156
+ removed. The contributor stays in the codebase (unwired) for a future
1157
+ gated, outcome-backed experiment.
1158
+
1159
+ - **Internal: `asset_salience` / `asset_outcome` state.db access moved behind
1160
+ `src/storage/repositories/{salience,outcome}-repository.ts`** (#672 part 2).
1161
+ Mirrors the existing state.db repository precedents
1162
+ (`proposals-repository.ts`, `improve-runs-repository.ts`,
1163
+ `events-repository.ts`): the raw SQL, row-mapping, and the #644
1164
+ encoding-provenance CASE guards are extracted verbatim, only relocated —
1165
+ `commands/improve/salience.ts` and `outcome-loop.ts` re-export the moved
1166
+ functions, so no importer or test churns. A new `state-table-sql` rule in
1167
+ `scripts/lint-repository-sql.ts` now fails the build if raw
1168
+ `asset_salience`/`asset_outcome` SQL reappears outside the repository
1169
+ directory (or `core/state/migrations.ts`). Not a user-visible behavior
1170
+ change: `rank_score`, `outcome_score`, and everything `improve`/`health`
1171
+ compute from them are identical.
1172
+
1173
+ ### Fixed
1174
+
1175
+ - **The compiled standalone binary can run `akm migrate`.** Release binaries
1176
+ compiled only `src/cli.ts`, and the migrator was resolved as a sibling file
1177
+ and spawned — neither candidate exists inside a compiled executable, so the
1178
+ documented `./akm-0.9 migrate status/apply` upgrade path always failed with
1179
+ `FILE_NOT_FOUND`. Standalone builds now compile `scripts/akm-standalone.ts`,
1180
+ a wrapper that embeds both the CLI and the migrator (src never imports
1181
+ scripts/ — the dist build's tsc forbids it); `akm migrate` re-execs the
1182
+ binary with an `AKM_MIGRATE_ENTRY` marker the wrapper dispatches on. The
1183
+ repo and npm layouts keep the subprocess path.
1184
+
1185
+ - **Quarantined migration rows are retained in full, not reduced to a count.**
1186
+ When the 0.8→0.9 cutover met a durable ref it could not map, it recorded
1187
+ surface/ref/count in `legacy_state` and then deleted the rows — destroying
1188
+ proposal payloads, event and task history, fingerprints, and canary anchors,
1189
+ contrary to the migration guide's "quarantined, not dropped". Complete rows
1190
+ are now preserved as JSON in `legacy_state_rows` before leaving the live
1191
+ tables.
1192
+
1193
+ - **A failed content migration fails the apply instead of reporting success.**
1194
+ Root discovery, sidecar folding, or the legacy-proposal import throwing was
1195
+ swallowed and logged; the apply then advanced and cleared its journal, and —
1196
+ because 0.9 removed the live `.stash.json` and filesystem-proposal readers —
1197
+ the affected metadata and pending proposals became permanently inaccessible
1198
+ behind an apparently successful upgrade. The step now fails the apply with
1199
+ the journal intact; the committed cutover is untouched and the next apply
1200
+ retries.
1201
+
1202
+ - **Sidecar provenance survives the fold.** Folding a `.stash.json` into
1203
+ frontmatter dropped `xrefs` and `sources` entirely and mapped legacy
1204
+ `sourceRefs` to a `source_refs` key that could never fire (the validator
1205
+ stopped copying the field) and that 0.9 never reads — then deleted the only
1206
+ copy. `xrefs`/`sources` now fold through, and legacy `sourceRefs` merge into
1207
+ `xrefs`.
1208
+
1209
+ - **A reserved-filename rename re-keys durable state.** The D-R6 rename of a
1210
+ mis-named `index.md`/`log.md` concept ran after the cutover had keyed usage,
1211
+ salience, and proposal rows to the old conceptId, stranding that learned
1212
+ state. The rename now feeds the same re-key engine the cutover uses, with
1213
+ the pairs persisted before re-keying so a crash between the two stays
1214
+ retryable.
1215
+
1216
+ - **v1 tasks in a read-only bundle are surfaced with a remedy instead of being
1217
+ silently skipped.** The 0.9 runtime removed the v1 task parser, so silently
1218
+ skipping a `writable: false` bundle left tasks that would start failing after
1219
+ an upgrade that reported current. The preflight now warns per bundle and
1220
+ lists the stranded files in the plan (`readOnlyLegacyTasks`). It does not
1221
+ block the apply: the migration deliberately never rewrites a read-only
1222
+ bundle, and the fix for a lock-materialized git/npm bundle belongs upstream.
1223
+
1224
+ - **Lock resolution metadata survives migration.** Merging the migrator's
1225
+ sparse lock entries replaced whole rows by id, discarding
1226
+ `resolvedVersion`/`resolvedRevision`/`integrity`/`installedAt` recorded by a
1227
+ real install. Merge now preserves existing fields the incoming entry does
1228
+ not define.
1229
+
1230
+ - **Migrating a pre-0.9 config no longer silently changes source policy.**
1231
+ Three settings were dropped by the config-shape migration: an explicit
1232
+ `writable: false` (an omitted filesystem `writable` reads as `true` in the
1233
+ new shape, so a source the user deliberately protected became writable), an
1234
+ explicit `enabled: false` (resuming refreshes and indexing for content the
1235
+ operator had turned off), and a website source's `maxDepth` (silently
1236
+ resetting crawl depth). All three now round-trip to the runtime source entry;
1237
+ `bundles.<id>.enabled` is a supported key.
1238
+
1239
+ - **`akm mv` refuses a bundle marked `writable: false`.** It renamed the file
1240
+ and rewrote citers anyway, because its preflight checked adapter
1241
+ compatibility rather than writability — every other write command already
1242
+ refused.
1243
+
1244
+ - **Memory belief edges written by `--supersedes` are no longer ignored.**
1245
+ `writeSupersededEdge` persists a fully-qualified conceptId, but the belief
1246
+ analyzer accepted only the internal `memory:<name>` spelling, so every edge
1247
+ from `akm remember --supersedes` / `akm import --supersedes` was dropped and
1248
+ a superseded memory read back as active.
1249
+
1250
+ - **`akm env run <ref> -- <cmd> --help` runs the command.** The builtin
1251
+ help-flag scan read the child tail after `--` and printed akm's own usage
1252
+ instead.
1253
+
1254
+ - **`akm mv` works under an `AKM_STASH_DIR` override again.** A valid override
1255
+ not owned by a configured bundle failed with `No configured bundle owns move
1256
+ source`.
1257
+
1258
+ - **An unexpected internal error exits 70 with the JSON failure envelope.** The
1259
+ residual dispatch boundary exited 1 with an unstructured message, so
1260
+ automation could not tell an internal defect from an ordinary failure.
1261
+
1262
+ - **Concurrent `akm config set` processes no longer give up prematurely.** The
1263
+ contended-lock wait budget was 500ms total, so several concurrent writers on
1264
+ a loaded machine could exhaust it and fail with "Timed out waiting for config
1265
+ lock" against a healthy but busy lock. Abandoned locks are still reclaimed by
1266
+ the stale probe, which this budget does not gate.
1267
+
1268
+ - **Config keys named in indexer output and comments now exist.** Four sites
1269
+ pointed at a top-level `llm.*` namespace that the config schema has no such
1270
+ key for — including the user-facing "Increase llm.timeoutMs" warning on an
1271
+ exceeded enrichment budget. The enrichment budget lives at
1272
+ `index.enrichment.timeoutMs` (or `index.defaults.timeoutMs`). Indexing
1273
+ concurrency is auto-derived (2 remote / 1 local) and currently has no config
1274
+ override on that path: `engines.<name>.concurrency` is a valid schema field
1275
+ but the engine resolver does not forward it (documented in
1276
+ `docs/architecture/internals/indexing.md`).
1277
+
1278
+ - **The bundle-identity-drift warning stops naming a command that doesn't
1279
+ exist.** It told users to "rekey it atomically via the bundle-rename
1280
+ command"; 0.9.0 ships no such command. It now gives the two remedies that
1281
+ work: restore the previous bundle id in `config.json`, or keep the new id and
1282
+ `akm index --full` to re-mint, accepting the loss of learned state keyed to
1283
+ the old id.
1284
+
1285
+ - **The scaffolded `organization.md` convention no longer contradicts `akm
1286
+ mv`.** It told authoring agents "there is no command that preserves an
1287
+ asset's identity or learned state" across a rename and showed a raw `mv`.
1288
+ `akm mv` does exactly that — it rewrites inbound refs and re-keys the index
1289
+ row, usage history, and state.db salience/outcome rows. The convention now
1290
+ points at it, flagged Experimental.
1291
+
1292
+ - **`setup.taskSchedules` is no longer documented.** The key was removed from
1293
+ the schema in 0.9.0 (nothing ever read or wrote it), but
1294
+ `docs/reference/configuration.md` still described its two sub-keys.
1295
+
1296
+ - **A freshly scaffolded stash passes its own `akm lint`.** All 12 shipped
1297
+ `facts/conventions/**` convention templates carry frontmatter but none
1298
+ carried an `updated` field, so the first `akm lint` after `akm init` flagged
1299
+ 12 `missing-updated` issues on files the user never wrote. The templates now
1300
+ ship the field, and a regression test lints a freshly scaffolded stash and
1301
+ requires nothing flagged.
1302
+
1303
+ - **`akm show akm//meta` is the documented spelling for the primary stash.**
1304
+ `docs/reference/cli.md` and `docs/guides/concepts.md` showed
1305
+ `akm show local//meta`, which errors with `ASSET_NOT_FOUND` — `local//` is no
1306
+ longer a scoping prefix, so it reads as a bundle named `local`.
1307
+
1308
+ - **`akm sync` emits `shape: "sync"`.** The envelope kept the `"save"` shape
1309
+ from the command's pre-rename name even after the persisted `eventType` was
1310
+ renamed. Unlike the event log, the shape is per-invocation and never
1311
+ persisted, so it needs no read-side synonym.
1312
+
1313
+ - **`akm add <pkg> --provider npm` adds an npm source instead of a broken
1314
+ filesystem bundle.** `--provider` was only read inside the remote-URL branch,
1315
+ so any non-URL target fell through to the filesystem path with the flag
1316
+ ignored, producing a bundle pointed at `<cwd>/<pkg>`. A URL target with
1317
+ `--provider npm` is now rejected at add time rather than storing the URL as a
1318
+ package spec and failing much later at first sync.
1319
+
1320
+ - **`akm add --provider` no longer prints `Installed undefined`.** Two
1321
+ incompatible result shapes reached one text formatter; each is now rendered
1322
+ honestly, including whether a follow-up `akm update` or `akm index` is needed.
1323
+
1324
+ - **`akm update --all` accounts for every configured source.** It previously
1325
+ considered only registry-managed installs and reported `nothing to update`
1326
+ for a stash full of plain sources — nothing was updated because nothing was
1327
+ looked at. Plain git and npm sources are now synced (npm is promoted to a
1328
+ lock-backed install on first sync) and website/filesystem sources are
1329
+ reported through a new `skipped` field with the reason. A successful update of
1330
+ a plain source no longer renders as `nothing to update` either.
1331
+
1332
+ - **`akm search` with no query browses**, as `--help` has always documented,
1333
+ instead of exiting 2.
1334
+
1335
+ - **`akm curate --type <t>` curates within the type instead of bypassing
1336
+ curation.** The filter skipped ranking, intent nudges, the score floor, and
1337
+ family collapse entirely — and could return a hit of the *wrong* type while
1338
+ dropping a higher-scoring correct one.
1339
+
1340
+ - **`akm curate` respects `--limit` for registry hits**, which were capped at a
1341
+ hard-coded 2 regardless.
1342
+
1343
+ - **`akm search --no-project-context` works.** citty strips a leading `--no-`
1344
+ before consulting declared args, so a flag *declared* as `no-project-context`
1345
+ could never be set — the ranking boost was identical with and without it. The
1346
+ flag users type is unchanged.
1347
+
1348
+ - **`akm env run`, `akm secret run`, `akm migrate`, `akm agent`, `akm proposal new`,
1349
+ `akm task run`, and `akm improve` no longer skip cleanup on exit.** They
1350
+ called `process.exit()` directly — in two cases even on success — bypassing
1351
+ teardown of spawned subprocesses. Exit codes, including forwarded non-zero
1352
+ child codes, are unchanged.
1353
+
1354
+ - **The `blocked` semantic-search warning names the cause.** It emitted one
1355
+ fixed string for every failure and discarded the status ledger's reason, so
1356
+ "no embedding provider configured" and "the configured endpoint is failing"
1357
+ read identically.
1358
+
1359
+ - **Shell completion for `--source` no longer suggests `stash|registry|both`
1360
+ on commands where that enum doesn't apply.** `--source` means a closed
1361
+ `stash|registry|both` enum on `akm search`/`akm curate`, but a free-form
1362
+ stash name/path on every `akm graph` subcommand and a free-form URL/ref/
1363
+ path on `akm remember`. The generated completion script keyed its value
1364
+ list by flag name only, so the search/curate enum leaked onto `akm graph
1365
+ --source <TAB>` and `akm remember --source <TAB>`. Value completion is now
1366
+ scoped per command path; commands without a fixed value set get no
1367
+ suggestion instead of the wrong one.
1368
+
1369
+ - **`akm setup --config <file>` / `--from <file>` no longer silently drops
1370
+ six valid config keys** (`index`, `search`, `feedback`,
1371
+ `archiveRetentionDays`, `workflow`, `experimental`). The allowlist was a
1372
+ hand-copied set that had drifted out of sync with the config schema; a
1373
+ user handing setup a config containing any of these keys got a different,
1374
+ silently truncated config written back, with only a warning and exit `0`.
1375
+ The allowlist is now derived from the schema's own key list so it cannot
1376
+ drift again. Keys that remain genuinely retired (`profiles`, `llm`,
1377
+ `agent`, `features`, `stashes`, `bindings`, `writable`) still warn-and-drop
1378
+ as before.
1379
+
1380
+ Note: a config that previously relied on one of these six keys being
1381
+ ignored (because the drop was silent) will now have it applied — re-check
1382
+ `--config`/`--from` inputs if you were unknowingly depending on that gap.
1383
+
1384
+ - **`akm index` no longer persists adapter auto-detection to `config.json`
1385
+ with zero disclosure.** Detecting and writing a bundle component's adapter
1386
+ (`bundles.<id>.components.<component>.adapter`) previously happened
1387
+ silently on every index run. It is now reported in the result envelope as
1388
+ an additive `configUpdated.detectedAdapters` map and on stderr, and only
1389
+ when a write actually happened.
1390
+
1391
+ - **`akm add owner/repo` now resolves as GitHub shorthand instead of failing
1392
+ with "Local path not found".** Any ref containing a `/` was treated as an
1393
+ explicit local path, so the local-ref resolver threw before the
1394
+ GitHub-shorthand fallback ever ran, making the advertised `owner/repo` form
1395
+ unreachable. A bare two-segment `owner/repo` (or `owner/repo#ref`) now
1396
+ falls through to the registry resolver when no such directory exists on
1397
+ disk; `./`, `../`, absolute, and three-or-more-segment paths still resolve
1398
+ as explicit local paths exactly as before.
1399
+
1400
+ - **Internal output-shape command keys renamed `events-list`/`events-tail` →
1401
+ `log-list`/`log-tail`**, matching the `akm log` command they back (the
1402
+ command group used to be `akm events`, removed in 0.9.0). Internal-only:
1403
+ the shape name is a registry lookup key that never reaches the wire (no
1404
+ output field, no schema change), so this is not a user-visible behavior
1405
+ change and carries no `schemaVersion` bump. The documented `[events-tail]`
1406
+ stderr trailer text is deliberately left as-is pending a separate ruling.
1407
+
1408
+ ### Removed
1409
+
1410
+ - **BREAKING: `akm upgrade --skip-checksum` is removed.** STABILITY.md has
1411
+ always said checksum verification is not optional and that the recovery hatch
1412
+ is an environment variable — but the flag shipped anyway, tab-completable,
1413
+ while the documented variable existed nowhere in the source. The code now
1414
+ matches the spec: set `AKM_UPGRADE_SKIP_CHECKSUM=1` if you must bypass a
1415
+ genuinely broken `checksums.txt`. It is deliberately undiscoverable.
1416
+
1417
+ - **BREAKING: `akm config enable|disable` is removed.** It was a hard-coded
1418
+ toggle for one target, the skills.sh registry, and the bare `akm enable` /
1419
+ `akm disable` aliases were already removed in 0.9.0. Use
1420
+ `akm registry add|remove`.
1421
+
1422
+ - **BREAKING: `akm mv` is removed.** No alias, no stub — `akm mv …` fails with
1423
+ the standard unknown-command error. It claimed to preserve identity across a
1424
+ rename, but its inbound-ref rewrite matched bare conceptIds rather than the
1425
+ anchored `bundle//conceptId` prose form, so it could rewrite ordinary prose
1426
+ while leaving real refs dangling. Renames are delete + create per
1427
+ `STABILITY.md`: move the file, `akm index`, `akm lint`. The one capability
1428
+ nothing else covered — carrying an asset's earned signal across the rename —
1429
+ moves to `bun scripts/rekey-asset-ref.ts <old-ref> <new-ref>` (maintainer
1430
+ tooling, `--dry-run` supported, idempotent), which re-keys the index
1431
+ `entries` row in place plus the `asset_salience` / `asset_outcome` /
1432
+ `usage_events` rows. The `mv` event type and output shape are gone; the
1433
+ script emits a `rekey` event instead. A leftover `kind:"mv"` transaction
1434
+ journal from an rc build is now swept by the recovery scanner rather than
1435
+ failing it — an unregistered journal kind no longer bricks index refresh or
1436
+ proposal accept/reject.
1437
+
1438
+ - **The CHURN alert class is removed from the collapse detector.** Its input was
1439
+ a hard-coded `0` from the 0.9.0 confidence-gate deletion onward, so the alert
1440
+ could never fire. The other three alert classes are unaffected. The
1441
+ `improve_cycle_metrics.accepted_actions` column stays and is written as `0`
1442
+ because deployed 0.8 `state.db` files already contain it.
1443
+
1444
+ - **`IndexResponse.graphQuality` is removed** from the `akm index` envelope — it
1445
+ was declared but never assigned in any code path, so it was always absent.
1446
+
1447
+ - **`akm secret path` and `akm secret remove` are removed.** The two resolved a
1448
+ secret ref through *different* stash-selection logic — `path` through the
1449
+ read-side, all-sources resolver and `remove` through the write-target
1450
+ resolver — so for a ref present in more than one stash they could name
1451
+ different files: you could inspect one secret and delete another. Rather than
1452
+ reconcile the resolvers, both subcommands are gone; `akm secret` now exposes
1453
+ only `list`, `run`, and `set`. Both spellings exit 2 with `Unknown command`.
1454
+
1455
+ Migration: a ref's file lives at `<stash>/secrets/<name>` (run `akm sources
1456
+ list` for stash roots) — locate or delete it directly, or use `akm secret run
1457
+ <ref> <VAR> -- <command>` to consume the value without it touching disk. `akm
1458
+ env path` and `akm env remove` are unaffected.
1459
+
1460
+ - Removed the dead `"backup"` output-shape registration left over from the
1461
+ removed `akm backup` command (superseded by `akm-migrate backup`). Already
1462
+ unreachable; no user-visible effect.
1463
+
1464
+ - **`akm task list`, `akm task show`, and `akm task remove` are removed** as
1465
+ redundant with the generic asset commands. List and inspect tasks with `akm
1466
+ search` / `akm show <bundle//tasks/id>` (both already cross-bundle); to remove a
1467
+ scheduled task, delete its file in the owning bundle and run `akm task sync`
1468
+ (sync uninstalls the orphaned scheduler entry). Run `akm task doctor` for
1469
+ scheduler diagnostics — bare `akm task` is a usage error, see the canonical
1470
+ bare-group change above.
1471
+
1472
+ - **The `akm show <ref> toc|section|lines|frontmatter|full` view-mode grammar is
1473
+ removed** (0.9.0 decision D2). `#fragment` is now the only section selector,
1474
+ and a positional after the ref is a usage error that names it. Migration:
1475
+
1476
+ | Old | New |
1477
+ | --- | --- |
1478
+ | `akm show knowledge/guide section "Auth"` | `akm show knowledge/guide#auth` |
1479
+ | `akm show knowledge/guide full` | `akm show knowledge/guide` |
1480
+ | `akm show knowledge/guide toc` | `akm show knowledge/guide#<unmatched>` — the error lists the available fragment slugs |
1481
+ | `akm show knowledge/guide lines 10 30` | no replacement — every response carries `path`, so slice the file yourself |
1482
+ | `akm show knowledge/guide frontmatter` | no replacement — if a raw-YAML projection proves necessary it returns as a `--shape` value |
1483
+
1484
+ The undocumented `--akmView` / `--akmHeading` / `--akmStart` / `--akmEnd`
1485
+ flags the grammar injected into argv are gone with it.
1486
+
468
1487
  ## [0.9.0-rc.1] - 2026-06-30
469
1488
 
470
1489
  ### Fixed
@@ -1948,7 +2967,7 @@ behind an interactive prompt (or `-y` / `--yes` in non-interactive use).
1948
2967
 
1949
2968
  ### Changed
1950
2969
 
1951
- - **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.
2970
+ - **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.
1952
2971
 
1953
2972
  - **Config layer rewrite** — single-source-of-truth Zod schema in
1954
2973
  `src/core/config-schema.ts` replaces the per-field parse switch AND
@@ -2136,7 +3155,7 @@ See `docs/migration/v0.7-to-v0.8.md` for the user-facing migration guide.
2136
3155
 
2137
3156
  ### Migration
2138
3157
 
2139
- - 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.
3158
+ - 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](https://github.com/itlackey/akm/blob/be3a6a632b0cbe7a63ce71b7d093d8ac266e857c/docs/archive/pre-1.0-migration.md) for the historical per-surface delta from any 0.6.x baseline.
2140
3159
 
2141
3160
  ## [0.6.0] - 2026-04-23
2142
3161