akm-cli 0.9.16 → 0.9.17-alpha.10

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 (403) hide show
  1. package/CHANGELOG.md +2101 -0
  2. package/STABILITY.md +11 -10
  3. package/dist/akm +124 -193
  4. package/dist/akm-migrate +38 -19
  5. package/dist/assets/hints/cli-hints-full.md +6 -7
  6. package/dist/assets/improve-strategies/catchup.json +0 -3
  7. package/dist/assets/improve-strategies/consolidate.json +0 -1
  8. package/dist/assets/improve-strategies/default.json +1 -2
  9. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
  10. package/dist/assets/improve-strategies/quick.json +1 -2
  11. package/dist/assets/improve-strategies/reflect-distill.json +1 -2
  12. package/dist/assets/improve-strategies/thorough.json +0 -3
  13. package/dist/assets/prompts/consolidate-pair.md +20 -0
  14. package/dist/assets/prompts/consolidate-system.md +4 -11
  15. package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
  17. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
  18. package/dist/assets/templates/html/health.html +3 -5
  19. package/dist/cli/retired-commands.js +1 -1
  20. package/dist/cli/shared.js +6 -2
  21. package/dist/cli/unknown-flags.js +24 -1
  22. package/dist/cli.js +68 -10
  23. package/dist/commands/agent/agent-dispatch.js +1 -1
  24. package/dist/commands/command/command-execution.js +24 -62
  25. package/dist/commands/feedback-cli.js +0 -1
  26. package/dist/commands/health/accept-rate.js +6 -0
  27. package/dist/commands/health/archive-usage.js +92 -0
  28. package/dist/commands/health/checks.js +83 -74
  29. package/dist/commands/health/config-skew.js +38 -0
  30. package/dist/commands/health/data-dir-usage.js +25 -13
  31. package/dist/commands/health/egress.js +54 -0
  32. package/dist/commands/health/html-report.js +1 -42
  33. package/dist/commands/health/improve-metrics.js +136 -591
  34. package/dist/commands/health/md-report.js +1 -6
  35. package/dist/commands/health/plugin-staleness.js +53 -3
  36. package/dist/commands/health/renderers.js +12 -4
  37. package/dist/commands/health/report-view-model.js +14 -120
  38. package/dist/commands/health/types-improve.js +4 -19
  39. package/dist/commands/health/windows.js +64 -74
  40. package/dist/commands/health.js +145 -143
  41. package/dist/commands/improve/consolidate/chunking.js +26 -117
  42. package/dist/commands/improve/consolidate/continuity-check.js +137 -0
  43. package/dist/commands/improve/consolidate/pair-pass.js +791 -0
  44. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  45. package/dist/commands/improve/consolidate.js +589 -1127
  46. package/dist/commands/improve/content-hash.js +16 -24
  47. package/dist/commands/improve/distill/content-repair.js +18 -100
  48. package/dist/commands/improve/distill-guards.js +20 -81
  49. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  50. package/dist/commands/improve/distill.js +608 -1041
  51. package/dist/commands/improve/eligibility.js +126 -390
  52. package/dist/commands/improve/execution.js +8 -10
  53. package/dist/commands/improve/extract-prompt.js +1 -2
  54. package/dist/commands/improve/extract.js +487 -1046
  55. package/dist/commands/improve/feedback-valence.js +0 -25
  56. package/dist/commands/improve/improve-cli.js +75 -169
  57. package/dist/commands/improve/improve-result-file.js +10 -66
  58. package/dist/commands/improve/improve-strategies.js +52 -4
  59. package/dist/commands/improve/improve-usage-report.js +18 -64
  60. package/dist/commands/improve/improve.js +480 -1074
  61. package/dist/commands/improve/ledger.js +119 -0
  62. package/dist/commands/improve/locks.js +2 -8
  63. package/dist/commands/improve/loop-stages.js +415 -1073
  64. package/dist/commands/improve/memory/derived-ref.js +12 -77
  65. package/dist/commands/improve/memory/memory-belief.js +16 -118
  66. package/dist/commands/improve/memory/memory-improve.js +266 -14
  67. package/dist/commands/improve/outcome-loop.js +28 -156
  68. package/dist/commands/improve/planner.js +5 -15
  69. package/dist/commands/improve/preparation.js +779 -2319
  70. package/dist/commands/improve/proactive-maintenance.js +34 -101
  71. package/dist/commands/improve/reflect-noise.js +104 -280
  72. package/dist/commands/improve/reflect.js +642 -1353
  73. package/dist/commands/improve/retrieval-gate.js +127 -0
  74. package/dist/commands/improve/retrieval-scope.js +92 -0
  75. package/dist/commands/improve/salience.js +41 -240
  76. package/dist/commands/improve/session-asset.js +19 -100
  77. package/dist/commands/improve/stage.js +322 -0
  78. package/dist/commands/lint/base-linter.js +37 -15
  79. package/dist/commands/proposal/drain.js +261 -578
  80. package/dist/commands/proposal/proposal-cli.js +19 -20
  81. package/dist/commands/proposal/proposal-types.js +31 -24
  82. package/dist/commands/proposal/proposal.js +38 -8
  83. package/dist/commands/proposal/propose.js +134 -160
  84. package/dist/commands/proposal/repository.js +1097 -1394
  85. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  86. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  87. package/dist/commands/proposal/validators/proposals.js +22 -89
  88. package/dist/commands/read/curate.js +105 -462
  89. package/dist/commands/read/knowledge.js +3 -2
  90. package/dist/commands/read/search-cli.js +16 -33
  91. package/dist/commands/read/search.js +17 -23
  92. package/dist/commands/read/show.js +57 -108
  93. package/dist/commands/sources/bundle-cli.js +25 -2
  94. package/dist/commands/sources/bundle-config-ops.js +4 -0
  95. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  96. package/dist/commands/sources/info.js +127 -29
  97. package/dist/commands/sources/installed-stashes.js +197 -746
  98. package/dist/commands/sources/schema-repair.js +98 -129
  99. package/dist/commands/sources/source-add.js +62 -12
  100. package/dist/commands/sources/source-manage.js +9 -2
  101. package/dist/commands/sources/stash-cli.js +24 -4
  102. package/dist/commands/tasks/explain.js +10 -13
  103. package/dist/commands/tasks/tasks-cli.js +12 -13
  104. package/dist/commands/tasks/tasks.js +350 -936
  105. package/dist/commands/tasks/validate.js +26 -24
  106. package/dist/commands/workflow/plan.js +22 -29
  107. package/dist/commands/workflow-cli.js +4 -4
  108. package/dist/core/adapter/adapters/akm-adapter.js +2 -1
  109. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  110. package/dist/core/adapter/adapters/akm-metadata.js +42 -12
  111. package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
  112. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  113. package/dist/core/adapter/execution-source.js +17 -29
  114. package/dist/core/asset/asset-placement.js +4 -13
  115. package/dist/core/asset/frontmatter.js +106 -1
  116. package/dist/core/asset/resolve-ref.js +1 -1
  117. package/dist/core/bundle-id.js +42 -5
  118. package/dist/core/bundle-rename.js +285 -0
  119. package/dist/core/config/config-io.js +1 -2
  120. package/dist/core/config/config-schema.js +9 -34
  121. package/dist/core/config/config-walker.js +1 -1
  122. package/dist/core/config/config.js +184 -111
  123. package/dist/core/config/engine-semantics.js +0 -2
  124. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  125. package/dist/core/config/schema/embedding.js +20 -5
  126. package/dist/core/config/schema/engines.js +5 -0
  127. package/dist/core/config/schema/execution.js +1 -1
  128. package/dist/core/config/schema/experimental.js +1 -1
  129. package/dist/core/config/schema/improve-processes.js +54 -125
  130. package/dist/core/config/schema/improve.js +4 -42
  131. package/dist/core/config/schema/index-config.js +9 -48
  132. package/dist/core/config/schema/scheduler.js +12 -12
  133. package/dist/core/config/schema/search.js +6 -22
  134. package/dist/core/env-secret-ref.js +0 -1
  135. package/dist/core/errors.js +8 -9
  136. package/dist/core/file-change.js +13 -5
  137. package/dist/core/file-lock.js +76 -173
  138. package/dist/core/improve-result.js +35 -7
  139. package/dist/core/improve-types.js +0 -1
  140. package/dist/core/logs-db.js +2 -2
  141. package/dist/core/loopback.js +7 -12
  142. package/dist/core/non-task-input.js +20 -0
  143. package/dist/core/parse.js +13 -16
  144. package/dist/core/paths.js +0 -24
  145. package/dist/core/redaction.js +109 -2
  146. package/dist/core/run-lock.js +2 -5
  147. package/dist/core/spawn-env.js +1 -1
  148. package/dist/core/state/migrations.js +123 -61
  149. package/dist/core/state-db-scope.js +2 -4
  150. package/dist/core/state-db.js +126 -692
  151. package/dist/core/time.js +0 -20
  152. package/dist/core/type-presentation.js +1 -9
  153. package/dist/core/write-source.js +294 -1005
  154. package/dist/execution/input-contract.js +1 -1
  155. package/dist/execution/resolved-request.js +135 -689
  156. package/dist/execution/source.js +63 -257
  157. package/dist/execution/target-ref.js +1 -1
  158. package/dist/indexer/bundle-identity-guard.js +2 -2
  159. package/dist/indexer/db/llm-cache.js +2 -2
  160. package/dist/indexer/ensure-index.js +77 -73
  161. package/dist/indexer/index-rebuild-lock.js +3 -11
  162. package/dist/indexer/index-writer-lock.js +8 -17
  163. package/dist/indexer/index-written-assets.js +141 -154
  164. package/dist/indexer/indexer.js +400 -1124
  165. package/dist/indexer/links/declared-links.js +90 -0
  166. package/dist/indexer/materialize-embeddings.js +60 -397
  167. package/dist/indexer/passes/memory-inference.js +96 -90
  168. package/dist/indexer/passes/metadata.js +132 -219
  169. package/dist/indexer/read-preflight.js +0 -7
  170. package/dist/indexer/scan/doc-to-entry.js +2 -3
  171. package/dist/indexer/scan/drain-dir.js +1 -1
  172. package/dist/indexer/search/db-search.js +190 -590
  173. package/dist/indexer/search/fts-query.js +30 -41
  174. package/dist/indexer/search/ranking.js +28 -154
  175. package/dist/indexer/search/search-attribution.js +12 -32
  176. package/dist/indexer/search/search-fields.js +11 -15
  177. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  178. package/dist/indexer/search/search-source.js +1 -4
  179. package/dist/indexer/usage/usage-events.js +36 -7
  180. package/dist/indexer/walk/walker.js +3 -4
  181. package/dist/integrations/agent/engine-fallback.js +23 -40
  182. package/dist/integrations/agent/engine-resolution.js +93 -183
  183. package/dist/integrations/agent/execution.js +507 -0
  184. package/dist/integrations/agent/model-map.js +28 -156
  185. package/dist/integrations/agent/request-lowering.js +66 -141
  186. package/dist/integrations/agent/runner-dispatch.js +143 -321
  187. package/dist/integrations/agent/runner.js +54 -14
  188. package/dist/integrations/lockfile.js +53 -101
  189. package/dist/llm/client.js +18 -6
  190. package/dist/llm/embedders/deterministic.js +2 -3
  191. package/dist/llm/embedders/profile.js +71 -0
  192. package/dist/llm/embedders/remote.js +11 -17
  193. package/dist/llm/feature-gate.js +0 -8
  194. package/dist/llm/index-passes.js +3 -5
  195. package/dist/llm/memory-infer.js +1 -2
  196. package/dist/llm/structured-call.js +5 -24
  197. package/dist/output/generic-render.js +23 -11
  198. package/dist/output/html-render.js +13 -10
  199. package/dist/output/render-registry.js +3 -32
  200. package/dist/output/shapes/helpers.js +25 -38
  201. package/dist/output/shapes/passthrough.js +1 -9
  202. package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
  203. package/dist/output/text/command-format.js +69 -31
  204. package/dist/output/text/helpers.js +1 -1
  205. package/dist/output/text/migrate.js +5 -14
  206. package/dist/output/text/proposal-format.js +48 -3
  207. package/dist/output/text/show-format.js +13 -17
  208. package/dist/output/text/workflow-format.js +0 -32
  209. package/dist/output/text.js +2 -0
  210. package/dist/registry/factory.js +4 -19
  211. package/dist/registry/network.js +66 -220
  212. package/dist/registry/providers/index.js +0 -2
  213. package/dist/registry/providers/skills-sh.js +3 -14
  214. package/dist/registry/providers/static-index.js +24 -26
  215. package/dist/registry/resolve.js +55 -131
  216. package/dist/scripts/akm-migrate-node.js +42948 -92369
  217. package/dist/scripts/akm-migrate.js +42935 -92354
  218. package/dist/setup/registry-stash-loader.js +4 -13
  219. package/dist/setup/semantic-assets.js +3 -44
  220. package/dist/setup/setup.js +1 -1
  221. package/dist/setup/steps/connection.js +5 -6
  222. package/dist/setup/steps/platforms.js +2 -2
  223. package/dist/setup/steps/tasks.js +25 -15
  224. package/dist/sources/provider-factory.js +17 -18
  225. package/dist/sources/providers/filesystem.js +2 -3
  226. package/dist/sources/providers/git-install.js +7 -1
  227. package/dist/sources/providers/git-provider.js +0 -3
  228. package/dist/sources/providers/git-stash.js +83 -21
  229. package/dist/sources/providers/npm.js +2 -4
  230. package/dist/sources/providers/provider-utils.js +5 -10
  231. package/dist/sources/providers/website.js +0 -2
  232. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  233. package/dist/sources/website-url.js +2 -2
  234. package/dist/storage/database.js +9 -35
  235. package/dist/storage/repositories/improve-ledger-repository.js +209 -0
  236. package/dist/storage/repositories/index-connection.js +39 -72
  237. package/dist/storage/repositories/index-entries-repository.js +131 -129
  238. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  239. package/dist/storage/repositories/index-entry-schema.js +101 -268
  240. package/dist/storage/repositories/index-fts-repository.js +86 -256
  241. package/dist/storage/repositories/index-links-repository.js +143 -0
  242. package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
  243. package/dist/storage/repositories/index-meta-repository.js +6 -4
  244. package/dist/storage/repositories/index-schema.js +257 -325
  245. package/dist/storage/repositories/index-utility-repository.js +8 -29
  246. package/dist/storage/repositories/index-vec-repository.js +133 -414
  247. package/dist/storage/repositories/outcome-repository.js +2 -1
  248. package/dist/storage/repositories/proposals-repository.js +104 -1
  249. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  250. package/dist/storage/repositories/salience-repository.js +1 -19
  251. package/dist/storage/repositories/task-history-repository.js +26 -4
  252. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  253. package/dist/storage/sqlite-migrations.js +136 -0
  254. package/dist/storage/sqlite-pragmas.js +11 -9
  255. package/dist/storage/sqlite-transaction.js +170 -0
  256. package/dist/storage/state-db-integrity.js +130 -0
  257. package/dist/tasks/activation-config.js +134 -62
  258. package/dist/tasks/backends/cron.js +191 -302
  259. package/dist/tasks/backends/exec-utils.js +2 -5
  260. package/dist/tasks/backends/launchd.js +141 -748
  261. package/dist/tasks/backends/schtasks.js +119 -623
  262. package/dist/tasks/prepare/prepare-support.js +5 -15
  263. package/dist/tasks/prepare/prepare.js +0 -2
  264. package/dist/tasks/resolve-akm-bin.js +20 -79
  265. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  266. package/dist/tasks/run/load-task.js +1 -1
  267. package/dist/tasks/scheduler-binding.js +20 -238
  268. package/dist/tasks/scheduler-invocation.js +136 -244
  269. package/dist/tasks/scheduler-lock.js +53 -0
  270. package/dist/tasks/scheduler-sync.js +368 -679
  271. package/dist/tasks/source/parse-task-source.js +55 -9
  272. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  273. package/dist/tasks/source/task-to-v4.js +464 -88
  274. package/dist/workflows/authoring/authoring.js +3 -12
  275. package/dist/workflows/compile.js +211 -0
  276. package/dist/workflows/concurrency-policy.js +13 -74
  277. package/dist/workflows/exec/child-invocation.js +3 -17
  278. package/dist/workflows/exec/child-workflow.js +32 -141
  279. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  280. package/dist/workflows/exec/environment.js +98 -0
  281. package/dist/workflows/exec/exec-unit.js +33 -140
  282. package/dist/workflows/exec/frozen-judge.js +7 -59
  283. package/dist/workflows/exec/native-executor.js +82 -341
  284. package/dist/workflows/exec/param-secrets.js +29 -47
  285. package/dist/workflows/exec/run-workflow.js +154 -387
  286. package/dist/workflows/exec/scheduler.js +9 -36
  287. package/dist/workflows/exec/step-work.js +127 -430
  288. package/dist/workflows/exec/unit-dispatch.js +11 -63
  289. package/dist/workflows/exec/unit-writer.js +8 -52
  290. package/dist/workflows/exec/worktree.js +39 -273
  291. package/dist/workflows/freeze/child-output-references.js +4 -15
  292. package/dist/workflows/freeze/environment.js +99 -92
  293. package/dist/workflows/freeze/freeze.js +172 -0
  294. package/dist/workflows/freeze/step-values.js +19 -21
  295. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  296. package/dist/workflows/freeze/targets/command.js +10 -33
  297. package/dist/workflows/freeze/targets/script.js +5 -12
  298. package/dist/workflows/freeze/targets/shell.js +3 -6
  299. package/dist/workflows/freeze/targets/task.js +25 -80
  300. package/dist/workflows/freeze/task-bindings.js +20 -67
  301. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  302. package/dist/workflows/ir/params.js +6 -51
  303. package/dist/workflows/ir/plan-hash.js +2 -34
  304. package/dist/workflows/parser.js +140 -43
  305. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  306. package/dist/workflows/renderer.js +36 -69
  307. package/dist/workflows/resource-limits.js +12 -120
  308. package/dist/workflows/runtime/agent-identity.js +8 -40
  309. package/dist/workflows/runtime/run-outputs.js +3 -6
  310. package/dist/workflows/runtime/run-plan.js +316 -0
  311. package/dist/workflows/runtime/runs.js +48 -200
  312. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  313. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  314. package/dist/workflows/validate-summary.js +2 -7
  315. package/docs/integration/bundling-akm.md +49 -42
  316. package/docs/migration/README.md +1 -0
  317. package/docs/migration/release-notes/0.9.17.md +43 -0
  318. package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
  319. package/docs/reference/cli.md +232 -135
  320. package/docs/reference/configuration.md +71 -57
  321. package/docs/reference/data-and-telemetry.md +20 -21
  322. package/docs/reference/tasks.md +105 -39
  323. package/docs/reference/workflow-schema.md +14 -18
  324. package/docs/reference/workflows.md +6 -9
  325. package/package.json +1 -1
  326. package/schemas/akm-config.json +115 -738
  327. package/schemas/akm-workflow.json +1 -0
  328. package/dist/assets/improve-strategies/graph-refresh.json +0 -15
  329. package/dist/assets/prompts/contradiction-judge.md +0 -33
  330. package/dist/assets/prompts/graph-extract-system.md +0 -1
  331. package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
  332. package/dist/assets/prompts/metadata-enhance-system.md +0 -1
  333. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
  334. package/dist/commands/health/advisories.js +0 -150
  335. package/dist/commands/health/metrics.js +0 -329
  336. package/dist/commands/health/surfaces.js +0 -102
  337. package/dist/commands/improve/anti-collapse.js +0 -83
  338. package/dist/commands/improve/collapse-detector.js +0 -432
  339. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  340. package/dist/commands/improve/consolidate/merge.js +0 -149
  341. package/dist/commands/improve/distill/promote-memory.js +0 -291
  342. package/dist/commands/improve/distill/quality-gate.js +0 -337
  343. package/dist/commands/improve/eval-cases.js +0 -52
  344. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  345. package/dist/commands/improve/proposal-envelope.js +0 -31
  346. package/dist/commands/improve/run-context.js +0 -123
  347. package/dist/commands/improve/shared.js +0 -31
  348. package/dist/commands/improve/source-identity.js +0 -28
  349. package/dist/commands/improve/triage.js +0 -96
  350. package/dist/commands/proposal/drain-policies.js +0 -151
  351. package/dist/commands/sources/update-transaction.js +0 -220
  352. package/dist/core/action-contributors.js +0 -28
  353. package/dist/core/config/config-version-shim.js +0 -101
  354. package/dist/core/fs-txn.js +0 -405
  355. package/dist/core/lexical-score.js +0 -25
  356. package/dist/core/maintenance-barrier.js +0 -167
  357. package/dist/execution/executable-identity.js +0 -105
  358. package/dist/execution/guarded-source.js +0 -427
  359. package/dist/indexer/db/graph-db.js +0 -444
  360. package/dist/indexer/graph/graph-boost.js +0 -427
  361. package/dist/indexer/graph/graph-dedup.js +0 -95
  362. package/dist/indexer/graph/graph-extraction.js +0 -1108
  363. package/dist/indexer/search/name-match.js +0 -35
  364. package/dist/indexer/search/ranking-contributors.js +0 -515
  365. package/dist/indexer/search/ranking-types.js +0 -4
  366. package/dist/indexer/walk/project-context.js +0 -192
  367. package/dist/integrations/agent/execution-cascade.js +0 -566
  368. package/dist/integrations/agent/execution-definitions.js +0 -202
  369. package/dist/integrations/agent/execution-lowering.js +0 -841
  370. package/dist/integrations/agent/execution-preparation.js +0 -98
  371. package/dist/integrations/agent/inline-execution.js +0 -74
  372. package/dist/llm/graph-extract.js +0 -728
  373. package/dist/llm/metadata-enhance.js +0 -96
  374. package/dist/registry/create-provider-registry.js +0 -29
  375. package/dist/registry/pinned-request-helper.js +0 -247
  376. package/dist/registry/pinned-transport.js +0 -717
  377. package/dist/sources/providers/index.js +0 -14
  378. package/dist/storage/engines/sqlite-migrations.js +0 -271
  379. package/dist/storage/repositories/canaries-repository.js +0 -107
  380. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  381. package/dist/storage/repositories/registry-cache.js +0 -113
  382. package/dist/tasks/scheduler-sync-preview.js +0 -52
  383. package/dist/tasks/source/task-to-v3.js +0 -507
  384. package/dist/workflows/freeze/resolve-steps.js +0 -86
  385. package/dist/workflows/freeze/source-freeze.js +0 -64
  386. package/dist/workflows/ir/compile.js +0 -321
  387. package/dist/workflows/ir/environment-v4.js +0 -330
  388. package/dist/workflows/ir/freeze-v4.js +0 -153
  389. package/dist/workflows/ir/schema-v4.js +0 -745
  390. package/dist/workflows/ir/schema.js +0 -354
  391. package/dist/workflows/program/schema.js +0 -77
  392. package/dist/workflows/runtime/checkin.js +0 -57
  393. package/dist/workflows/runtime/plan-classifier.js +0 -196
  394. package/dist/workflows/runtime/unit-checkin.js +0 -45
  395. package/dist/workflows/runtime/unit-phases.js +0 -20
  396. package/dist/workflows/schema.js +0 -4
  397. package/dist/workflows/source-ir/compile.js +0 -200
  398. package/dist/workflows/source-ir/program.js +0 -50
  399. package/dist/workflows/source-ir/result.js +0 -26
  400. package/dist/workflows/source-ir/schema.js +0 -786
  401. package/dist/workflows/source-ir/triggers.js +0 -79
  402. package/dist/workflows/source-ir/uses.js +0 -40
  403. package/dist/workflows/validator.js +0 -60
