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
@@ -6,7 +6,9 @@
6
6
  *
7
7
  * Attempts to patch missing frontmatter fields (`description`, `when_to_use`)
8
8
  * on assets that failed schema validation, using a single bounded in-tree LLM
9
- * call per asset. Results are recorded as `schema_repair_invoked` events.
9
+ * call per asset. Results are recorded as `schema_repair_invoked` events; a
10
+ * queued repair's `improve_ledger` row (written with the proposal) keeps the
11
+ * same asset from being re-queued inside the ledger's revisit window.
10
12
  *
11
13
  * This module is extracted from `improve.ts` to make the repair logic
12
14
  * independently testable and to use the shared structured execution seam.
@@ -18,52 +20,30 @@ import { parseFrontmatter } from "../../core/asset/frontmatter.js";
18
20
  import { parseRefInput } from "../../core/asset/resolve-ref.js";
19
21
  import { authoringRulesForType } from "../../core/authoring-rules.js";
20
22
  import { ConfigError } from "../../core/errors.js";
21
- import { appendEvent, readEvents } from "../../core/events.js";
23
+ import { appendEvent } from "../../core/events.js";
22
24
  import { parseEmbeddedJsonResponse } from "../../core/parse.js";
23
25
  import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
24
26
  import { info } from "../../core/warn.js";
25
27
  import { resolveAssetPath } from "../../indexer/walk/path-resolver.js";
