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
@@ -8,11 +8,12 @@
8
8
  * (block scalars, multi-line strings, nested objects, flow sequences, escape
9
9
  * sequences) is handled correctly without a brittle hand-rolled state machine.
10
10
  */
11
+ import { createHash } from "node:crypto";
11
12
  import fs from "node:fs";
12
13
  import { parse as yamlParse, stringify as yamlStringify } from "yaml";
13
14
  import { existingFileMode, writeFileAtomic } from "../common.js";
14
15
  import { recordWrittenPath } from "../write-provenance.js";
15
- import { assembleAsset, serializeFrontmatter } from "./asset-serialize.js";
16
+ import { assembleAsset, assembleAssetFromString, serializeFrontmatter } from "./asset-serialize.js";
16
17
  /**
17
18
  * Parse YAML frontmatter from a Markdown (or similar) string.
18
19
  *
@@ -451,6 +452,110 @@ export function parseYamlScalar(value) {
451
452
  }
452
453
  return value;
453
454
  }
455
+ // ── Bookkeeping-insensitive freshness (STALE, R20) ────────────────────────────
456
+ /**
457
+ * Frontmatter keys akm's own improve/index passes write into an EXISTING
458
+ * asset as pipeline bookkeeping — never a change to the asset's authored
459
+ * meaning. `salience`/`salienceInputs` come from {@link writeSalienceToFrontmatter}
460
+ * (distill); `inferenceProcessed` comes from memory inference
461
+ * (`indexer/passes/memory-inference.ts`). A pending proposal's mint-time
462
+ * before-hash is sensitive to these rewrites even though nothing a reviewer
463
+ * or the proposal's own diff cares about actually changed, which stales out
464
+ * proposals that a same-run bookkeeping pass touches after mint. See
465
+ * {@link computeNormalizedContentHash} and {@link carryForwardBookkeepingFrontmatter}.
466
+ *
467
+ * Deliberately excludes `beliefState`/`contradictedBy`/`supersededBy`: those
468
+ * are editorial state (contradiction/supersession demotions), not derived
469
+ * audit metadata — a promote should still refuse when one of those changed
470
+ * underneath a pending proposal.
471
+ */
472
+ export const BOOKKEEPING_FRONTMATTER_KEYS = ["salience", "salienceInputs", "inferenceProcessed"];
473
+ function sha256Hex(content) {
474
+ return createHash("sha256").update(content, "utf8").digest("hex");
475
+ }
476
+ /**
477
+ * Hash of `raw` with {@link BOOKKEEPING_FRONTMATTER_KEYS} removed from its
478
+ * frontmatter and the remaining frontmatter re-serialized with sorted keys,
479
+ * so pipeline-only bookkeeping rewrites (and incidental key-order churn)
480
+ * cannot change the result. The body's boundary is normalized the same way
481
+ * {@link assembleAssetFromString} normalizes it (leading newlines stripped,
482
+ * exactly one trailing newline) before hashing, so the body-boundary shift
483
+ * that `writeSalienceToFrontmatter` and the `assembleAsset` bookkeeping
484
+ * rewrite both introduce cannot change the result either; the body's
485
+ * interior is still hashed verbatim.
486
+ *
487
+ * An empty frontmatter block (`---\n---\n…`) is treated as `{}` rather than
488
+ * falling back to the raw hash, so adding bookkeeping keys to a memory with
489
+ * no prior frontmatter fields is still insensitive.
490
+ *
491
+ * Falls back to hashing `raw` verbatim when there is no frontmatter block at
492
+ * all or it fails to parse — normalizing unparsable frontmatter isn't safe,
493
+ * and the caller's existing raw-hash check already covers that case.
494
+ */
495
+ export function computeNormalizedContentHash(raw) {
496
+ const block = parseFrontmatterBlock(raw);
497
+ if (!block)
498
+ return sha256Hex(raw);
499
+ let data;
500
+ try {
501
+ data = block.frontmatter.trim() ? yamlParse(block.frontmatter) : {};
502
+ }
503
+ catch {
504
+ return sha256Hex(raw);
505
+ }
506
+ if (data === null || typeof data !== "object" || Array.isArray(data))
507
+ return sha256Hex(raw);
508
+ const normalized = { ...data };
509
+ for (const key of BOOKKEEPING_FRONTMATTER_KEYS)
510
+ delete normalized[key];
511
+ const canonicalFrontmatter = yamlStringify(normalized, { sortMapEntries: true }).trimEnd();
512
+ return sha256Hex(assembleAssetFromString(canonicalFrontmatter, block.content));
513
+ }
514
+ /**
515
+ * Fold the live target's {@link BOOKKEEPING_FRONTMATTER_KEYS} into
516
+ * `proposedRaw` wherever the proposal's own frontmatter does not already set
517
+ * them, so promoting a proposal minted before a bookkeeping rewrite never
518
+ * drops that bookkeeping (STALE, R20) — e.g. dropping `inferenceProcessed`
519
+ * would make memory inference reprocess the memory.
520
+ *
521
+ * Returns `proposedRaw` unchanged when either side has no parseable
522
+ * frontmatter block or nothing needs to carry forward.
523
+ */
524
+ export function carryForwardBookkeepingFrontmatter(proposedRaw, liveRaw) {
525
+ const proposedBlock = parseFrontmatterBlock(proposedRaw);
526
+ const liveBlock = parseFrontmatterBlock(liveRaw);
527
+ if (!proposedBlock || !liveBlock)
528
+ return proposedRaw;
529
+ let proposedData;
530
+ let liveData;
531
+ try {
532
+ const parsedProposed = proposedBlock.frontmatter.trim() ? yamlParse(proposedBlock.frontmatter) : {};
533
+ const parsedLive = liveBlock.frontmatter.trim() ? yamlParse(liveBlock.frontmatter) : {};
534
+ if (parsedProposed === null || typeof parsedProposed !== "object" || Array.isArray(parsedProposed)) {
535
+ return proposedRaw;
536
+ }
537
+ if (parsedLive === null || typeof parsedLive !== "object" || Array.isArray(parsedLive))
538
+ return proposedRaw;
539
+ proposedData = parsedProposed;
540
+ liveData = parsedLive;
541
+ }
542
+ catch {
543
+ return proposedRaw;
544
+ }
545
+ const merged = { ...proposedData };
546
+ let changed = false;
547
+ for (const key of BOOKKEEPING_FRONTMATTER_KEYS) {
548
+ if (!(key in merged) && key in liveData) {
549
+ merged[key] = liveData[key];
550
+ changed = true;
551
+ }
552
+ }
553
+ if (!changed)
554
+ return proposedRaw;
555
+ const newFrontmatter = yamlStringify(merged).trimEnd();
556
+ const separator = proposedBlock.content.startsWith("\n") ? "" : "\n";
557
+ return `---\n${newFrontmatter}\n---\n${separator}${proposedBlock.content}`;
558
+ }
454
559
  // ── Minimum score delta to trigger a frontmatter salience rewrite ─────────────