@@ -104,7 +104,7 @@ with an `INVALID_SHAPE_VALUE` usage error (exit 2) — an honest rejection rathe
104
104
  than a silent fallback. It returns a compact view suitable for capability
105
105
  discovery:
106
106
 
107
- - **show**: `type`, `name`, canonical `ref`, `description`, `tags`, `parameters`, `workflowTitle`, `action`, `run`, `origin`, `keys`, `related`
107
+ - **show**: `type`, `name`, canonical `ref`, `description`, `tags`, `parameters`, `workflowTitle`, `action`, `run`, `origin`, `keys`, `links`
108
108
 
109
109
  ## Exit Codes and Error Envelope
110
110
 
@@ -195,8 +195,8 @@ akm setup
195
195
  The setup wizard configures AKM in two steps:
196
196
 
197
197
  **Step 1 — Small model connection** (for background processing)
198
- Configures the OpenAI-compatible endpoint and model used for `akm index`
199
- metadata enhancement and `akm remember --enrich`. Supports Ollama,
198
+ Configures the OpenAI-compatible endpoint and model used for `akm improve`
199
+ and `akm remember --enrich`. Supports Ollama,
200
200
  OpenAI, LM Studio, or any custom endpoint. Skipping disables enrichment features.
201
201
 
202
202
  **Step 2 — Agent connection** (for agentic commands)