26
- import { disposeLoweredExecutionDispatchLease } from "../../integrations/agent/execution-lowering.js";
27
- import { callStructured, preflightStructuredLlmRunner } from "../../llm/structured-call.js";
28
- import { createProposal, isProposalSkipped } from "../proposal/repository.js";
29
- // ── Constants ────────────────────────────────────────────────────────────────
30
- /** Minimum gap between schema-repair attempts on the same asset. */
31
- const SCHEMA_REPAIR_COOLDOWN_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
32
- /**
33
- * Per-ref attempt cap (O-6 / #379): maximum number of schema-repair attempts
34
- * allowed within SCHEMA_REPAIR_WINDOW_MS. Prevents indefinite nightly re-repair
35
- * of assets whose source content is genuinely ambiguous or inconsistently
36
- * structured. After cap, the asset is skipped until the window rolls over.
37
- * Self-Refine arXiv:2303.17651 — iteration must be bounded.
38
- */
39
- const SCHEMA_REPAIR_MAX_ATTEMPTS = 3;
40
- const SCHEMA_REPAIR_WINDOW_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
28
+ import { assertRunnerCredentials } from "../../integrations/agent/runner-dispatch.js";
29
+ import { callStructured } from "../../llm/structured-call.js";
30
+ import { isLedgerBlocked, ledgerKey, loadLedgerSnapshot } from "../improve/ledger.js";
31
+ import { createProposal } from "../proposal/repository.js";
32
+ /** Proposal source and improve-ledger source for this pass. */
33
+ const SCHEMA_REPAIR_SOURCE = "schema-repair";
41
34
  async function classifySchemaRepairs(args) {
42
35
  const { failures, startMs, budgetMs, stashDir, findFilePath, isLessonCandidateFn, repairs } = args;
43
36
  const eligibleRepairs = [];
44
37
  const pendingErrors = [];
38
+ const ledger = loadLedgerSnapshot(undefined, stashDir, [SCHEMA_REPAIR_SOURCE]);
39
+ const nowIso = new Date().toISOString();
45
40
  for (const failure of failures) {
46
41
  if (Date.now() - startMs >= budgetMs)
47
42
  break;
48
- const recentRepairs = readEvents({ type: "schema_repair_invoked", ref: failure.ref });
49
- const lastRepair = recentRepairs.events
50
- .filter((event) => event.metadata?.outcome === "queued")
51
- .sort((a, b) => new Date(b.ts ?? 0).getTime() - new Date(a.ts ?? 0).getTime())[0];
52
- if (lastRepair?.ts && Date.now() - new Date(lastRepair.ts).getTime() < SCHEMA_REPAIR_COOLDOWN_MS) {
43
+ if (isLedgerBlocked(ledger.get(ledgerKey(SCHEMA_REPAIR_SOURCE, failure.ref)), nowIso)) {
53
44
  repairs.push({ ref: failure.ref, reason: failure.reason, outcome: "skipped" });
54
45
  continue;
55
46
  }
56
- const windowStart = Date.now() - SCHEMA_REPAIR_WINDOW_MS;
57
- const attemptsInWindow = recentRepairs.events.filter((event) => event.ts !== undefined && new Date(event.ts).getTime() >= windowStart).length;
58
- if (attemptsInWindow >= SCHEMA_REPAIR_MAX_ATTEMPTS) {
59
- repairs.push({
60
- ref: failure.ref,
61
- reason: failure.reason,
62
- outcome: "skipped",
63
- error: `schema-repair attempt cap reached (${attemptsInWindow}/${SCHEMA_REPAIR_MAX_ATTEMPTS} in 30d window)`,
64
- });
65
- continue;
66
- }
67
47
  const filePath = await findFilePath(failure.ref, stashDir);
68
48
  if (!filePath || path.extname(filePath).toLowerCase() !== ".md") {
69
49
  repairs.push({ ref: failure.ref, reason: failure.reason, outcome: "skipped" });
@@ -152,112 +132,101 @@ export async function runSchemaRepairPass(failures, options) {
152
132
  }
153
133
  return { repairs, repairedRefs };
154
134
  }
155
- const dispatchLease = await preflightStructuredLlmRunner(llmRunner);
156
- try {
157
- for (const repair of pendingErrors) {
158
- appendEvent({
159
- eventType: "schema_repair_invoked",
160
- ref: repair.ref,
161
- metadata: { outcome: "error", reason: repair.reason, error: repair.error },
135
+ assertRunnerCredentials(llmRunner);
136
+ for (const repair of pendingErrors) {
137
+ appendEvent({
138
+ eventType: "schema_repair_invoked",
139
+ ref: repair.ref,
140
+ metadata: { outcome: "error", reason: repair.reason, error: repair.error },
141
+ });
142
+ repairs.push(repair);
143
+ }
144
+ for (const { failure, frontmatter: fm, fieldList, messages } of eligibleRepairs) {
145
+ let loweringNotices = [];
146
+ const noticeFields = () => loweringNotices.length > 0 ? { notices: loweringNotices } : {};
147
+ try {
148
+ info(`[improve] schema-repair ${failure.ref} (${fieldList})`);
149
+ const llmResponse = await callStructured({
150
+ feature: "schema_repair",
151
+ runner: llmRunner,
152
+ messages,
153
+ ...(chatFn ? { request: { chat: chatFn } } : {}),
154
+ onNotices: (value) => {
155
+ loweringNotices = value;
156
+ },
157
+ parse: (rawResponse) => rawResponse ?? "",
158
+ onError: () => "",
159
+ fallback: "",
162
160
  });
163
- repairs.push(repair);
164
- }
165
- for (const { failure, frontmatter: fm, fieldList, messages } of eligibleRepairs) {
166
- let loweringNotices = [];
167
- const noticeFields = () => loweringNotices.length > 0 ? { notices: loweringNotices } : {};
168
- try {
169
- info(`[improve] schema-repair ${failure.ref} (${fieldList})`);
170
- const llmResponse = await callStructured({
171
- feature: "schema_repair",
172
- runner: llmRunner,
173
- lease: dispatchLease,
174
- messages,
175
- ...(chatFn ? { request: { chat: chatFn } } : {}),
176
- onNotices: (value) => {
177
- loweringNotices = value;
178
- },
179
- parse: (rawResponse) => rawResponse ?? "",
180
- onError: () => "",
181
- fallback: "",
182
- });
183
- const parsed = parseEmbeddedJsonResponse(llmResponse.trim());
184
- if (!parsed) {
185
- repairs.push({
186
- ref: failure.ref,
187
- reason: failure.reason,
188
- outcome: "error",
189
- error: "LLM returned unparseable JSON for schema repair",
190
- ...noticeFields(),
191
- });
192
- continue;
193
- }
194
- const newFm = { ...fm.data };
195
- if (parsed.description)
196
- newFm.description = parsed.description;
197
- if (parsed.when_to_use)
198
- newFm.when_to_use = parsed.when_to_use;
199
- const newContent = assembleAsset(newFm, fm.content);
200
- // M-3 / #387: Route through proposal queue instead of writing directly to
201
- // disk. This restores akm's safety invariant — the proposal queue is the
202
- // only path to a committed asset write. LLM-generated `description` /
203
- // `when_to_use` fields can be incorrect; routing through the queue makes
204
- // them human-reviewable before they affect search ranking and curate hints.
205
- // mem0 open gaps (arXiv:2504.19413) — any LLM write to a memory field
206
- // should be human-reviewable.
207
- const proposalResult = createProposal(stashDir, {
208
- ref: failure.ref,
209
- source: "schema-repair",
210
- // §23.6 fingerprint model-id term (WI-6.4).
211
- modelId: llmRunner.connection.model,
212
- payload: {
213
- content: newContent,
214
- ...(Object.keys(newFm).length > 0 ? { frontmatter: newFm } : {}),
215
- },
216
- });
217
- if (isProposalSkipped(proposalResult)) {
218
- info(`[improve] schema-repair proposal skipped for ${failure.ref}: ${proposalResult.message}`);
219
- repairs.push({ ref: failure.ref, reason: failure.reason, outcome: "skipped", ...noticeFields() });
220
- continue;
221
- }
222
- info(`[improve] schema-repair queued: ${failure.ref} (proposal id: ${proposalResult.id})`);
223
- appendEvent({
224
- eventType: "schema_repair_invoked",
225
- ref: failure.ref,
226
- metadata: {
227
- outcome: "queued",
228
- reason: failure.reason,
229
- proposalId: proposalResult.id,
230
- ...noticeFields(),
231
- },
232
- });
161
+ const parsed = parseEmbeddedJsonResponse(llmResponse.trim());
162
+ if (!parsed) {
233
163
  repairs.push({
234
164
  ref: failure.ref,
235
165
  reason: failure.reason,
236
- outcome: "queued",
237
- proposalId: proposalResult.id,
166
+ outcome: "error",
167
+ error: "LLM returned unparseable JSON for schema repair",
238
168
  ...noticeFields(),
239
169
  });
170
+ continue;
240
171
  }
241
- catch (e) {
242
- if (e instanceof ConfigError)
243
- throw e;
244
- appendEvent({
245
- eventType: "schema_repair_invoked",
246
- ref: failure.ref,
247
- metadata: { outcome: "error", reason: failure.reason, error: String(e), ...noticeFields() },
248
- });
249
- repairs.push({
250
- ref: failure.ref,
172
+ const newFm = { ...fm.data };
173
+ if (parsed.description)
174
+ newFm.description = parsed.description;
175
+ if (parsed.when_to_use)
176
+ newFm.when_to_use = parsed.when_to_use;
177
+ const newContent = assembleAsset(newFm, fm.content);
178
+ // M-3 / #387: Route through proposal queue instead of writing directly to
179
+ // disk. This restores akm's safety invariant — the proposal queue is the
180
+ // only path to a committed asset write. LLM-generated `description` /
181
+ // `when_to_use` fields can be incorrect; routing through the queue makes
182
+ // them human-reviewable before they affect search ranking and curate hints.
183
+ // mem0 open gaps (arXiv:2504.19413) — any LLM write to a memory field
184
+ // should be human-reviewable.
185
+ const proposalResult = createProposal(stashDir, {
186
+ ref: failure.ref,
187
+ source: SCHEMA_REPAIR_SOURCE,
188
+ // Key the ledger row by the ref this pass reads it back under.
189
+ attemptedRefs: [failure.ref],
190
+ payload: {
191
+ content: newContent,
192
+ ...(Object.keys(newFm).length > 0 ? { frontmatter: newFm } : {}),
193
+ },
194
+ });
195
+ info(`[improve] schema-repair queued: ${failure.ref} (proposal id: ${proposalResult.id})`);
196
+ appendEvent({
197
+ eventType: "schema_repair_invoked",
198
+ ref: failure.ref,
199
+ metadata: {
200
+ outcome: "queued",
251
201
  reason: failure.reason,
252
- outcome: "error",
253
- error: String(e),
202
+ proposalId: proposalResult.id,
254
203
  ...noticeFields(),
255
- });
256
- }
204
+ },
205
+ });
206
+ repairs.push({
207
+ ref: failure.ref,
208
+ reason: failure.reason,
209
+ outcome: "queued",
210
+ proposalId: proposalResult.id,
211
+ ...noticeFields(),
212
+ });
213
+ }
214
+ catch (e) {
215
+ if (e instanceof ConfigError)
216
+ throw e;
217
+ appendEvent({
218
+ eventType: "schema_repair_invoked",
219
+ ref: failure.ref,
220
+ metadata: { outcome: "error", reason: failure.reason, error: String(e), ...noticeFields() },
221
+ });
222
+ repairs.push({
223
+ ref: failure.ref,
224
+ reason: failure.reason,
225
+ outcome: "error",
226
+ error: String(e),
227
+ ...noticeFields(),
228
+ });
257
229
  }
258
- }
259
- finally {
260
- disposeLoweredExecutionDispatchLease(dispatchLease);
261
230
  }
262
231
  return { repairs, repairedRefs };
263
232
  }
@@ -5,6 +5,7 @@ import fs from "node:fs";
5
5
  import path from "node:path";
6
6
  import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
7
7
  import { isBundleSlug } from "../../core/asset/asset-ref.js";
8
+ import { slugForRegistryId, validateExplicitBundleName } from "../../core/bundle-id.js";
8
9
  import { isHttpUrl, resolveStashDir } from "../../core/common.js";
9
10
  import { bundleEntryToSourceEntry, getSources, installedSourceDescriptor, loadConfig, mutateConfig, resolveSecret, } from "../../core/config/config.js";
10
11
  import { ConfigError, UsageError } from "../../core/errors.js";
@@ -38,7 +39,7 @@ export async function akmAdd(input) {
38
39
  catch {
39
40
  // Not a local ref — fall through to registry install
40
41
  }
41
- return addRegistryStash(ref, stashDir, input.writable, input, input.credential);
42
+ return addRegistryStash(ref, stashDir, input.name, input.writable, input, input.credential);
42
43
  }
43
44
  /** Add a local directory as a filesystem bundle. */
44
45
  async function addLocalSource(ref, sourcePath, stashDir, explicitName, explicitAdapter, position = {}) {
@@ -49,6 +50,9 @@ async function addLocalSource(ref, sourcePath, stashDir, explicitName, explicitA
49
50
  mutateConfig((config) => {
50
51
  const existing = bundleKeyForPath(config, resolvedPath);
51
52
  if (existing) {
53
+ if (explicitName !== undefined) {
54
+ validateExplicitBundleName(config.bundles ?? {}, explicitName, existing);
55
+ }
52
56
  bundleKey = existing;
53
57
  const current = config.bundles?.[existing];
54
58
  if (current?.components && explicitAdapter === undefined)
@@ -62,6 +66,11 @@ async function addLocalSource(ref, sourcePath, stashDir, explicitName, explicitA
62
66
  return { ...config, bundles };
63
67
  }
64
68
  const bundles = { ...(config.bundles ?? {}) };
69
+ // D6: an explicit `--name` is a contract on this (local) add path — validated
70
+ // strictly before nextBundleKey derives a key, since that shared helper is also
71
+ // used by the out-of-scope `akm source add` (`addStash`) and stays forgiving.
72
+ if (explicitName !== undefined)
73
+ validateExplicitBundleName(bundles, explicitName);
65
74
  bundleKey = nextBundleKey(bundles, explicitName, resolvedPath);
66
75
  const entry = {
67
76
  path: resolvedPath,
@@ -75,6 +84,7 @@ async function addLocalSource(ref, sourcePath, stashDir, explicitName, explicitA
75
84
  schemaVersion: 1,
76
85
  bundleDir: stashDir,
77
86
  ref,
87
+ bundleId: bundleKey,
78
88
  sourceAdded: {
79
89
  type: "filesystem",
80
90
  path: resolvedPath,
@@ -100,10 +110,29 @@ async function addWebsiteSource(ref, stashDir, name, options, position = {}) {
100
110
  const maxPages = numberOption(options?.maxPages);
101
111
  const maxDepth = numberOption(options?.maxDepth);
102
112
  let entry;
113
+ let bundleId = "";
103
114
  mutateConfig((config) => {
104
115
  const bundles = { ...(config.bundles ?? {}) };
105
116
  const existingKey = bundleKeyForUrl(config, normalizedUrl);
106
- const key = existingKey ?? nextBundleKey(bundles, name ?? toWebsiteName(normalizedUrl), normalizedUrl);
117
+ if (existingKey && name !== undefined) {
118
+ validateExplicitBundleName(bundles, name, existingKey);
119
+ }
120
+ // An explicit `--name` is a contract (D6) — validated strictly and used
121
+ // as-is, never silently substituted. A DERIVED default (no --name) keeps
122
+ // the forgiving `deriveBundleId` fallback, so a dotted hostname or a
123
+ // URL collision still mints a usable id instead of erroring.
124
+ let key;
125
+ if (existingKey) {
126
+ key = existingKey;
127
+ }
128
+ else if (name !== undefined) {
129
+ validateExplicitBundleName(bundles, name);
130
+ key = name;
131
+ }
132
+ else {
133
+ key = deriveBundleId(toWebsiteName(normalizedUrl), normalizedUrl, new Set(Object.keys(bundles)));
134
+ }
135
+ bundleId = key;
107
136
  // Merge onto the existing descriptor rather than replacing it: re-running
108
137
  // `bundle add` for a URL that already has a bundle would otherwise drop
109
138
  // respectRobots / refresh, silently restoring default robots enforcement
@@ -140,6 +169,7 @@ async function addWebsiteSource(ref, stashDir, name, options, position = {}) {
140
169
  schemaVersion: 1,
141
170
  bundleDir: stashDir,
142
171
  ref,
172
+ bundleId,
143
173
  sourceAdded: {
144
174
  type: "website",
145
175
  url: normalizedUrl,
@@ -162,7 +192,7 @@ async function addWebsiteSource(ref, stashDir, name, options, position = {}) {
162
192
  * Install a stash from a registry (npm, github, git) by dispatching to the
163
193
  * matching syncable provider and persisting the lock entry.
164
194
  */
165
- async function addRegistryStash(ref, stashDir, writable, position = {}, credentialRef) {
195
+ async function addRegistryStash(ref, stashDir, explicitName, writable, position = {}, credentialRef) {
166
196
  const parsedRef = parseRegistryRef(ref);
167
197
  if (writable === true && parsedRef.source !== "git" && parsedRef.source !== "github") {
168
198
  throw new ConfigError("writable: true is only supported on filesystem and git sources", "INVALID_CONFIG_FILE");
@@ -172,6 +202,14 @@ async function addRegistryStash(ref, stashDir, writable, position = {}, credenti
172
202
  }
173
203
  const currentConfig = loadConfig();
174
204
  const existingBundleKey = findInstalledBundleKey(currentConfig.bundles ?? {}, parsedRef.id);
205
+ // D6: validate an explicit `--name` before any network sync or write — an
206
+ // illegal name, a name already taken by a different bundle, or re-adding
207
+ // this same install under a different name than it already carries must
208
+ // fail loudly here, not mint a `-<hash>` fallback deep inside the config
209
+ // mutation below.
210
+ if (explicitName !== undefined) {
211
+ validateExplicitBundleName(currentConfig.bundles ?? {}, explicitName, existingBundleKey);
212
+ }
175
213
  const existingBundle = existingBundleKey ? currentConfig.bundles?.[existingBundleKey] : undefined;
176
214
  const priorLock = existingBundleKey ? readLockfile().find((entry) => entry.id === existingBundleKey) : undefined;
177
215
  const existingWritable = Object.values(existingBundle?.components ?? {})[0]?.writable ?? existingBundle?.writable === true;
@@ -200,7 +238,7 @@ async function addRegistryStash(ref, stashDir, writable, position = {}, credenti
200
238
  cacheDir: synced.cacheDir,
201
239
  installedAt: synced.syncedAt,
202
240
  writable: synced.writable,
203
- }, position, credentialRef);
241
+ }, position, credentialRef, explicitName);
204
242
  // The prior materialized root (if this is a re-install) — read BEFORE the lock
205
243
  // upsert overwrites it, so a moved cache root can be cleaned afterwards.
206
244
  const priorLocalRoot = priorLock?.localRoot;
@@ -229,6 +267,8 @@ async function addRegistryStash(ref, stashDir, writable, position = {}, credenti
229
267
  schemaVersion: 1,
230
268
  bundleDir: stashDir,
231
269
  ref,
270
+ bundleId,
271
+ registryId: synced.id,
232
272
  installed: {
233
273
  id: synced.id,
234
274
  source: synced.source,
@@ -258,14 +298,15 @@ async function addRegistryStash(ref, stashDir, writable, position = {}, credenti
258
298
  * (spec §10.1 / §10.2 desired/resolved split). The bundle carries ONLY the
259
299
  * desired descriptor (git/npm locator + preserved `registryId` + `writable`);
260
300
  * the resolved cache root belongs exclusively in the lock (written by callers
261
- * via {@link upsertLockEntry} with the returned `bundleId`). Returns the config
301
+ * via {@link upsertLockEntry} with the returned `bundleId`). A new install is
302
+ * keyed by `explicitName` (the CLI's `--name`) when given. Returns the config
262
303
  * plus the derived bundle id so the caller keys its lock entry identically.
263
304
  */
264
- export function upsertInstalledRegistryEntry(entry, position = {}, credential) {
305
+ export function upsertInstalledRegistryEntry(entry, position = {}, credential, explicitName) {
265
306
  let bundleId = entry.id;
266
307
  const config = mutateConfig((current) => {
267
308
  const bundles = { ...(current.bundles ?? {}) };
268
- bundleId = resolveInstalledBundleKey(bundles, entry.id, entry.stashRoot);
309
+ bundleId = resolveInstalledBundleKey(bundles, entry.id, entry.stashRoot, explicitName);
269
310
  const existingComponents = bundles[bundleId]?.components;
270
311
  const components = existingComponents
271
312
  ? Object.fromEntries(Object.entries(existingComponents).map(([id, component]) => [
@@ -334,15 +375,24 @@ function findInstalledBundleKey(bundles, installId) {
334
375
  }
335
376
  /**
336
377
  * The stable bundle key for a registry install: reuse the existing bundle for
337
- * this install id (so re-installs keep the same key), otherwise derive a
338
- * batch-unique key via the shared {@link deriveBundleId} (D-R5), unique against
339
- * the currently-configured bundle keys.
378
+ * this install id (so re-installs keep the same key — a caller-visible name
379
+ * mismatch was already rejected upstream, by {@link validateExplicitBundleName}
380
+ * in `addRegistryStash`, before any write). Otherwise an explicit `--name`
381
+ * (D6) is a contract — validated strictly and used as-is, never silently
382
+ * substituted. Without one, a batch-unique key is derived via the shared
383
+ * {@link deriveBundleId} (D-R5) from the package/repo name the install id
384
+ * names rather than the basename of the materialized cache directory
385
+ * (`extracted`) — unique against the currently-configured bundle keys.
340
386
  */
341
- function resolveInstalledBundleKey(bundles, installId, stashRoot) {
387
+ function resolveInstalledBundleKey(bundles, installId, stashRoot, explicitName) {
342
388
  const existing = findInstalledBundleKey(bundles, installId);
343
389
  if (existing)
344
390
  return existing;
345
- return deriveBundleId(installId, path.resolve(stashRoot), new Set(Object.keys(bundles)));
391
+ if (explicitName !== undefined) {
392
+ validateExplicitBundleName(bundles, explicitName);
393
+ return explicitName;
394
+ }
395
+ return deriveBundleId(slugForRegistryId(installId), path.resolve(stashRoot), new Set(Object.keys(bundles)));
346
396
  }
347
397
  function toReadableId(resolvedPath) {
348
398
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
@@ -3,6 +3,7 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import path from "node:path";
5
5
  import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
6
+ import { validateExplicitBundleName } from "../../core/bundle-id.js";
6
7
  import { isRemoteUrl } from "../../core/common.js";
7
8
  import { bundleEntryToSourceEntry, bundlesToSourceEntries, getSources, mutateConfig } from "../../core/config/config.js";
8
9
  import { ConfigError, UsageError } from "../../core/errors.js";
@@ -51,7 +52,10 @@ export function addStash(opts) {
51
52
  const bundles = { ...(config.bundles ?? {}) };
52
53
  let key;
53
54
  if (useDescriptorPath) {
54
- if (bundleKeyForUrl(config, target)) {
55
+ const existingKey = bundleKeyForUrl(config, target);
56
+ if (name !== undefined)
57
+ validateExplicitBundleName(bundles, name, existingKey);
58
+ if (existingKey) {
55
59
  const already = targetIsUrl ? "Source URL already configured" : "Source already configured";
56
60
  result = { sources: getSources(config), added: false, message: already };
57
61
  return config;
@@ -69,7 +73,10 @@ export function addStash(opts) {
69
73
  }
70
74
  else {
71
75
  const resolvedPath = path.resolve(target);
72
- if (bundleKeyForPath(config, resolvedPath)) {
76
+ const existingKey = bundleKeyForPath(config, resolvedPath);
77
+ if (name !== undefined)
78
+ validateExplicitBundleName(bundles, name, existingKey);
79
+ if (existingKey) {
73
80
  result = { sources: getSources(config), added: false, message: "Source path already configured" };
74
81
  return config;
75
82
  }
@@ -33,6 +33,7 @@ import * as p from "../../cli/clack.js";
33
33
  import { getParsedInvocation } from "../../cli/invocation.js";
34
34
  import { defineJsonCommand, GLOBAL_OUTPUT_ARGS, output, parseAllFlagValues, runWithJsonErrors } from "../../cli/shared.js";
35
35
  import { assertFlatAssetName } from "../../core/asset/asset-create.js";
36
+ import { placementTypes } from "../../core/asset/asset-placement.js";
36
37
  import { parseFrontmatter } from "../../core/asset/frontmatter.js";
37
38
  import { isHttpUrl, resolveStashDir } from "../../core/common.js";
38
39
  import { loadConfig } from "../../core/config/config.js";
@@ -45,6 +46,7 @@ import { resolveWriteTarget } from "../../core/write-source.js";
45
46
  import { releaseIndexRebuildLock, tryAcquireIndexRebuildLock } from "../../indexer/index-rebuild-lock.js";
46
47
  import { akmIndex } from "../../indexer/indexer.js";
47
48
  import { getHyphenatedBoolean, getOutputMode } from "../../output/context.js";
49
+ import { pkgVersion } from "../../version.js";
48
50
  import { inferAssetName, mergeXrefsIntoContent, readKnowledgeInput, resolveSupersedesForWrite, resolveSupersedesWriteTarget, resolveXrefsForWrite, writeMarkdownAsset, } from "../read/knowledge.js";
49
51
  import { assembleInfo } from "./info.js";
50
52
  /** Matches the high-frequency per-committed-batch progress line (#954), excluded from non-verbose JSON-mode stderr. */
@@ -71,7 +73,7 @@ export const indexCommand = defineCommand({
71
73
  },
72
74
  reembed: {
73
75
  type: "boolean",
74
- description: "Force re-embedding of every entry, bypassing the embedding-model-rename compatibility check.",
76
+ description: "Discard every stored vector and re-embed all entries under the configured model.",
75
77
  default: false,
76
78
  },
77
79
  "skip-if-locked": {
@@ -83,10 +85,10 @@ export const indexCommand = defineCommand({
83
85
  async run({ args }) {
84
86
  await runWithJsonErrors(async () => {
85
87
  if (getHyphenatedBoolean(args, "enrich") || getParsedInvocation().getFlagValue("--enrich") !== undefined) {
86
- throw new UsageError("`akm index --enrich` has been removed. Plain `akm index` now performs metadata enrichment by default.");
88
+ throw new UsageError("`akm index --enrich` has been removed. Metadata enrichment during indexing is retired; it never runs.");
87
89
  }
88
90
  if (getHyphenatedBoolean(args, "re-enrich") || getParsedInvocation().getFlagValue("--re-enrich") !== undefined) {
89
- throw new UsageError("`akm index --re-enrich` has been removed. Re-enrichment of index-time LLM passes is not exposed in this slice.");
91
+ throw new UsageError("`akm index --re-enrich` has been removed. Metadata enrichment during indexing is retired; there is nothing to re-enrich.");
90
92
  }
91
93
  // #956: opt-in, non-blocking rebuild lock — never gates a human-typed
92
94
  // `akm index` (it only warns and contends), but a scheduled/opportunistic
@@ -181,7 +183,25 @@ export const indexCommand = defineCommand({
181
183
  export const infoCommand = defineJsonCommand({
182
184
  meta: { name: "info", description: "Show system capabilities, configuration, and index stats" },
183
185
  run() {
184
- const result = assembleInfo();
186
+ // `akm info` must behave like a help command: always exit 0 with a
187
+ // report. `assembleInfo()` already degrades what it reasonably can
188
+ // per-section; this is the final backstop for whatever it can't (e.g.
189
+ // every path resolver needs an environment variable, such as `HOME`,
190
+ // that this process genuinely does not have) — still a report, with
191
+ // whatever is cheap and safe enough to never itself throw.
192
+ let result;
193
+ try {
194
+ result = assembleInfo();
195
+ }
196
+ catch (err) {
197
+ result = {
198
+ schemaVersion: 1,
199
+ version: pkgVersion,
200
+ error: err instanceof Error ? err.message : String(err),
201
+ assetTypes: [...placementTypes()],
202
+ searchModes: ["fts"],
203
+ };
204
+ }
185
205
  output("info", result);
186
206
  },
187
207
  });
@@ -34,11 +34,10 @@
34
34
  * `with.content`, an inline `akm/command` prompt body, or a stored
35
35
  * command's own rendered content is never read, let alone printed;
36
36
  * - effective execution settings (engine/model/timeout) reuse
37
- * `prepareResolvedExecution` (`src/integrations/agent/execution-preparation.ts`)
38
- * — the SAME cascade-composition entry point `prepareCommandInvocation`
39
- * itself calls once a command/persona source is already rendered — fed a
40
- * BLANK inline placeholder command (`createInlineResolvedCommand`) and an
41
- * EMPTY command-layer values map, instead of the task's real referenced
37
+ * `resolveExecution` (`src/integrations/agent/execution.ts`) — the SAME
38
+ * resolution entry point every command/persona invocation goes through —
39
+ * fed a BLANK inline placeholder command (`createInlineResolvedCommand`)
40
+ * and an EMPTY command-layer values map, instead of the task's real referenced
42
41
  * command source. This is a deliberate, documented trade-off: a
43
42
  * referenced command's OWN frontmatter overrides (its own `engine:`/
44
43
  * `model:`, if any) do not contribute a layer here, in exchange for never
@@ -70,9 +69,8 @@
70
69
  * `suppliedInputs`). Do not paste this command's output into an untrusted
71
70
  * place on the assumption that it can never contain a credential.
72
71
  *
73
- * Field-level execution provenance is READ from `planExecutionCascade`'s own
74
- * `ResolvedExecutionPlanV1.provenance` (via `prepareResolvedExecution`) —
75
- * this module is a CONSUMER of the one common cascade resolver, never a
72
+ * Field-level execution provenance is READ from `resolveExecution`'s own
73
+ * `provenance` — this module is a CONSUMER of the one common resolver, never a
76
74
  * second resolver: it never re-derives engine/model precedence itself.
77
75
  */
78
76
  import fs from "node:fs";
@@ -83,7 +81,7 @@ import { NotFoundError } from "../../core/errors.js";
83
81
  import { applyInputDefaults, materializeInputFlags, } from "../../execution/input-contract.js";
84
82
  import { createInlineResolvedCommand } from "../../execution/resolved-request.js";
85
83
  import { resolveAdapterConceptOwner } from "../../indexer/lookup/adapter-concept-owner.js";
86
- import { prepareResolvedExecution } from "../../integrations/agent/execution-preparation.js";
84
+ import { resolveExecution } from "../../integrations/agent/execution.js";
87
85
  import { isSchedulerRefEnabled } from "../../tasks/activation-config.js";
88
86
  import { parseTaskSource } from "../../tasks/source/parse-task-source.js";
89
87
  import { projectTaskSourceV4 } from "../../tasks/source/project-v4.js";
@@ -209,10 +207,9 @@ function resolveExecutionSettings(document) {
209
207
  if (!isCommandTarget(document))
210
208
  return { provenance: {} };
211
209
  const current = currentExecutionValues(document);
212
- const prepared = prepareResolvedExecution({
210
+ const prepared = resolveExecution({
213
211
  command: createInlineResolvedCommand({ template: "", content: "" }),
214
212
  config: loadConfig(),
215
- invocationKind: "task",
216
213
  commandLayer: { id: "task-explain", values: {} },
217
214
  ...(Object.keys(current).length > 0 ? { current } : {}),
218
215
  });
@@ -225,7 +222,7 @@ function resolveExecutionSettings(document) {
225
222
  },
226
223
  ...(prepared.request.model !== undefined ? { model: prepared.request.model } : {}),
227
224
  ...(prepared.request.runtime.timeoutMs !== undefined ? { timeoutMs: prepared.request.runtime.timeoutMs } : {}),
228
- provenance: prepared.plan.provenance,
225
+ provenance: prepared.provenance,
229
226
  };
230
227
  }
231
228
  /**
@@ -272,7 +269,7 @@ export async function akmTaskExplain(ref, options = {}) {
272
269
  const materializedInputs = materializeInputFlags(inputContract, options.inputFlags ?? [], TASK_INPUT_DIAGNOSTICS);
273
270
  const defaultedInputs = applyInputDefaults(inputContract, materializedInputs);
274
271
  const document = projectTaskSourceV4(parsed.v4);
275
- const enabled = isSchedulerRefEnabled(loadConfig(), "task", makeBundleRef(bundle.source.name, taskConceptId));
272
+ const enabled = isSchedulerRefEnabled(loadConfig(), makeBundleRef(bundle.source.name, taskConceptId));
276
273
  const schedule = parsed.v4.schedule.map((entry) => ({
277
274
  ordinal: entry.ordinal,
278
275
  cron: entry.cron,