455
560
  const SALIENCE_WRITE_DELTA_THRESHOLD = 0.05;
456
561
  /**
@@ -89,7 +89,7 @@ function notFound(conceptId, triedForms, ctx) {
89
89
  *
90
90
  * Exported (Chunk-8 WI-8.5c) as the ONE conceptId derivation the improve
91
91
  * correlation sites (`eligibility.ts` candidate refs, `salience.ts`
92
- * last-use lookup, `collapse-detector.ts` canary mint/score) share with the
92
+ * last-use lookup) share with the
93
93
  * display rule — the permanent successor to the retired transient
94
94
  * `legacyConceptId`.
95
95
  */
@@ -4,18 +4,55 @@
4
4
  import crypto from "node:crypto";
5
5
  import path from "node:path";
6
6
  import { isBundleSlug } from "./asset/asset-ref.js";
7
+ import { UsageError } from "./errors.js";
7
8
  /** Deterministic, filesystem-safe bundle slug from a source path. */
8
9
  export function slugForPath(sourcePath) {
9
10
  const resolved = path.resolve(sourcePath);
10
- const base = path
11
- .basename(resolved)
12
- .toLowerCase()
13
- .replace(/[^a-z0-9]+/g, "-")
14
- .replace(/^-+|-+$/g, "");
11
+ const base = slugify(path.basename(resolved));
15
12
  if (base.length > 0)
16
13
  return base;
17
14
  return `bundle-${shortHash(resolved)}`;
18
15
  }