@@ -219,11 +219,11 @@ Build or refresh the search index.
219
219
 
220
220
  ```sh
221
221
  akm index # Incremental (only changed directories)
222
- akm index --full # Full rebuild (reuses unchanged embeddings — see below)
222
+ akm index --full # Re-drain every directory (keeps unchanged embeddings — see below)
223
223
  akm index --verbose # Print phase progress to stderr
224
224
  akm index --clean # Normal index + remove stale entries from the DB
225
225
  akm index --clean --dry-run # Report stale entries without deleting
226
- akm index --reembed # Force re-embedding of every entry
226
+ akm index --reembed # Discard stored vectors and re-embed every entry
227
227
  akm index --skip-if-locked # for scheduled/opportunistic runs: skip (exit 0) if a run is already in progress
228
228
  ```
229
229
 
@@ -254,25 +254,22 @@ Use `--clean` to resolve the edge case where a deleted file in an unchanged
254
254
  directory lingers in the index across incremental runs. With `--dry-run`, reports
255
255
  which entries would be removed without modifying the database.
256
256
 
257
- **`--full` no longer re-embeds unchanged content (#955):** a full rebuild
258
- (and an index-generation bump on first open under a new binary) used to
259
- delete every embedding unconditionally, forcing a full re-embed of the
260
- whole corpus even when nothing changed. Vectors about to be discarded are
261
- now salvaged (keyed by a hash of their content plus the fingerprint they
262
- were generated under) and handed straight back to unchanged entries at the
263
- start of the next embedding pass, with zero provider calls for them — a
264
- progress line reports the split (`Reused N embeddings from the previous
265
- generation; embedding M new.`). Content that changed even by one byte, or
266
- a fingerprint that no longer matches, still goes through the provider
267
- normally. `--reembed` is the way to force a full re-embed regardless.
268
-
269
- **`--reembed` flag:** Forces a full purge and re-embed of every entry,
270
- independent of the embedding-model-rename compatibility check described
271
- below. Ordinary indexing already tells a config-only rename of
272
- `embedding.model` (e.g. a gateway that changes how it names the same model)
273
- apart from a genuine model change, and keeps the stored vectors when they
274
- are still compatible; `--reembed` skips that check and forces a rebuild
275
- regardless of what it would have decided.
257
+ **`--full` does not re-embed unchanged content:** a full run re-drains and
258
+ re-persists every directory, but entry ids are kept, so a vector stays
259
+ attached to its entry and only entries whose search text changed go back to
260
+ the embedding provider. An incremental run re-persists only the files that
261
+ changed.
262
+
263
+ **Embedding model changes:** every stored vector records the embedding model
264
+ it was generated under (`embedding.model` plus dimension for a remote
265
+ endpoint, the local model name otherwise). When the configured model
266
+ changes, the next `akm index` re-embeds entry by entry, committing each
267
+ batch; nothing is purged first, an interrupted run resumes where it
268
+ stopped, and search serves only vectors from the configured model in the
269
+ meantime.
270
+
271
+ **`--reembed` flag:** Discards every stored vector and re-embeds all entries
272
+ under the configured model.
276
273
 
277
274
  **`--skip-if-locked` flag:** Every explicit `akm index` run acquires an
278
275
  opt-in, PID-liveness-only rebuild lock and releases it on exit — this is
@@ -303,10 +300,8 @@ invokes `akm index` directly should pass `--skip-if-locked` so it steps
303
300
  aside instead of piling up behind a longer rebuild (the shipped
304
301
  `index-refresh` task does this).
305
302
 
306
- `akm index` always rebuilds the search index and keeps metadata in the index.
307
- When a selected named LLM engine (`defaults.llmEngine` or an indexing-pass
308
- override) is configured and the per-pass gate allows it, metadata
309
- enhancement runs during indexing. In text mode, the default CLI UI shows a
303
+ `akm index` always rebuilds the search index and keeps metadata in the
304
+ index, generated deterministically. In text mode, the default CLI UI shows a
310
305
  spinner with processed-versus-total source counts; structured output modes
311
306
  (`json`, `yaml`, `jsonl`) stay clean and machine-readable.
312
307
 
@@ -323,8 +318,10 @@ Returns a JSON object with:
323
318
  | Field | Description |
324
319
  | --- | --- |
325
320
  | `version` | Current akm version |
326
- | `bundleDir` | Primary bundle directory — same resolution `akm bundle list` uses |
321
+ | `bundleDir` | Primary bundle directory — same resolution `akm bundle list` uses. Falls back to the platform-default location when no bundle resolves. |
327
322
  | `defaultBundle` | Name of the primary bundle from config, or `null` when none is configured |
323
+ | `configError` | Present only when `config.json` exists but could not be loaded (parse or schema failure); every config-derived field falls back to the same defaults a fresh install reports |
324
+ | `bundleDirError` | Present when a bundle IS configured (an env override or `bundles.*` in config) but its path doesn't resolve, OR when the platform-default fallback itself can't resolve (e.g. `HOME` unset) — absent for the ordinary "no bundle created yet" state, where `bundleDir` needs no explanation |
328
325
  | `dataDir` | Resolved data directory (`getDataDir()`) |
329
326
  | `configDir` | Resolved config directory (`getConfigDir()`) |
330
327
  | `cacheDir` | Resolved cache directory (`getCacheDir()`) |
@@ -334,11 +331,17 @@ Returns a JSON object with:
334
331
  | `semanticSearch` | Semantic search status: `mode`, `status`, and optional `reason`/`message` |
335
332
  | `registries` | Configured registries |
336
333
  | `sourceProviders` | Configured sources (filesystem, git, website, npm) |
337
- | `indexStats` | Index stats: `entryCount`, `byType` (per-asset-type breakdown), `lastBuiltAt`, `hasEmbeddings`, `vecAvailable` |
334
+ | `indexStats` | Index stats: `entryCount`, `byType` (per-asset-type breakdown), `links` (declared links per kind with `total` and `unresolved`; absent when the index holds none), `lastBuiltAt`, `hasEmbeddings`, `unreadable` (index.db exists but the filesystem refuses to read it — a permissions problem), `unavailable` (index.db is readable but the SQLite-level read didn't complete: locked by another akm process, a newer layout this akm can't understand, or a corrupt file) |
335
+
336
+ `akm info` never refuses: an unreadable config, an unresolvable bundle
337
+ directory, or an index.db that's locked, newer, older, corrupt, missing, or
338
+ empty each degrade the relevant field(s) above instead of failing the
339
+ command. It also never waits more than about 1.5s on a locked index.db,
340
+ regardless of the shared 30s lock-wait every write command otherwise uses,
341
+ and warns rather than refusing on an unrecognized flag.
338
342
 
339
343
  `semanticSearch.status` values:
340
- - `"ready-vec"` — native sqlite-vec extension active (fastest)
341
- - `"ready-js"` — pure JS fallback active (correct but slower at scale)
344
+ - `"ready-js"` — every entry has a vector; semantic search is active (the name is historical: `"ready-vec"`, the sqlite-vec variant, is gone)
342
345
  - `"pending"` — not yet initialized (run `akm index` to set up)
343
346
  - `"blocked"` — setup failed (see `reason` and `message` fields)
344
347
  - `"disabled"` — semantic search is turned off in config
@@ -379,7 +382,7 @@ default agent engine, and summarizes recent `improve_*` events. Unless
379
382
  to the `default-llm-engine` and every `configured-engines` LLM connection (and
380
383
  an SDK engine's LLM fallback), one probe per distinct endpoint, checks the
381
384
  installed akm-cli version against the latest GitHub release (`cli-version`),
382
- and runs the scheduler's recorded akm binary with `--version` to check it
385
+ runs the scheduler's recorded akm binary with `--version` to check it
383
386
  against the running CLI (`scheduler-binary`).
384
387
 
385
388
  Primary result fields:
@@ -387,23 +390,23 @@ Primary result fields:
387
390
  | Field | Description |
388
391
  | --- | --- |
389
392
  | `status` | Overall health verdict: `pass`, `warn`, or `fail` |
390
- | `hardChecks` | Deterministic checks such as `state-db-schema`, `state-db-round-trip`, `state-db-migrations`, `task-log-backing`, `active-runs`, `default-engine`, `model-map-files`, `default-llm-engine`, `configured-engines`, and `active-improve-strategy` |
393
+ | `hardChecks` | Deterministic checks such as `state-db-schema`, `state-db-round-trip`, `state-db-integrity`, `state-db-migrations`, `active-runs`, `default-engine`, `model-map-files`, `default-llm-engine`, `configured-engines`, and `active-improve-strategy` |
391
394
  | `advisories` | Non-fatal warnings including `semantic-search-runtime`, `session-extraction` (akmExtract pipeline health), `cli-version` (installed vs latest release), `thinking-control` (an `enableThinking: false` engine whose recorded usage still shows reasoning tokens), and `engine-last-used` (an engine bound to an enabled improve process with no recorded use in 30 days) |
392
- | `metrics` | Aggregate task/runtime metrics: `taskFailRate`, `agentFailureRate`, `stuckActiveRuns`, `logBackingRate`, `probeRoundTripMs` |
395
+ | `metrics` | Aggregate task/runtime metrics: `taskFailRate`, `agentFailureRate`, `stuckActiveRuns` |
393
396
  | `improve` | Recent improve-loop counts derived from `improve_invoked`, `improve_skipped`, and `improve_completed` events |
394
397
 
395
398
  The `improve` section includes counts for planned refs, reflect/distill actions,
396
- memory-prune actions, memory-inference writes, graph-extraction refreshes,
399
+ memory-prune actions, memory-inference writes,
397
400
  session-extraction outcomes (`sessionsScanned`, `sessionsExtracted`, `proposalsCreated`),
398
401
  dead-URL detections, and skip reasons observed in the selected time window.
399
402
 
400
- `state-db-migrations` reports whether `state.db`'s migration ledger has any
401
- pending entries (checked read-only, without applying anything). It `fail`s
402
- when migrations are pending — naming them and pointing at `akm migrate apply`
403
- — rather than the command crashing, which is what happens when `state.db`
404
- holds a pending historical-destructive migration and something other than
405
- `akm upgrade` / `akm migrate apply` opens it directly. Read this check's
406
- `status` instead of grepping akm's error text for that case.
403
+ `state-db-migrations` reports what `akm health`'s own open of `state.db`
404
+ applied. Every open applies pending migrations (copying the file to
405
+ `state.db.pre-<id>.bak` first when one drops schema), so the check passes and
406
+ names the applied IDs (`evidence.applied`) and the copy (`evidence.backupPath`).
407
+ It `fail`s only when a pending migration could not be applied — naming it and
408
+ pointing at `akm migrate apply` — rather than the command crashing. Read this
409
+ check's `status` instead of grepping akm's error text.
407
410
 
408
411
  `default-llm-engine` and `configured-engines` probe reachability (not just
409
412
  configuration) for a `kind: "llm"` engine — an unreachable endpoint is a hard
@@ -436,14 +439,6 @@ for an infrastructure reason (`llm_unavailable`, `read_failed`, `exception`,
436
439
  `locked_concurrent`) — naming the reason and, when recorded, the engine — and
437
440
  `pass` otherwise, with per-outcome counts.
438
441
 
439
- The indexed entity graph (entities/relations extracted from bundle assets) has
440
- no dedicated inspection command; its summary counts surface as an info-level
441
- metric in `akm health`. Graph data is automatically re-extracted on the first
442
- `akm improve` cycle after a `DB_VERSION` upgrade, and search ranking can
443
- optionally use graph-derived confidence-weighted boosts — tune
444
- `search.graphBoost.confidenceMode` and `search.graphBoost.confidenceWeight` in
445
- [`docs/reference/configuration.md#search-tuning`](configuration.md#search-tuning).
446
-
447
442
  ### search
448
443
 
449
444
  Search bundle assets, registries, or both.
@@ -499,6 +494,20 @@ query. The last case also adds one sanitized, endpoint-naming entry to
499
494
  preserved by `--shape agent` so machine consumers can lower their confidence
500
495
  instead of treating keyword fallback as healthy semantic ranking.
501
496
 
497
+ Ranking fuses two candidate lists by reciprocal rank (k = 60, equal weights):
498
+ BM25 over whole documents matching any non-stopword query word, and the
499
+ document vectors nearest to the query embedding, 100 candidates each. A hit's
500
+ `score` is its fused score, and equal scores are ordered by ref. The query is
501
+ embedded with the model's query template (see `embedding.queryTemplate` in
502
+ [`configuration.md`](configuration.md)); when the embedding takes longer than
503
+ `embedding.queryTimeoutMs` (default 3000) or fails, the search is served by
504
+ keyword ranking alone with `fts-fallback` and a warning. Filters (`--type`,
505
+ `--from`, `--filter`, `--belief`, the default session exclusion, proposed
506
+ quality) and one-hit-per-file deduplication narrow the fused list without
507
+ reordering it. Of entries with identical indexed content (the same body
508
+ saved under another name or in another bundle), only the highest-ranked is
509
+ kept.
510
+
502
511
  | Flag | Values | Default | Description |
503
512
  | --- | --- | --- | --- |
504
513
  | `--type` | `skill`, `command`, `agent`, `knowledge`, `instruction`, `workflow`, `script`, `memory`, `env`, `secret`, `lesson`, `task`, `session`, `fact`, `any` | `any` | Filter by asset type. Free-form and unvalidated — an unknown type returns no hits. Also accepts any adapter-defined type (e.g. `website`) — see [Bundle Types](bundle-types.md) for the open types each adapter emits. |
@@ -508,8 +517,7 @@ instead of treating keyword fallback as healthy semantic ranking.
508
517
  | `--filter` | `<key>=<value>` | _(none)_ | Scope filter — repeatable. Valid keys: `user`, `agent`, `run`, `channel`. Example: `--filter user=alice --filter channel=ops`. Narrows the result set; ranking is unchanged. |
509
518
  | `--include-proposed` | flag | `false` | Include entries with `quality: "proposed"` in the result set. Default search excludes them; `generated` and `curated` quality entries are always included. Unknown quality values warn once and remain searchable. |
510
519
  | `--belief` | `all`, `current`, `historical` | `all` | Memory belief filter. `current` keeps active memory beliefs; `historical` keeps contradicted/superseded/archived ones. |
511
- | `--no-project-context` | flag | `false` | Disable the automatic project-context ranking boost for this search only |
512
- | `--track-usage`, `--no-track-usage` | flag | `true` | Record or suppress local usage-event and ranking updates for this successful read |
520
+ | `--track-usage`, `--no-track-usage` | flag | `true` | Record or suppress local usage events for this successful read |
513
521
  | `--include-sessions` | flag | `false` | Include session assets, which are excluded from default results via `config.search.defaultExcludeTypes` |
514
522
  | `--format` | `json`, `jsonl`, `yaml`, `text`, `md`, `html` | `json` | Output format |
515
523
  | `--detail` | `brief`, `normal`, `full` | `brief` | Output verbosity level |
@@ -529,21 +537,12 @@ availability:
529
537
  - **`ref`** -- The asset handle to pass to `akm show` (for example
530
538
  `team//scripts/deploy.sh`); present at `brief`, `full`, and `agent` for local
531
539
  hits
532
- - **fragment provenance** -- when `ref` selects an indexed Markdown fragment,
533
- `selectedRef` and `parentRef` distinguish the ranked evidence from its parent;
534
- one-based `fragmentOrdinal`, `fragmentCount`, source-line bounds, neighbor
535
- refs, and separate fragment/parent size estimates are available without
536
- changing ranking. `estimatedTokens` describes the fragment for a
537
- fragment-qualified hit; `parentEstimatedTokens` describes the whole asset.
538
540
  - **`name`** -- The asset's filename or identifier; present at all levels
539
541
  - **`origin`** -- The source bundle (e.g. `npm:@scope/pkg`), present only for
540
542
  managed source assets; surfaced at `full` only
541
543
  - **`id`** -- Registry-level identifier (registry hits only)
542
- - **`matchStage`** -- Which stage of the progressive AND->OR lexical search
543
- ladder produced the hit: `exact` (strict AND), `prefix` (prefix AND), or
544
- `relaxed` (OR/prefix-OR recovery). Omitted for hits with no FTS component
545
- (e.g. a pure-semantic hybrid match) and for registry hits; surfaced at
546
- `normal`, `full`, and `--shape agent`
544
+ - **`whyMatched`** -- The hit's rank in each candidate list that returned
545
+ it (`lexical rank 3`, `vector rank 12`); surfaced at `full`
547
546
 
548
547
  The default brief shape is intentionally small. The exact field set per
549
548
  detail level (and per `--shape`) is authoritative in
@@ -553,9 +552,9 @@ assembled into the shape registry by the `src/output/shapes.ts` barrel:
553
552
  | Level | Local bundle hits | Registry hits |
554
553
  | --- | --- | --- |
555
554
  | `brief` (default) | `type`, `name`, `ref`, `action`, `estimatedTokens` | `name`, `installRef`, `score` |
556
- | `normal` | `type`, `name`, `description`, `action`, `score`, `estimatedTokens`, optional `warnings`/`quality`/`keys`/`matchStage` | `name`, `description`, `action`, `installRef`, `score`, optional `warnings` |
557
- | `full` | full hit object (includes `ref`, `origin`, `tags`, `whyMatched`, optional `warnings`, optional `quality`, optional `matchStage`, timings, bundle metadata) | full hit object |
558
- | `--shape agent` | `name`, `ref`, `type`, `path`, `editable`, conditional `editHint`, `description`, `action`, `score`, optional `estimatedTokens`/`keys`/`matchStage` | no local access fields |
555
+ | `normal` | `type`, `name`, `description`, `action`, `score`, `estimatedTokens`, optional `warnings`/`quality`/`keys` | `name`, `description`, `action`, `installRef`, `score`, optional `warnings` |
556
+ | `full` | full hit object (includes `ref`, `origin`, `tags`, `whyMatched`, optional `warnings`, optional `quality`, timings, bundle metadata) | full hit object |
557
+ | `--shape agent` | `name`, `ref`, `type`, `path`, `editable`, conditional `editHint`, `description`, `action`, `score`, optional `estimatedTokens`/`keys` | no local access fields |
559
558
 
560
559
  `--shape summary` is **not valid on `search`** — see
561
560
  [`--shape summary`](#--shape-summary) above; it is a usage error (exit 2)
@@ -594,29 +593,37 @@ akm curate "learn the release workflow" --from all --format text
594
593
  | `--type` | `skill`, `command`, `agent`, `knowledge`, `instruction`, `workflow`, `script`, `memory`, `env`, `secret`, `lesson`, `task`, `session`, `fact`, `any` | `any` | Filter curated results by asset type |
595
594
  | `--limit` | number | `4` | Maximum curated results |
596
595
  | `--from` | `local`, `registry`, `all` | `local` | Where to search before curating |
597
- | `--track-usage`, `--no-track-usage` | flag | `true` | Record or suppress local usage-event and ranking updates for this successful read |
598
-
599
- `akm curate` selects a small relevance-first shortlist. It preserves the
600
- strongest search hits first, uses only small type-aware nudges for close-score
601
- ties, can collapse obvious root/reference families into one top-level result,
602
- and falls back to token searches when the phrase result set is weak. Curate
603
- includes direct follow-up commands such as `akm show <ref>` or `akm bundle add <ref>`
604
- so you can immediately inspect or install what it found.
596
+ | `--track-usage`, `--no-track-usage` | flag | `true` | Record or suppress local usage events for this successful read |
597
+
598
+ `akm curate` takes the top `--limit` hits of one search, in search order, and
599
+ enriches each with a preview, run details and up to two support refs: the
600
+ assets the hit's declared links name (`xrefs:`, `supersededBy:` and the other
601
+ kinds `akm show` lists under `links`), what it links to before what links to
602
+ it, skipping assets curate already selected. With
603
+ `search.curateRerank.enabled`, a cross-encoder first reorders the top 30 fused
604
+ candidates (`search.curateRerank.topN`) by name, description and the start of
605
+ each asset's indexed content. Curate includes direct follow-up
606
+ commands such as `akm show <ref>` or `akm bundle add <ref>` so you can
607
+ immediately inspect or install what it found.
605
608
  `--detail` and `--shape agent` both work on curate output; `--shape summary`
606
609
  does not.
607
- Curate preserves the underlying `searchMode` and deduplicates semantic fallback
608
- warnings across its full-query and token-fallback searches.
610
+ Curate preserves the underlying search's `searchMode` and warnings.
609
611
  Agent-shaped local items include `ref`, `path`, and `editable`, plus `editHint`
610
612
  only for read-only items. Their `followUp` remains `akm show <ref>` rather than
611
613
  being replaced by clone guidance.
612
614
  Use `--type workflow` when you want curated step-by-step procedures instead of
613
615
  individual scripts, skills, or docs.
616
+ Curate returns no items, on purpose, when the input is not a task: a harness
617
+ or tool envelope (input that starts with an XML-style tag and contains a
618
+ closing tag, such as `<task-notification>…</task-notification>`) or the stash
619
+ README boilerplate. The `summary` then starts with `Curate abstained` and
620
+ names the reason, and `tip` says how to curate the task instead. Long input is
621
+ curated like any other.
614
622
  `akm curate` is safe to call frequently, including from a hook that fires on
615
623
  every prompt: it only ever reads the index as it currently stands (the same
616
624
  non-blocking `ensureIndex()` path `search` uses) and never waits on or
617
625
  contends with a full `akm index` rebuild in progress.
618
- Use `--no-track-usage` when this inspection must not update local usage or
619
- ranking signals.
626
+ Use `--no-track-usage` when this inspection must not record usage events.
620
627
 
621
628
  ### show
622
629
 
@@ -624,8 +631,8 @@ Display an asset by ref. On a markdown document `#fragment` selects one
624
631
  section by heading slug (falling back to case-insensitive heading text); an
625
632
  unmatched fragment lists the available slugs.
626
633
 
627
- Successful reads record local usage and ranking signals by default; pass
628
- `--no-track-usage` to suppress those updates.
634
+ Successful reads record local usage events by default; pass
635
+ `--no-track-usage` to suppress them.
629
636
 
630
637
  ```sh
631
638
  akm show scripts/deploy.sh
@@ -655,7 +662,7 @@ akm show memories/retro --filter user=alice --filter agent=claude
655
662
  | `--max-chars` | positive integer | `3200` for `lead` | Hard contextual content budget in characters; requires `--context lead` and is mutually exclusive with `--max-tokens`. |
656
663
  | `--max-tokens` | positive integer | _(none)_ | Approximate contextual budget using four characters per token; requires `--context lead` and is mutually exclusive with `--max-chars`. |
657
664
  | `--filter` | `<key>=<value>` | _(none)_ | Repeatable scope filter (`user`, `agent`, `run`, `channel`). |
658
- | `--track-usage`, `--no-track-usage` | flag | `true` | Record or suppress local usage-event and ranking updates for this successful read. |
665
+ | `--track-usage`, `--no-track-usage` | flag | `true` | Record or suppress local usage events for this successful read. |
659
666
 
660
667
  `meta` is not an asset type — `[<origin>//]meta[:<name>]` direct-reads a
661
668
  human-authored orientation doc from a bundle's optional `.meta/` directory
@@ -688,6 +695,16 @@ returns a compact view with `type`, `name`, `ref`, `description`, `tags`,
688
695
  `parameters`, `workflowTitle`, `action`, `run`, `origin`, and `keys`, plus the
689
696
  optional fragment metadata described below.
690
697
 
698
+ `links` lists the asset's declared links, grouped by kind: `outgoing` (the
699
+ assets its own `xrefs:`, `supersededBy:`, `contradictedBy:`,
700
+ `currentBeliefRefs:`, wiki `sources:`, `.derived` parent, page links, or
701
+ workflow and task targets name), `incoming` (the assets that name it), and
702
+ `unresolved` (tokens it names that match no indexed asset, as written). Each
703
+ kind is `{ "total": n, "refs": [...] }` with at most 10 refs; `total` counts
704
+ them all. The field is omitted when nothing links either way. Links are read
705
+ from frontmatter and parsed structure at index time, with no model; they do
706
+ not affect search ranking.
707
+
691
708
  Opaque fragment shows and `--context lead` keep `ref` as the canonical parent
692
709
  identity and add
693
710
  `selectedRef`, `parentRef`, one-based `fragmentOrdinal`, `fragmentCount`,
@@ -816,7 +833,7 @@ The old `--params <json>` bag is removed.
816
833
  | `--max-retries <n>` | When a step fails, reopen the same run and retry the failed step up to this many additional times. Range: 0 through 100; default 0. Gate rejection and interruption are not retried. |
817
834
  | `--timeout <duration>` | Abort the whole invocation after `N`, `Nms`, `Ns`, or `Nm`; bare `N` is milliseconds. The active step remains resumable. |
818
835
  | `--new` | Start a fresh run even when one is already active for this ref, instead of resuming it. The existing active run is left untouched — it is never abandoned automatically. A workflow ref only: passing a run id with `--new` is a usage error (exit 2). Parameter flags are allowed together with `--new`, since it is starting a new run. |
819
- | `--skip-if-locked` | If another akm process already holds this run's engine lease (`RUN_LEASE_HELD`), or `state.db` is busy with another writer (`STATE_DB_CONTENDED`), skip gracefully (exit 0) instead of failing (exit 75, `TransientError`). The envelope reports `{ skipped: { reason: "lock-held" \| "state-db-contended", message } }`. Every other failure (a bad flag, an unresolvable target) still fails loudly regardless of this flag. Use for high-frequency scheduled runs so they don't pile up failures while a longer-running invocation is in progress — same family as `improve --skip-if-locked`. |
836
+ | `--skip-if-locked` | If another akm process is already driving this run (it holds the run's lock file: `RUN_LEASE_HELD`), or `state.db` is busy with another writer (`STATE_DB_CONTENDED`), skip gracefully (exit 0) instead of failing (exit 75, `TransientError`). The envelope reports `{ skipped: { reason: "lock-held" \| "state-db-contended", message } }`. Every other failure (a bad flag, an unresolvable target) still fails loudly regardless of this flag. Use for high-frequency scheduled runs so they don't pile up failures while a longer-running invocation is in progress — same family as `improve --skip-if-locked`. |
820
837
 
821
838
  **Resuming an active run is announced, not silent.** Passing a ref that
822
839
  already has an active run in the current scope resumes that run rather than
@@ -941,8 +958,8 @@ Two output modes:
941
958
  - **`--format json`**: the full envelope — `ok`, `ref`, `title`,
942
959
  `sourceFormat`, `sourcePath`, `irVersion`, `planHash`, `published` (always
943
960
  `false`, so a consumer can never mistake this for a run envelope),
944
- `execution`, `budget?`, `params?`, `outputs?`, `steps[]`, `sourceReadSet[]`,
945
- `notices[]`, `warnings[]`. Each step entry carries an `expansion` field
961
+ `execution`, `budget?`, `params?`, `outputs?`, `steps[]`, `notices[]`,
962
+ `warnings[]`. Each step entry carries an `expansion` field
946
963
  naming how its target was reached: `{via: "direct"}`, `{via: "task",
947
964
  taskRef}`, or — for a step composing a child workflow —
948
965
  `{via: "child", childRef, childPlanHash, childOutputs, steps[]}` with the
@@ -1038,7 +1055,7 @@ akm bundle add https://docs.example.com --max-pages 100 --max-depth 5
1038
1055
 
1039
1056
  | Flag | Description |
1040
1057
  | --- | --- |
1041
- | `--name` | Human-friendly name for the source |
1058
+ | `--name` | The bundle key. A contract, not a hint: it must be a legal bundle slug (no `:` `.` `#` `/` or whitespace) and not already taken by a different bundle, or the add fails before any write. Re-adding an already-installed source under a different `--name` than it already carries also fails — use `akm bundle rename <old> <new>` instead. Omit it and akm derives a name (falling back to a `-<hash>` suffix on a collision). |
1042
1059
  | `--provider` | Explicit provider for declarative source configuration; normally inferred from the input |
1043
1060
  | `--writable` | Mark a git source as writable so `akm sync` also pushes (default: false) |
1044
1061
  | `--options` | Provider options as JSON (e.g. `'{"ref":"main"}'`) |
@@ -1209,6 +1226,42 @@ in `processed`/`plainSynced`; rejected entries report `status: "blocked"` and a
1209
1226
  security code; provider or transaction errors report `status: "failed"`. The
1210
1227
  command continues with later bundles without half-publishing a blocked one.
1211
1228
 
1229
+ ### bundle rename
1230
+
1231
+ Rename a configured bundle's key everywhere akm itself persists it — the one
1232
+ command allowed to change it (renaming by hand-editing `config.json`'s
1233
+ `bundles` key strands every durable ref the tool minted under the old id; see
1234
+ `akm health` / the startup warning that names this).
1235
+
1236
+ ```sh
1237
+ akm bundle rename old-name new-name
1238
+ akm bundle rename old-name new-name --dry-run # Show the plan; write nothing
1239
+ ```
1240
+
1241
+ | Flag | Description |
1242
+ | --- | --- |
1243
+ | `--dry-run` | Report what would change (index/state row counts, scheduler refs, content files that still mention the old name) without writing anything |
1244
+
1245
+ `<new>` must be a legal, unused bundle slug (the same `--name` contract `akm
1246
+ bundle add` enforces) or the rename fails before any write. Rewritten: the
1247
+ config `bundles` key; `defaultBundle`/`defaultWriteTarget` when they name the
1248
+ old id; every `scheduler.enabled[].ref` with the old `<old>//` prefix; the
1249
+ lockfile entry id; every indexed entry's `bundle_id`/ref; and this tool's own
1250
+ state rows that name the old bundle (`proposals.ref`, a pending proposal's
1251
+ write target, and workflow `task_history.target_ref`). Reported, never
1252
+ rewritten: refs inside the bundle's own CONTENT (cross-references, `uses:` in
1253
+ a task, `supersededBy`) — the result's `contentRefs` lists the indexed files
1254
+ that still spell the old `<old>//` prefix so you can fix them by hand. A real
1255
+ run also re-syncs native scheduler bindings under the new name (`taskSync` in
1256
+ the result reports the outcome, never thrown, since config/index/state are
1257
+ already renamed by then). `taskSync.ok` is `false` both when the sync call
1258
+ itself fails and when it comes back reporting one or more
1259
+ `taskSync.result.failures` — a binding that failed to prepare has already
1260
+ lost its old native row and stays unscheduled until you re-run
1261
+ `akm task sync`; `--dry-run` lists the installed native rows that still name
1262
+ the old bundle (`nativeSchedulerRows`) so you can see what that sync will
1263
+ replace.
1264
+
1212
1265
  ### upgrade
1213
1266
 
1214
1267
  Upgrade `akm` itself to the latest release. Standalone binaries are downloaded,
@@ -1432,7 +1485,7 @@ akm remember "Deployment needs VPN access" --bundle team-bundle
1432
1485
  | `--expires <dur>` | Expiry shorthand (`30d`, `12h`, `6m`). Resolved to an ISO date |
1433
1486
  | `--source <s>` | Free-form source reference — URL, asset ref, file path, or any string |
1434
1487
  | `--xref <ref>` | Cross-reference ref recorded in the memory's `xrefs:` frontmatter list. Repeatable: `--xref knowledge/auth-flow --xref memories/vpn-note`. Each ref must resolve in the write target or a configured source (read-only sources count); an unresolvable ref fails with exit 2 before anything is written. More than 5 refs warns (soft cap) but still writes. Does not trigger the tags-required check. |
1435
- | `--supersedes <ref>` | Ref of an existing asset this memory corrects. Repeatable. Writes the correction with the old ref folded into its `xrefs:` (correction provenance) AND demotes the old asset — `beliefState: superseded` + `supersededBy: [<new ref>]`, a metadata-only frontmatter edit that preserves every other key and the body — then reindexes it so ranking prefers the correction and `--belief current` hides the stale version immediately. An unresolvable ref fails with exit 2 before anything is written or demoted; so does a ref naming the asset being written itself (a correction cannot supersede itself, e.g. `--force` overwriting the same name). A ref that resolves only outside the write target and the working bundle still writes the correction but skips the demotion: stderr warns and the JSON output reports `superseded: [{ref, applied: false, reason}]` — the reason names the `--bundle` remedy when the old asset lives in a configured writable source. An old asset whose existing frontmatter is not parseable YAML is skipped the same way (`applied: false`) instead of being rewritten lossily. Re-running the same correction is idempotent. On a git write target the correction and the demoted old asset land in the same single boundary commit. |
1488
+ | `--supersedes <ref>` | Ref of an existing asset this memory corrects. Repeatable. Writes the correction with the old ref folded into its `xrefs:` (correction provenance) AND demotes the old asset — `beliefState: superseded` + `supersededBy: [<new ref>]`, a metadata-only frontmatter edit that preserves every other key and the body — then reindexes it so `--belief current` hides the stale version immediately. An unresolvable ref fails with exit 2 before anything is written or demoted; so does a ref naming the asset being written itself (a correction cannot supersede itself, e.g. `--force` overwriting the same name). A ref that resolves only outside the write target and the working bundle still writes the correction but skips the demotion: stderr warns and the JSON output reports `superseded: [{ref, applied: false, reason}]` — the reason names the `--bundle` remedy when the old asset lives in a configured writable source. An old asset whose existing frontmatter is not parseable YAML is skipped the same way (`applied: false`) instead of being rewritten lossily. Re-running the same correction is idempotent. On a git write target the correction and the demoted old asset land in the same single boundary commit. |
1436
1489
  | `--auto` | Apply heuristic tagging from the body (opt-in, zero-latency, pure TS) |
1437
1490
  | `--enrich` | Call the configured LLM for tag/description proposals (opt-in, 10s timeout, fails soft) |
1438
1491
  | `--user <id>` | Scope this memory to a user id. Persisted as the canonical `scope_user` frontmatter key. |
@@ -1565,9 +1618,9 @@ akm feedback skills/code-review --negative --reason "flaky" --tag slice:train --
1565
1618
  Specify exactly one of `--positive` or `--negative`. The ref must already be
1566
1619
  present in the current local index.
1567
1620
 
1568
- The `--applied-to` flag drives the lesson-strength ranking signal: lessons that
1569
- have demonstrably helped resolve tasks receive a small additive ranking boost
1570
- (capped at +0.3) so they float to the top of search.
1621
+ The `--applied-to` flag records the lesson-strength signal: each credit is
1622
+ kept in the lesson's `lessonStrength[]` frontmatter. Search ranking does not
1623
+ use it.
1571
1624
 
1572
1625
  ### log
1573
1626
 
@@ -1671,18 +1724,25 @@ wrapper over the standalone `akm-migrate` executable (installed alongside
1671
1724
  akm has ever written so the CLI proper reads only current schemas. The steps,
1672
1725
  in order:
1673
1726
 
1674
- 1. legacy config `extraParams` keys lifted onto first-class engine fields
1675
- (`configExtraParams`);
1727
+ 1. config.json rewritten in its current shape (`configFile`): retired and
1728
+ unknown keys dropped, legacy `extraParams` lifted onto first-class engine
1729
+ fields, the legacy `stashDir`/`sources[]`/`installed` layout converted to
1730
+ `bundles`/`defaultBundle`, `configVersion` bumped — the same pipeline
1731
+ every load already runs in memory, so this only persists it, under a
1732
+ backup;
1676
1733
  2. pending `state.db` migrations, historical-destructive ones included, with
1677
1734
  a verified sibling safety copy (`stateMigrations`) — the only path besides
1678
1735
  `akm upgrade` that admits released migration 018, which an ordinary
1679
1736
  command refuses;
1680
- 3. task-v2 files to task v3, then task-v3 files to task source v4
1681
- (`taskV3Migration`, `taskV4Migration`), each keeping its own lock, backup,
1682
- prevalidation, and rollback, so a file blocked in the first generation does
1683
- not stop the second from converting files already at `version: 3`;
1684
- 4. superseded pre-0.9.0 `.akm` residue and stale filesystem transactions
1685
- (`deadResidue`, `staleTxns`).
1737
+ 3. task files at version 2 or 3, and version 4 files still carrying the
1738
+ retired `schedule[].enabled` key, rewritten as task source v4
1739
+ (`taskFiles`) under one backup directory per run, each emitted document
1740
+ re-parsed by the runtime v4 parser first; a file the planner cannot
1741
+ convert unambiguously is reported `blocked` and left alone;
1742
+ 4. superseded residue removed (`deadResidue`): pre-0.9.0 `.akm` leftovers in
1743
+ the stash, and the transaction-journal, maintenance-barrier, lock-mutex and
1744
+ version-stamp files older releases kept under `$DATA`, `$STATE` and
1745
+ `$CONFIG`.
1686
1746
 
1687
1747
  ```sh
1688
1748
  akm migrate status
@@ -1701,6 +1761,16 @@ blocked-reason table and worked examples, and
1701
1761
  [Bundling akm](../integration/bundling-akm.md) for the plan JSON shape and
1702
1762
  how to drive this from a container/image boot step.
1703
1763
 
1764
+ Each step above runs under its own catch: a step's own anomaly is always
1765
+ recorded in the plan's `failedSteps: [{step, error}]` instead of ending the
1766
+ whole run — the remaining steps still run in order. Under `apply`, a failed
1767
+ step's section falls back to its read-only preview; if that fails too, the
1768
+ fallback adds its own `failedSteps` entry, and the section is absent from the
1769
+ plan. Any `failedSteps` entry
1770
+ forces `status: "blocked"` and adds a matching line to `blockers`, so
1771
+ `akm migrate status|apply` reports the plan and exits 1 (not the internal-error
1772
+ 70) the same way it does for any other blocked plan.
1773
+
1704
1774
  ### config
1705
1775
 
1706
1776
  Read and write configuration. Bare `akm config` (no subcommand) is a usage
@@ -2374,10 +2444,14 @@ akm improve report --since 7d # ...aggregated over every real run start
2374
2444
  `akm improve` is the public entrypoint for whole-bundle, type-scoped, and
2375
2445
  ref-scoped improvement. It owns the memory-cleanup and lesson-distillation
2376
2446
  flow. A qualified scope such as `team//skills/code-review` selects that bundle;
2377
- a different explicit `--bundle` is a usage error. Inspecting or re-minting the
2378
- collapse-detector canary set is maintainer tooling, not a CLI verb — run
2379
- `bun scripts/refresh-canary-set.ts` (add `--refresh` to mint a new set and
2380
- deactivate the old one; old rows and their cycle history are retained).
2447
+ a different explicit `--bundle` is a usage error.
2448
+
2449
+ Every stage records what it did with each asset in the improve ledger
2450
+ (`improve_ledger` in `state.db`) and reads it before any model call: an asset
2451
+ whose proposal was rejected waits 14 days (reflect), 30 days (distill) or 7
2452
+ days (other stages) before it is tried again; an expired proposal waits one
2453
+ day; an asset a stage looked at and left unchanged is revisited after 7 days,
2454
+ or as soon as new feedback (or, for consolidation, an edit) arrives.
2381
2455
 
2382
2456
  Built-in `default` and `frequent` leave the improve-stage extract process off,
2383
2457
  and `default` plus `reflect-distill` leave proactive maintenance off. Use the
@@ -2453,14 +2527,15 @@ clock, or session-log changes.
2453
2527
 
2454
2528
  `plan.processes` (#947) is the resolved process -> engine -> model routing
2455
2529
  table: one row per improve process (`reflect`, `distill`, `consolidate`,
2456
- `memoryInference`, `graphExtraction`, `extract`, `validation`, `triage`,
2530
+ `memoryInference`, `extract`, `validation`, `triage`,
2457
2531
  `proactiveMaintenance`), plus a `triage.judgment` row when the strategy
2458
2532
  configures a judgment engine. Each row carries `enabled`, the resolved
2459
2533
  `engine`/`model` (llm-backed processes only) and `engineKind`, this process's
2460
2534
  own lowering `notices`, and — for reflect/distill/consolidate only —
2461
2535
  `eligibleRefs`, the count of this run's `effectiveRefs` the process would act
2462
- on (`shouldSkipRef`'s allowedTypes/process-disabled check; a count, not a
2463
- per-ref matrix, to keep the envelope bounded). A row that could not resolve an
2536
+ on (`shouldSkipRef`'s allowedTypes/excludeRefPrefixes (reflect only)/
2537
+ process-disabled check; a count, not a per-ref matrix, to keep the envelope
2538
+ bounded). A row that could not resolve an
2464
2539
  engine or credential carries `unavailable: {configKey, reason}` — the same
2465
2540
  data behind `skippedProcesses` above, reshaped per process. When the process
2466
2541
  resolved a real engine whose credential just isn't reachable here, the row
@@ -2480,7 +2555,7 @@ default probe-on behavior) to check whether a named engine actually answers.
2480
2555
  builds the exact prompt reflect would send for one asset — the same source
2481
2556
  resolution, runner selection, feedback/schema-hint/related-lesson/rejected-
2482
2557
  proposal gathering `akm improve`'s live reflect step uses — and prints it
2483
- without acquiring a dispatch lease, so it never calls an engine. Add
2558
+ without reading a credential, so it never calls an engine. Add
2484
2559
  `--format text` (the default JSON/yaml envelope escapes the prompt into one
2485
2560
  line, which defeats a by-eye read) to confirm by eye that recent feedback is
2486
2561
  framed as an unverified report to investigate (never a fact to insert
@@ -2488,9 +2563,7 @@ verbatim) and that the response contract tells the model never to emit the
2488
2563
  truncation marker or any content from outside the shown asset.
2489
2564
 
2490
2565
  When reinforced facts need promotion, `knowledge` is the higher-authority
2491
- destination than `memory`. The deterministic search ranking also prefers
2492
- `knowledge` over `memory` hits, including inferred `.derived` memories, when
2493
- the evidence is otherwise comparable.
2566
+ destination than `memory`.
2494
2567
 
2495
2568
  #### improve report
2496
2569
 
@@ -2509,7 +2582,7 @@ field on the result (`result_json` in `improve_runs`, and in the
2509
2582
  `calls`, `failures`, `promptTokens`, `completionTokens`, `totalTokens`,
2510
2583
  `reasoningTokens`, and `totalDurationMs`. `noCalls` lists every LLM-backed
2511
2584
  process (`reflect`, `distill`, `consolidate`, `memoryInference`,
2512
- `graphExtraction`, `extract`, `validation` — not `triage`/`proactiveMaintenance`,
2585
+ `extract`, `validation` — not `triage`/`proactiveMaintenance`,
2513
2586
  which never make an attributable LLM call themselves) the active strategy
2514
2587
  enabled but that ended the run with zero calls, each with a `reason` drawn
2515
2588
  from the existing skip-reason vocabulary: `"engine_unavailable"` (also in
@@ -2647,6 +2720,7 @@ akm proposal list
2647
2720
  akm proposal list --queue team-bundle
2648
2721
  akm proposal list --status pending|accepted|rejected|reverted
2649
2722
  akm proposal list --ref skills/deploy
2723
+ akm proposal list --generator consolidate-pair
2650
2724
  ```
2651
2725
 
2652
2726
  | Flag | Description |
@@ -2655,6 +2729,12 @@ akm proposal list --ref skills/deploy
2655
2729
  | `--status` | Filter by `pending`, `accepted`, `rejected`, or `reverted` |
2656
2730
  | `--ref` | Filter by asset ref. A qualified ref preserves bundle identity; a short ref matches that concept in the selected queue |
2657
2731
  | `--type` | Reserved type filter |
2732
+ | `--generator <name>` | Filter by generator/source (e.g. `reflect`, `distill`, `consolidate-pair`) — the same value `accept`/`reject --generator` take |
2733
+
2734
+ Each retire proposal's `retirement.continuityRisk`, when present, also shows
2735
+ in the default listing (`⚠ continuity-risk` inline) and in `proposal show`'s
2736
+ text output (the specific failing/unverified queries) — see
2737
+ [Retirement continuity](https://github.com/itlackey/akm/blob/main/docs/architecture/improvement.md#retirement-continuity).
2658
2738
 
2659
2739
  Each proposal record carries an optional `confidence` field (0..1) emitted by
2660
2740
  reflect/propose runs. It is recorded for triage and ranking only — there is no
@@ -2776,27 +2856,27 @@ requires `--reason`.
2776
2856
 
2777
2857
  #### proposal drain
2778
2858
 
2779
- Drain the standing pending-proposal backlog using a deterministic triage
2780
- policy, instead of adjudicating proposals one at a time. Default mode stages
2781
- decisions (queue mode); pass `--promote` to actually accept matching
2782
- proposals.
2859
+ Drain the standing pending-proposal backlog instead of adjudicating proposals
2860
+ one at a time. One rule decides each proposal: a proposal whose quality judge
2861
+ passed on its current content is accepted (unless its target changed since it
2862
+ was minted — that one is auto-rejected as `stale-target`); an empty diff is
2863
+ rejected; everything else goes to the judgment tier when one is enabled, and
2864
+ is otherwise left for review. Default mode stages decisions (queue mode); pass
2865
+ `--promote` to actually accept.
2783
2866
 
2784
2867
  ```sh
2785
2868
  akm proposal drain --dry-run # Preview without writing
2786
- akm proposal drain --policy personal-stash --promote -y
2787
- akm proposal drain --policy conservative --max-accepts 10 --promote -y
2788
- akm proposal drain --max-diff-lines 50 --older-than 7 --promote -y
2869
+ akm proposal drain --promote -y
2870
+ akm proposal drain --max-accepts 10 --older-than 7 --promote -y
2789
2871
  akm proposal drain --strategy default --promote -y # Read the triage block from an improve strategy
2790
2872
  ```
2791
2873
 
2792
2874
  | Flag | Description |
2793
2875
  | --- | --- |
2794
- | `--policy` | Built-in preset (`personal-stash`, `conservative`, `manual`) or a path to a policy file |
2795
- | `--strategy` | Read the triage block (policy, apply mode, ceilings, judgment) from this improve strategy instead |
2796
- | `--promote` | Promote (accept) matching proposals. Default is queue mode — stage only, no writes to assets. |
2876
+ | `--strategy` | Read the triage block (apply mode, ceilings, judgment) from this improve strategy instead |
2877
+ | `--promote` | Promote (accept) judge-passed proposals. Default is queue mode — stage only, no writes to assets. |
2797
2878
  | `--dry-run` | List what would be accepted/rejected/deferred, without writing |
2798
2879
  | `--max-accepts` | Hard per-run accept ceiling; accepts beyond this are reported as `skippedByCap` |
2799
- | `--max-diff-lines` | Defer (never promote) accepts whose proposed content exceeds this many lines |
2800
2880
  | `--older-than` | Only consider proposals created more than this many days ago |
2801
2881
  | `--judgment` | Explicitly enable the judgment tier for this standalone drain, including when the selected strategy says `judgment.enabled: false`; execution overrides still come from that strategy. Without this flag, strategy judgment config does not enable standalone drain judgment. A missing runner remains a no-op with a logged `triage_deferred` summary. |
2802
2882
  | `-y`, `--yes` | Skip the confirmation prompt (required in non-interactive mode for promotion) |
@@ -2845,10 +2925,10 @@ akm task prune --yes # Remove every currently-computed or
2845
2925
  akm task prune --id ghost,stale --yes # Remove only the named orphan ids
2846
2926
  ```
2847
2927
 
2848
- `task add` also accepts `--disabled` (register but leave off in the OS
2849
- scheduler), `--force` (overwrite an existing task with the same id), and
2850
- `--rebind` (explicitly permit scheduler creation from a local invocation that
2851
- would otherwise be considered ineligible).
2928
+ `task add` also accepts `--disabled` (write the task but leave its ref out of
2929
+ this host's scheduler activation), `--force` (overwrite an existing task with
2930
+ the same id), and `--rebind` (also point the bundle's installed scheduler rows
2931
+ at this akm invocation, as `akm task sync --rebind` does).
2852
2932
 
2853
2933
  `akm task list [<query>] [--limit <n>] [--from local|registry|all]` is a
2854
2934
  pure alias for `akm search --type task` with the query, `--limit`, and
@@ -2892,22 +2972,39 @@ time. Each run is recorded as a row in the durable `task_history` table
2892
2972
  no `task_invoked`/`task_completed` event type on the `akm log` stream.
2893
2973
 
2894
2974
  Task source cannot enable itself. `akm task enable <fully-qualified-ref>` adds
2895
- an exact source-bound `{kind, ref, sourceId}` grant to this host's
2896
- `scheduler.enabled` config and
2897
- syncs that bundle; `akm task disable` removes it and unschedules the task.
2975
+ the ref to this host's `scheduler.enabled` list and syncs that bundle; `akm task disable` removes it and unschedules the task.
2898
2976
  Manual `akm task run` remains available. To remove a task, delete its file
2899
2977
  (`<bundle>/tasks/<id>.yml`) and run `akm task sync` — sync uninstalls the
2900
2978
  orphaned scheduler entry.
2901
2979
 
2902
- `akm task sync --dry-run` prints the planned adds/updates/removes (removals
2903
- carry their owning bundle) without touching the scheduler — zero writes.
2904
- Exits non-zero when removals are pending, so it can gate a CI/health check
2905
- on "sync would change something."
2980
+ A config with no `scheduler.enabled` list at all (written before 0.9.17)
2981
+ means "keep what is installed": `akm task sync` takes the akm-written rows
2982
+ already in the scheduler as this host's choice and writes the list; an
2983
+ explicit list is never second-guessed. `akm task sync --dry-run` prints the
2984
+ planned adds/updates/removes (removals carry their owning bundle) without
2985
+ touching the scheduler — zero writes. Exits non-zero when removals are pending, so it can
2986
+ gate a CI/health check on "sync would change something."
2987
+
2988
+ `sync`'s (and `sync --dry-run`'s) result always carries `failures: [{path,
2989
+ ref?, reason}]` — one entry per item sync could not reconcile: a task/workflow
2990
+ source that failed to parse or prepare (its installed row is left as it is),
2991
+ two sources claiming the same scheduler id, a desired binding whose id is
2992
+ already scheduled from a different bundle or installation, a row whose
2993
+ install or removal failed, or — for an unscoped, multi-bundle sync — a whole
2994
+ bundle whose sources could not be read. Every one of these is a per-item
2995
+ failure: the item is left exactly as it was and reported here, while every
2996
+ OTHER item and bundle in the same sync still reconciles; with `--bundle`,
2997
+ that one bundle IS the whole sync, so a bundle that cannot be read raises
2998
+ instead of being reported here. `failures` is empty on a fully clean sync; a
2999
+ non-empty `failures` still exits non-zero, same as a pending removal. A
3000
+ crontab whose akm markers are malformed is refused unmodified, and another
3001
+ akm process holding the scheduler lock makes sync exit 75 (retry shortly).
2906
3002
 
2907
3003
  `akm task prune` reclaims installed scheduler entries that `sync` can never
2908
- clean up on its own: entries whose own `--scheduler-context` descriptor no
2909
- longer resolves to a live bundle (a corrupt/missing descriptor, or the
2910
- bundle directory it pointed at is gone). It never touches an entry that
3004
+ clean up on its own: entries that no longer resolve to a live bundle (a row
3005
+ whose `AKM_BUNDLE_DIR` names a directory that is gone, or a row written
3006
+ before 0.9.17-alpha.7 whose `--scheduler-context` descriptor cannot be
3007
+ read). It never touches an entry that
2911
3008
  still resolves to a live bundle — that's `sync`'s job. Like `sync
2912
3009
  --dry-run`, the default is a dry-run preview (zero scheduler writes) that
2913
3010
  exits non-zero when there are candidates to remove; `--yes` executes the