16
+ /**
17
+ * Bundle slug from the package/repo name a registry install id names
18
+ * (`npm:@scope/pkg` → `pkg`, `github:owner/repo` → `repo`,
19
+ * `git:https://host/owner/repo` → `repo`); empty when it names none.
20
+ */
21
+ export function slugForRegistryId(registryId) {
22
+ const locator = registryId.slice(registryId.indexOf(":") + 1);
23
+ return slugify(locator.split(/[/:]/).filter(Boolean).pop() ?? "");
24
+ }
25
+ function slugify(name) {
26
+ return name
27
+ .toLowerCase()
28
+ .replace(/[^a-z0-9]+/g, "-")
29
+ .replace(/^-+|-+$/g, "");
30
+ }
31
+ /**
32
+ * Enforce the `--name` contract on every add path (D6): an explicit name is
33
+ * not a silent hint that may fall back to a derived id — it is a request
34
+ * that either succeeds exactly or fails loudly, before anything is written.
35
+ *
36
+ * `existingKeyForThisInstall` is the bundle key this exact source (path/URL/
37
+ * registry id) is already configured under, if any. Re-adding that same
38
+ * source under a *different* explicit name is rejected in favor of
39
+ * `akm bundle rename`, which is the one command allowed to change a bundle's
40
+ * key. A caller with no existing install for this source (the common case)
41
+ * omits it.
42
+ */
43
+ export function validateExplicitBundleName(bundles, name, existingKeyForThisInstall) {
44
+ if (!isBundleSlug(name)) {
45
+ throw new UsageError(`"${name}" is not a legal bundle name: it must not contain whitespace or the characters ":" "." "#" "/".`, "INVALID_FLAG_VALUE");
46
+ }
47
+ if (existingKeyForThisInstall !== undefined && name !== existingKeyForThisInstall) {
48
+ throw new UsageError(`This source is already installed as bundle "${existingKeyForThisInstall}". Re-adding it under a ` +
49
+ `different name is not supported — run \`akm bundle rename ${existingKeyForThisInstall} ${name}\` instead.`, "INVALID_FLAG_VALUE");
50
+ }
51
+ if (Object.hasOwn(bundles, name) && name !== existingKeyForThisInstall) {
52
+ throw new UsageError(`Bundle name "${name}" already exists. Choose another name, or run ` +
53
+ `\`akm bundle rename ${name} <new-name>\` first.`, "INVALID_FLAG_VALUE");
54
+ }
55
+ }
19
56
  /** Derive one batch-unique bundle id. */
20
57
  export function deriveBundleId(registryId, sourcePath, usedIds) {
21
58
  const preferred = registryId && registryId.length > 0 && isBundleSlug(registryId) ? registryId : slugForPath(sourcePath);
@@ -0,0 +1,285 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * `akm bundle rename <old> <new>` (D6) — the one command allowed to change a
6
+ * bundle's key. A bundle id is a mass identity prefix: every durable ref this
7
+ * tool minted (`entries.item_ref`/`bundle_id`, `proposals.ref`, a pending
8
+ * proposal's `proposedTarget.source`, a workflow task_history row's
9
+ * `target_ref`, `scheduler.enabled[].ref`) carries it, and a hand-edited
10
+ * `bundles` key strands all of it (see `src/indexer/bundle-identity-guard.ts`
11
+ * §11.5). This module is the rekey transaction that guard's docstring points
12
+ * to.
13
+ *
14
+ * Rewritten: the config `bundles` key, `defaultBundle`/`defaultWriteTarget`
15
+ * when they name the old id, every `scheduler.enabled[].ref` with the old
16
+ * `//` prefix, the lockfile entry id, and the index/state rows above.
17
+ *
18
+ * Reported, never rewritten: refs inside bundle CONTENT (xrefs,
19
+ * `supersededBy`, task `uses:`) — rewriting a bundle's own files is
20
+ * `akm mv`/editing territory, not a config-identity rename. `--dry-run`
21
+ * (and every real run) lists the indexed files that still spell the old
22
+ * `<old>//` prefix so the operator can follow up.
23
+ *
24
+ * Left behind on purpose: `usage_events`/`asset_salience`/`asset_outcome`
25
+ * keyed by the old bundle prefix (learned utility/outcome history) — outside
26
+ * this item's scope; `warnOnBundleRenameDrift` already documents this class
27
+ * of gap and `akm index --full` re-mints under the new id.
28
+ */
29
+ import fs from "node:fs";
30
+ import { readLockfile, renameLockEntry } from "../integrations/lockfile.js";
31
+ import { closeDatabase, openIndexDatabase, openReadonlyExistingDatabase, } from "../storage/repositories/index-connection.js";
32
+ import { getFilePathsByBundle, renameEntriesBundleId } from "../storage/repositories/index-entries-repository.js";
33
+ import { countProposalsForBundleRename, renameProposalsBundleRef } from "../storage/repositories/proposals-repository.js";
34
+ import { countTaskHistoryTargetRefs, renameTaskHistoryTargetRefs, } from "../storage/repositories/task-history-repository.js";
35
+ import { selectBackend } from "../tasks/backends/index.js";
36
+ import { bundleRefToString, parseBundleRef } from "./asset/asset-ref.js";
37
+ import { validateExplicitBundleName } from "./bundle-id.js";
38
+ import { loadConfig, mutateConfig } from "./config/config.js";
39
+ import { NotFoundError, UsageError } from "./errors.js";
40
+ import { getDbPath } from "./paths.js";
41
+ import { getStateDbPath, withStateDb } from "./state-db.js";
42
+ /** Throws if `newId` cannot become `oldId`'s new key. Re-run under the config lock at apply time. */
43
+ function validateRename(config, oldId, newId) {
44
+ if (!config.bundles?.[oldId]) {
45
+ throw new NotFoundError(`No configured bundle named "${oldId}".`, "SOURCE_NOT_FOUND");
46
+ }
47
+ if (oldId === newId) {
48
+ throw new UsageError(`"${oldId}" and "${newId}" are the same bundle name.`, "INVALID_FLAG_VALUE");
49
+ }
50
+ const withoutOld = { ...(config.bundles ?? {}) };
51
+ delete withoutOld[oldId];
52
+ validateExplicitBundleName(withoutOld, newId);
53
+ }
54
+ function bundleOfRef(ref) {
55
+ try {
56
+ return parseBundleRef(ref).bundle;
57
+ }
58
+ catch {
59
+ return undefined;
60
+ }
61
+ }
62
+ function schedulerRefsToRewrite(config, oldId) {
63
+ return (config.scheduler?.enabled ?? []).filter((ref) => bundleOfRef(ref) === oldId);
64
+ }
65
+ function renameBundleInConfig(config, oldId, newId) {
66
+ validateRename(config, oldId, newId);
67
+ const bundles = {};
68
+ for (const [key, entry] of Object.entries(config.bundles ?? {})) {
69
+ bundles[key === oldId ? newId : key] = entry;
70
+ }
71
+ const enabled = config.scheduler?.enabled;
72
+ const scheduler = enabled === undefined
73
+ ? config.scheduler
74
+ : {
75
+ ...config.scheduler,
76
+ enabled: enabled.map((ref) => bundleOfRef(ref) === oldId ? bundleRefToString({ ...parseBundleRef(ref), bundle: newId }) : ref),
77
+ };
78
+ return {
79
+ ...config,
80
+ bundles,
81
+ ...(config.defaultBundle === oldId ? { defaultBundle: newId } : {}),
82
+ ...(config.defaultWriteTarget === oldId ? { defaultWriteTarget: newId } : {}),
83
+ ...(scheduler ? { scheduler } : {}),
84
+ };
85
+ }
86
+ /** Indexed files (already read into `filePaths`) whose content still spells `<oldId>//`, best-effort. */
87
+ function filesStillMentioning(filePaths, oldId) {
88
+ const needle = `${oldId}//`;
89
+ const hits = [];
90
+ for (const filePath of filePaths) {
91
+ try {
92
+ if (fs.readFileSync(filePath, "utf8").includes(needle))
93
+ hits.push(filePath);
94
+ }
95
+ catch {
96
+ // Best-effort: a since-removed or unreadable file is skipped, not fatal —
97
+ // this scan is a report, not a correctness requirement.
98
+ }
99
+ }
100
+ return hits;
101
+ }
102
+ /** True when an installed binding's invocation names `bundleId` — either as a `task run` entry's `--bundle <id>` argument, or as a `workflow run <id>//…` ref. */
103
+ function invocationNamesBundle(invocation, bundleId) {
104
+ if (!invocation)
105
+ return false;
106
+ for (let i = 0; i < invocation.length; i++) {
107
+ const token = invocation[i];
108
+ if (token === bundleId && invocation[i - 1] === "--bundle")
109
+ return true;
110
+ if (token?.startsWith(`${bundleId}//`))
111
+ return true;
112
+ }
113
+ return false;
114
+ }
115
+ /**
116
+ * Installed native scheduler rows whose invocation names `oldId`, best-effort
117
+ * (a backend whose listing throws reports none — this is a preview, not a
118
+ * correctness requirement).
119
+ */
120
+ async function nativeSchedulerRowsNamingBundle(sched, oldId) {
121
+ try {
122
+ return (await sched.list())
123
+ .filter((entry) => invocationNamesBundle(entry.invocation, oldId))
124
+ .map((entry) => entry.invocation?.join(" ") ?? entry.id);
125
+ }
126
+ catch {
127
+ return [];
128
+ }
129
+ }
130
+ /**
131
+ * Build the rename plan — every count and ref this rename would touch — by
132
+ * reading, never writing. Shared by `--dry-run` and a real run so the two
133
+ * can never disagree about what was reported vs. what happened.
134
+ */
135
+ async function buildPlan(config, oldId, newId, sched) {
136
+ const schedulerRefs = schedulerRefsToRewrite(config, oldId);
137
+ const lockPresent = readLockfile().some((entry) => entry.id === oldId);
138
+ const nativeSchedulerRows = await nativeSchedulerRowsNamingBundle(sched, oldId);
139
+ let indexEntries = 0;
140
+ let contentRefs = [];
141
+ const readIndexDb = openReadonlyExistingDatabase(getDbPath());
142
+ if (readIndexDb) {
143
+ try {
144
+ const filePaths = getFilePathsByBundle(readIndexDb, oldId);
145
+ indexEntries = filePaths.length;
146
+ contentRefs = filesStillMentioning(filePaths, oldId);
147
+ }
148
+ finally {
149
+ closeDatabase(readIndexDb);
150
+ }
151
+ }
152
+ let proposalRefs = 0;
153
+ let proposalTargets = 0;
154
+ let taskHistoryRefs = 0;
155
+ if (fs.existsSync(getStateDbPath())) {
156
+ withStateDb((db) => {
157
+ const counts = countProposalsForBundleRename(db, oldId);
158
+ proposalRefs = counts.refs;
159
+ proposalTargets = counts.targets;
160
+ taskHistoryRefs = countTaskHistoryTargetRefs(db, oldId);
161
+ });
162
+ }
163
+ return {
164
+ oldId,
165
+ newId,
166
+ config: {
167
+ defaultBundleChanges: config.defaultBundle === oldId,
168
+ defaultWriteTargetChanges: config.defaultWriteTarget === oldId,
169
+ schedulerRefs,
170
+ },
171
+ lock: { present: lockPresent },
172
+ index: { entries: indexEntries },
173
+ state: { proposalRefs, proposalTargets, taskHistoryRefs },
174
+ contentRefs,
175
+ nativeSchedulerRows,
176
+ };
177
+ }
178
+ function taskSyncErrorMessage(cause) {
179
+ return cause instanceof Error ? cause.message : String(cause);
180
+ }
181
+ /**
182
+ * Remove every installed native row still naming `oldId`, best-effort,
183
+ * before the sync below installs the new-named ones. Without this, a plain
184
+ * `akmTasksSync(deps, newId)` alone cannot clean the old rows up: a task
185
+ * binding's native id depends only on the task id, so the OLD row and the
186
+ * new one it should become collide on that id, and `installedRowScope`
187
+ * (scheduler-sync.ts) attributes a row by the bundle NAME it was installed
188
+ * under — the physical-path check only confirms a name match, it never
189
+ * substitutes for one — so the sync reports the old row as another bundle's
190
+ * and leaves the new binding out instead of replacing it. A workflow binding's native id
191
+ * depends on its fully-qualified ref instead, so old and new never collide
192
+ * at all and the old row would otherwise be left installed forever. Both
193
+ * fail the same way this function fixes: uninstall the exact native rows
194
+ * `nativeSchedulerRowsNamingBundle` already found, by their native id, so
195
+ * the sync that follows starts from a clean slate.
196
+ */
197
+ async function removeStaleNativeSchedulerRows(sched, oldId) {
198
+ let installed;
199
+ try {
200
+ installed = await sched.list();
201
+ }
202
+ catch {
203
+ return;
204
+ }
205
+ for (const entry of installed) {
206
+ if (!invocationNamesBundle(entry.invocation, oldId))
207
+ continue;
208
+ try {
209
+ await sched.uninstall(entry.nativeId ?? entry.id);
210
+ }
211
+ catch {
212
+ // Best-effort: a row this process can't remove is left for the
213
+ // operator's own `akm task sync` to reconcile, same as every other
214
+ // per-item failure the sync itself reports rather than throws.
215
+ }
216
+ }
217
+ }
218
+ /**
219
+ * Rename a configured bundle's key everywhere akm itself persists it. With
220
+ * `dryRun: true`, only {@link buildPlan} runs — nothing is written, matching
221
+ * a `applied: false` result the caller renders as the plan. `deps.backend`
222
+ * lets a caller (tests) inject a fake scheduler backend instead of the real
223
+ * OS one `selectBackend()` would otherwise pick. `deps.syncTasks` is how the
224
+ * caller runs the post-rename `akmTasksSync` — `src/core` sits below
225
+ * `src/commands` (see `src/core/improve-types.ts`'s note on the same
226
+ * direction), so this module never imports `akmTasksSync` itself; the real
227
+ * caller (`akm bundle rename`'s command handler) always supplies it, and is
228
+ * required so a missing wire-up is a type error, not a silently skipped sync.
229
+ */
230
+ export async function renameBundle(oldId, newId, options = {}, deps) {
231
+ const config = loadConfig();
232
+ validateRename(config, oldId, newId);
233
+ const sched = deps.backend ?? selectBackend();
234
+ const plan = await buildPlan(config, oldId, newId, sched);
235
+ if (options.dryRun)
236
+ return { ...plan, applied: false };
237
+ // Config: the bundles key, defaultBundle/defaultWriteTarget, and every
238
+ // scheduler.enabled[].ref with the old `//` prefix — all under one write
239
+ // (validated again inside the config lock).
240
+ mutateConfig((current) => renameBundleInConfig(current, oldId, newId));
241
+ // Lockfile: the resolved-install entry id (no-op for a bundle with none,
242
+ // e.g. a plain filesystem bundle).
243
+ await renameLockEntry(oldId, newId);
244
+ // Index: bundle_id/item_ref on every entry row (see index-entries-repository's
245
+ // renameEntriesBundleId docstring for why no FTS/vector rebuild is needed).
246
+ const readIndexDb = openReadonlyExistingDatabase(getDbPath());
247
+ if (readIndexDb) {
248
+ closeDatabase(readIndexDb);
249
+ const writeIndexDb = openIndexDatabase(getDbPath());
250
+ try {
251
+ renameEntriesBundleId(writeIndexDb, oldId, newId);
252
+ }
253
+ finally {
254
+ closeDatabase(writeIndexDb);
255
+ }
256
+ }
257
+ // State: proposals.ref, a pending proposal's proposedTarget.source, and
258
+ // workflow task_history.target_ref.
259
+ if (fs.existsSync(getStateDbPath())) {
260
+ withStateDb((db) => {
261
+ renameProposalsBundleRef(db, oldId, newId);
262
+ renameTaskHistoryTargetRefs(db, oldId, newId);
263
+ });
264
+ }
265
+ // Scheduler: remove native rows still naming `<old>//` (see
266
+ // removeStaleNativeSchedulerRows for why a plain sync alone can't do
267
+ // this), then re-sync so a scheduled run's invocation stops naming the
268
+ // old bundle the moment the rename applies, instead of waiting on the
269
+ // operator to run `akm task sync` by hand. Reported, never thrown:
270
+ // config/index/state above are already renamed by this point, so a sync
271
+ // problem must not make the rename itself look like it failed. `ok` is
272
+ // false both when the sync call throws and when it comes back with
273
+ // `result.failures` — a binding that failed to prepare has already lost
274
+ // its old native row above and is not scheduled until a retry.
275
+ let taskSync;
276
+ try {
277
+ await removeStaleNativeSchedulerRows(sched, oldId);
278
+ const result = await deps.syncTasks(newId, sched);
279
+ taskSync = { ok: result.failures.length === 0, result };
280
+ }
281
+ catch (cause) {
282
+ taskSync = { ok: false, error: taskSyncErrorMessage(cause) };
283
+ }
284
+ return { ...plan, applied: true, taskSync };
285
+ }
@@ -124,8 +124,7 @@ function isTimestampedConfigBackup(name) {
124
124
  * Keep the `keep` most-recently-modified entries of `dir` that `select`
125
125
  * admits and remove the rest. Best-effort: an unreadable dir is a no-op, an
126
126
  * unreadable entry sorts oldest (pruned first), and a failed removal is
127
- * retried by the next call. Shared by the config backups above and the task
128
- * migration snapshots (#897).
127
+ * retried by the next call.
129
128
  */
130
129
  export function pruneToNewest(dir, keep, select) {
131
130
  let entries;
@@ -39,8 +39,6 @@
39
39
  * enforced at save time via `superRefine` on the top-level schema.
40
40
  */
41
41
  import { z } from "zod";
42
- import { bundleRefToString, parseBundleRef } from "../asset/asset-ref.js";
43
- import { warnOnce } from "../warn.js";
44
42
  import { BUILTIN_IMPROVE_STRATEGY_NAMES, IMPROVE_PROCESS_ENGINE_CAPABILITIES } from "./engine-semantics.js";
45
43
  import { EmbeddingConnectionConfigSchema } from "./schema/embedding.js";
46
44
  import { EnginesSchema } from "./schema/engines.js";
@@ -62,11 +60,11 @@ export { EngineConfigSchema, EnginesSchema, LlmConnectionConfigSchema, LlmProfil
62
60
  export { ExperimentalConfigSchema } from "./schema/experimental.js";
63
61
  export { FEEDBACK_FAILURE_MODES, FeedbackConfigSchema } from "./schema/feedback.js";
64
62
  export { ImproveConfigSchema } from "./schema/improve.js";
65
- export { ConsolidateProcessConfigSchema, DistillProcessConfigSchema, ExtractProcessConfigSchema, GraphExtractionProcessConfigSchema, ImproveProcessConfigSchema, ImproveProfileConfigSchema, MemoryInferenceProcessConfigSchema, ProactiveMaintenanceProcessConfigSchema, ReflectProcessConfigSchema, TriageProcessConfigSchema, ValidationProcessConfigSchema, } from "./schema/improve-processes.js";
63
+ export { ConsolidateProcessConfigSchema, DistillProcessConfigSchema, ExtractProcessConfigSchema, ImproveProcessConfigSchema, ImproveProfileConfigSchema, MemoryInferenceProcessConfigSchema, ProactiveMaintenanceProcessConfigSchema, ReflectProcessConfigSchema, TriageProcessConfigSchema, ValidationProcessConfigSchema, } from "./schema/improve-processes.js";
66
64
  export { IndexConfigSchema, IndexPassConfigSchema } from "./schema/index-config.js";
67
65
  export { OutputConfigSchema } from "./schema/output.js";
68
66
  export { CURRENT_CONFIG_VERSION, LlmInvocationOverridesSchema } from "./schema/primitives.js";
69
- export { SchedulerActivationSchema, SchedulerConfigSchema } from "./schema/scheduler.js";
67
+ export { SchedulerConfigSchema } from "./schema/scheduler.js";
70
68
  export { SearchConfigSchema } from "./schema/search.js";
71
69
  export { SetupConfigSchema } from "./schema/setup.js";
72
70
  export { BundleConfigEntrySchema, BundlesConfigSchema, RegistryConfigEntrySchema, SourceConfigEntrySchema, } from "./schema/sources-bundles.js";
@@ -143,11 +141,6 @@ const RETIRED_SOURCE_SHAPE_KEY_MESSAGES = {
143
141
  };
144
142
  export const AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) => {
145
143
  const raw = config;
146
- for (const key of ["profiles", "llm", "agent", "features", "stashes", "modelAliases", "bindings", "writable"]) {
147
- if (key in raw) {
148
- warnOnce(`config:retired-key:${key}`, `Config key "${key}" is retired in 0.9 and is ignored; configure engines/improve.strategies/bundles.<id> instead.`);
149
- }
150
- }
151
144
  // Only the current source shape enters the runtime. There is no config
152
145
  // compatibility path; `bundles` + `defaultBundle` fully supersede these keys.
153
146
  for (const key of ["stashDir", "sources", "installed"]) {
@@ -200,31 +193,6 @@ export const AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) =>
200
193
  });
201
194
  }
202
195
  }
203
- const activationKeys = new Set();
204
- for (const [index, activation] of (config.scheduler?.enabled ?? []).entries()) {
205
- try {
206
- const parsed = parseBundleRef(activation.ref);
207
- if (!parsed.bundle || parsed.fragment !== undefined || bundleRefToString(parsed) !== activation.ref) {
208
- throw new Error("not canonical");
209
- }
210
- const key = `${activation.kind}\0${activation.ref}`;
211
- if (activationKeys.has(key)) {
212
- ctx.addIssue({
213
- code: z.ZodIssueCode.custom,
214
- path: ["scheduler", "enabled", index],
215
- message: "duplicates an earlier scheduler activation",
216
- });
217
- }
218
- activationKeys.add(key);
219
- }
220
- catch {
221
- ctx.addIssue({
222
- code: z.ZodIssueCode.custom,
223
- path: ["scheduler", "enabled", index, "ref"],
224
- message: "must be one canonical fully-qualified ref without a fragment",
225
- });
226
- }
227
- }
228
196
  for (const key of ["llm", "agent", "improve"]) {
229
197
  if (config.defaults && key in config.defaults) {
230
198
  ctx.addIssue({
@@ -272,6 +240,13 @@ export const AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) =>
272
240
  }
273
241
  const defaultStrategy = config.defaults?.improveStrategy;
274
242
  if (defaultStrategy &&
243
+ // graph-refresh is exempt from this eager, config-load-time check: unlike
244
+ // a plain typo, it is a specific, known retirement, and refusing it here
245
+ // would fail every command's config load (including `akm migrate apply`,
246
+ // the one that fixes this). `resolveImproveStrategy`
247
+ // (src/commands/improve/improve-strategies.ts) refuses it lazily, at
248
+ // improve-invocation time, with the same message either way.
249
+ defaultStrategy !== "graph-refresh" &&
275
250
  !BUILTIN_IMPROVE_STRATEGY_NAMES.includes(defaultStrategy) &&
276
251
  !config.improve?.strategies?.[defaultStrategy]) {
277
252
  ctx.addIssue({
@@ -78,7 +78,7 @@ function unwrap(schema) {
78
78
  * AkmConfig schema. Returns `undefined` if any path segment doesn't match a
79
79
  * known schema field.
80
80
  */
81
- function resolveSchemaAt(path, config, raw) {
81
+ export function resolveSchemaAt(path, config, raw) {
82
82
  let schema = AkmConfigBaseSchema;
83
83
  let existing = config;
84
84
  for (const [index, segment] of path.entries()) {