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
@@ -4,9 +4,8 @@
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
6
  import { writeFileAtomic } from "../core/common.js";
7
- import { ConfigError, rethrowIfTestIsolationError } from "../core/errors.js";
7
+ import { ConfigError, rethrowIfTestIsolationError, TransientError } from "../core/errors.js";
8
8
  import { createLockPayload, probeLock, reclaimStaleLock, releaseLock, tryAcquireLockSync } from "../core/file-lock.js";
9
- import { acquireMaintenanceBarrier } from "../core/maintenance-barrier.js";
10
9
  import { classifyPathAccess, describeInaccessiblePath } from "../core/path-access.js";
11
10
  import { getDataDir, getLockfileLockPath, getLockfilePath } from "../core/paths.js";
12
11
  import { warn } from "../core/warn.js";
@@ -27,23 +26,18 @@ async function acquireLockSentinel() {
27
26
  let delayMs = LOCK_RETRY_INITIAL_DELAY_MS;
28
27
  let announced = false;
29
28
  for (;;) {
30
- const releaseBarrier = acquireMaintenanceBarrier();
31
- try {
32
- const ownership = tryAcquireLockSync(sentinelPath, createLockPayload());
33
- if (ownership) {
34
- return () => releaseLock(ownership);
35
- }
36
- const probe = probeLock(sentinelPath);
37
- if (probe.state === "stale" && reclaimStaleLock(sentinelPath, probe)) {
38
- continue; // Reclaimed — retry immediately.
39
- }
29
+ const ownership = tryAcquireLockSync(sentinelPath, createLockPayload());
30
+ if (ownership) {
31
+ return () => releaseLock(ownership);
40
32
  }
41
- finally {
42
- releaseBarrier();
33
+ const probe = probeLock(sentinelPath);
34
+ if (probe.state === "stale" && reclaimStaleLock(sentinelPath, probe)) {
35
+ continue; // Reclaimed — retry immediately.
43
36
  }
44
- // Another process holds the lock.
37
+ // Another process holds the lock: ordinary contention, exit 75, not a
38
+ // config error a supervisor should stop retrying on.
45
39
  if (Date.now() >= deadline) {
46
- throw new ConfigError(`Could not acquire lockfile sentinel at ${sentinelPath} after ${(timeoutMs / 1000).toFixed(1)}s; refusing to write without exclusive ownership.`, "INVALID_CONFIG_FILE");
40
+ throw new TransientError(`Could not acquire lockfile sentinel at ${sentinelPath} after ${(timeoutMs / 1000).toFixed(1)}s; refusing to write without exclusive ownership.`, "LOCKFILE_CONTENDED");
47
41
  }
48
42
  if (!announced) {
49
43
  announced = true;
@@ -93,37 +87,33 @@ function assertLockfilePathReadable(target) {
93
87
  "records, and writing over them would destroy every bundle they track. Fix the ownership or mode of that " +
94
88
  "path (or point AKM_DATA_DIR / XDG_DATA_HOME somewhere this user owns) and retry.", "DATA_DIR_UNREADABLE");
95
89
  }
96
- function readLockfileSnapshotOrThrow() {
90
+ /**
91
+ * Like {@link readLockfile}, but THROWS instead of silently degrading to `[]`
92
+ * when the on-disk lockfile exists yet cannot be read or parsed (R-012, #791).
93
+ *
94
+ * `readLockfile`'s fail-open contract is intentional for READ paths — a
95
+ * corrupt lock degrades a managed bundle to "unmanaged" rather than erroring
96
+ * every read-only command. But every writer below reads the current entries
97
+ * and writes the whole array back; if that read silently returned `[]` for a
98
+ * corrupt or unreadable file, the write would replace it with only the one
99
+ * entry being changed — permanently destroying every other lock record (a
100
+ * corrupt lockfile once wiped every entry this way). A missing file is NOT
101
+ * corruption: there is nothing to preserve, so that case returns `[]`.
102
+ */
103
+ function readLockfileOrThrow() {
97
104
  const lockfilePath = getLockfilePath();
98
- let fd;
99
105
  let raw;
100
- let mode;
101
106
  try {
102
- // One descriptor owns both byte and metadata observation so a rename or
103
- // chmod between separate path-based calls cannot synthesize a generation
104
- // that never existed on disk.
105
- fd = fs.openSync(lockfilePath, "r");
106
- raw = fs.readFileSync(fd, "utf8");
107
- mode = fs.fstatSync(fd).mode & 0o777;
107
+ raw = fs.readFileSync(lockfilePath, "utf8");
108
108
  }
109
109
  catch (err) {
110
110
  rethrowIfTestIsolationError(err);
111
- if (err.code === "ENOENT") {
112
- return { entries: [], raw: null, mode: 0o600 };
113
- }
114
- // "Missing file" is the only failure with nothing to preserve. An
115
- // UNREADABLE lockfile has everything to preserve and we cannot see it —
116
- // degrading it to `[]` here is precisely the destructive overwrite this
117
- // function was written to prevent, only triggered by a permission fault
118
- // instead of a corrupt file (#791). Classify AFTER the failed read so the
119
- // happy path costs no extra syscall and the answer describes the failure
120
- // we actually got.
111
+ if (err.code === "ENOENT")
112
+ return [];
113
+ // An UNREADABLE lockfile has everything to preserve and we cannot see it.
114
+ // Classify AFTER the failed read so the happy path costs no extra syscall.
121
115
  assertLockfilePathReadable(lockfilePath);
122
- return { entries: [], raw: null, mode: 0o600 };
123
- }
124
- finally {
125
- if (fd !== undefined)
126
- fs.closeSync(fd);
116
+ return [];
127
117
  }
128
118
  let parsed;
129
119
  try {
@@ -145,23 +135,7 @@ function readLockfileSnapshotOrThrow() {
145
135
  throw new ConfigError(`Refusing to modify lockfile ${lockfilePath}: ${invalid.length} existing entr${invalid.length === 1 ? "y is" : "ies are"} malformed. ` +
146
136
  "Fix or remove the file by hand before retrying — those entries would otherwise be lost.", "INVALID_CONFIG_FILE");
147
137
  }
148
- return {
149
- entries: parsed.filter(isValidLockfileEntry),
150
- raw,
151
- mode,
152
- };
153
- }
154
- function readLockfileOrThrow() {
155
- return readLockfileSnapshotOrThrow().entries;
156
- }
157
- /**
158
- * Read the exact lock generation that a source-lifecycle transaction may
159
- * replace. Unlike {@link readLockfile}, this refuses corrupt, malformed, or
160
- * unreadable state so an update can never treat state it could not snapshot as
161
- * an empty generation.
162
- */
163
- export function readLockfileForUpdate() {
164
- return readLockfileSnapshotOrThrow();
138
+ return parsed;
165
139
  }
166
140
  /**
167
141
  * The materialized content root recorded in the lock for a managed (git/npm)
@@ -201,66 +175,44 @@ export async function writeLockfile(entries) {
201
175
  release();
202
176
  }
203
177
  }
204
- /**
205
- * Publish an update from one exact raw + parsed lockfile generation and return
206
- * the exact bytes that were written. Formatting-only concurrent edits are a
207
- * generation change here: rollback must never overwrite bytes it did not
208
- * publish merely because they parse to an equivalent array.
209
- */
210
- export async function publishLockfileUpdate(expected, desired) {
178
+ export async function upsertLockEntry(entry) {
211
179
  const release = await acquireLockSentinel();
212
180
  try {
213
- const current = readLockfileSnapshotOrThrow();
214
- if (JSON.stringify(current.entries) !== JSON.stringify(expected.entries) ||
215
- current.raw !== expected.raw ||
216
- current.mode !== expected.mode) {
217
- return null;
218
- }
219
- writeLockfileUnlocked(desired);
220
- return readLockfileSnapshotOrThrow();
181
+ // R-012: readLockfileOrThrow (not readLockfile) — a corrupt/malformed
182
+ // lockfile must abort the upsert loudly rather than read as `[]` and get
183
+ // silently overwritten with just this one entry.
184
+ const entries = readLockfileOrThrow();
185
+ const withoutExisting = entries.filter((e) => e.id !== entry.id);
186
+ writeLockfileUnlocked([...withoutExisting, entry]);
221
187
  }
222
188
  finally {
223
189
  release();
224
190
  }
225
191
  }
226
- /** Restore an exact raw snapshot after verifying the exact generation we published. */
227
- export async function compareAndSwapLockfileSnapshot(expected, desired) {
192
+ /**
193
+ * Rename a lock entry's id in place (D6 — `akm bundle rename`), keeping every
194
+ * other resolved field (`localRoot`, `resolvedVersion`, …) unchanged. Returns
195
+ * `true` when an entry for `oldId` existed and was renamed, `false` when
196
+ * there was nothing to rename (e.g. a filesystem bundle, which has no lock
197
+ * entry).
198
+ */
199
+ export async function renameLockEntry(oldId, newId) {
228
200
  const release = await acquireLockSentinel();
229
201
  try {
230
- const current = readLockfileSnapshotOrThrow();
231
- if (JSON.stringify(current.entries) !== JSON.stringify(expected.entries) ||
232
- current.raw !== expected.raw ||
233
- current.mode !== expected.mode) {
202
+ // R-012: see upsertLockEntry — a corrupt lockfile must abort loudly
203
+ // rather than read as `[]` and get silently overwritten.
204
+ const entries = readLockfileOrThrow();
205
+ const existing = entries.find((e) => e.id === oldId);
206
+ if (!existing)
234
207
  return false;
235
- }
236
- const lockfilePath = getLockfilePath();
237
- if (desired.raw === null) {
238
- fs.rmSync(lockfilePath, { force: true });
239
- }
240
- else {
241
- fs.mkdirSync(path.dirname(lockfilePath), { recursive: true });
242
- writeFileAtomic(lockfilePath, desired.raw, desired.mode);
243
- }
208
+ const renamed = entries.map((e) => (e.id === oldId ? { ...e, id: newId } : e));
209
+ writeLockfileUnlocked(renamed);
244
210
  return true;
245
211
  }
246
212
  finally {
247
213
  release();
248
214
  }
249
215
  }
250
- export async function upsertLockEntry(entry) {
251
- const release = await acquireLockSentinel();
252
- try {
253
- // R-012: readLockfileOrThrow (not readLockfile) — a corrupt/malformed
254
- // lockfile must abort the upsert loudly rather than read as `[]` and get
255
- // silently overwritten with just this one entry.
256
- const entries = readLockfileOrThrow();
257
- const withoutExisting = entries.filter((e) => e.id !== entry.id);
258
- writeLockfileUnlocked([...withoutExisting, entry]);
259
- }
260
- finally {
261
- release();
262
- }
263
- }
264
216
  export async function removeLockEntry(id) {
265
217
  // Returning early says "there is no lock record to remove", and the uninstall
266
218
  // that called us reports success on that basis. Only an absent data dir earns
@@ -101,10 +101,9 @@ function retryBackoffMs() {
101
101
  * narrating about a document) does not get misclassified as a provider
102
102
  * context-limit error (#496).
103
103
  *
104
- * Canonical home: `graph-extract.ts` re-exports this so the index-pass
105
- * graph extractor and the retry classifier (`isRetryable`) share one
106
- * definition — retrying a context overflow cannot shrink the input, so it
107
- * must never be retried.
104
+ * Canonical home: `structured-call.ts`'s failure classifier and the retry
105
+ * classifier (`isRetryable`) here share one definition — retrying a context
106
+ * overflow cannot shrink the input, so it must never be retried.
108
107
  */
109
108
  export function isContextSizeError(message) {
110
109
  const lower = message.toLowerCase();
@@ -117,12 +116,23 @@ export function isContextSizeError(message) {
117
116
  /exceeded|over.*limit|too.*long/.test(lower);
118
117
  return evidence;
119
118
  }
119
+ /**
120
+ * Codes describing a failure to reach or get a usable response from the
121
+ * provider transport itself, as opposed to a malformed-but-received response
122
+ * (`parse_error`) or a request-shape rejection (`rate_limited`). Used by
123
+ * {@link isRetryable}, which additionally requires evidence the failure is
124
+ * transient. Not exported — its one external caller (batched LLM
125
+ * entity-graph extraction) was retired in 0.9.17-alpha.9.
126
+ */
127
+ function isTransportFailure(err) {
128
+ return err.code === "provider_error" || err.code === "network_error" || err.code === "provider_html_error";
129
+ }
120
130
  /**
121
131
  * Decide whether a first-attempt {@link LlmCallError} is eligible for a single
122
132
  * retry. Retryable: HTTP 5xx (`provider_error` with statusCode >= 500) and
123
133
  * `network_error` whose message looks like a transient connection drop.
124
- * NOT retryable: 4xx, `rate_limited` (429), `timeout`, `parse_error`, and
125
- * context-overflow-classified errors.
134
+ * NOT retryable: 4xx, `rate_limited` (429), `timeout`, `parse_error`,
135
+ * `provider_html_error`, and context-overflow-classified errors.
126
136
  *
127
137
  * The connection-drop heuristic covers the substrings emitted across runtimes
128
138
  * for a mid-flight socket close:
@@ -141,6 +151,8 @@ export function isContextSizeError(message) {
141
151
  function isRetryable(err) {
142
152
  if (isContextSizeError(err.message))
143
153
  return false;
154
+ if (!isTransportFailure(err))
155
+ return false;
144
156
  if (err.code === "provider_error") {
145
157
  return typeof err.statusCode === "number" && err.statusCode >= 500;
146
158
  }
@@ -4,9 +4,8 @@
4
4
  /** Env var that switches the whole embedding facade into deterministic mode. */
5
5
  export const DETERMINISTIC_EMBED_ENV = "AKM_EMBED_DETERMINISTIC";
6
6
  /**
7
- * Vector width. Matches the default local model (`bge-small`, 384 dims) so the
8
- * index DB's embedding column and sqlite-vec table dimensions line up without
9
- * any extra config.
7
+ * Vector width. Matches the default local model (`bge-small`, 384 dims), so a
8
+ * deterministic index is the same shape as a default local one.
10
9
  */
11
10
  export const DETERMINISTIC_EMBED_DIM = 384;
12
11
  /**
@@ -0,0 +1,71 @@
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
+ * Embedding profile: the text an embedding model expects around a query and
6
+ * around a document. Retrieval models are trained with these prompts, and
7
+ * sending raw text costs recall — Qwen3-Embedding without its query
8
+ * instruction lost 0.096 nDCG@10 on the retrieval suite.
9
+ *
10
+ * Presets are matched on the model name; `embedding.queryTemplate` and
11
+ * `embedding.documentTemplate` override them (an empty string means none).
12
+ * `{text}` marks where the text goes; a template without it is a prefix.
13
+ */
14
+ import { createHash } from "node:crypto";
15
+ import { isDeterministicEmbedEnabled } from "./deterministic.js";
16
+ import { DEFAULT_LOCAL_MODEL } from "./local.js";
17
+ const RETRIEVAL_QUERY_PREFIX = "Represent this sentence for searching relevant passages: {text}";
18
+ const PRESETS = [
19
+ {
20
+ model: /qwen3-embedding/i,
21
+ profile: {
22
+ queryTemplate: "Instruct: Given a question or task, retrieve the knowledge asset that helps with it\nQuery:{text}",
23
+ },
24
+ },
25
+ {
26
+ model: /nomic-embed/i,
27
+ profile: { queryTemplate: "search_query: {text}", documentTemplate: "search_document: {text}" },
28
+ },
29
+ {
30
+ model: /bge-(?:small|base|large)-en|mxbai-embed|arctic-embed/i,
31
+ profile: { queryTemplate: RETRIEVAL_QUERY_PREFIX },
32
+ },
33
+ {
34
+ model: /(?:^|[^a-z0-9])e5-(?:small|base|large)(?!.*instruct)/i,
35
+ profile: { queryTemplate: "query: {text}", documentTemplate: "passage: {text}" },
36
+ },
37
+ ];
38
+ /** The model a config embeds with, as the presets match it. */
39
+ function embeddingModelName(config) {
40
+ if (config?.endpoint)
41
+ return config.model ?? "";
42
+ return config?.localModel ?? DEFAULT_LOCAL_MODEL;
43
+ }
44
+ /** The configured model's templates: its preset, with each side replaced by an explicit config value. */
45
+ export function resolveEmbeddingProfile(config) {
46
+ const model = embeddingModelName(config);
47
+ const preset = isDeterministicEmbedEnabled() ? {} : (PRESETS.find((entry) => entry.model.test(model))?.profile ?? {});
48
+ const queryTemplate = config?.queryTemplate ?? preset.queryTemplate;
49
+ const documentTemplate = config?.documentTemplate ?? preset.documentTemplate;
50
+ return {
51
+ ...(queryTemplate ? { queryTemplate } : {}),
52
+ ...(documentTemplate ? { documentTemplate } : {}),
53
+ };
54
+ }
55
+ /** Put `text` into `template`; no template returns the text unchanged. */
56
+ export function applyEmbeddingTemplate(template, text) {
57
+ if (!template)
58
+ return text;
59
+ // A replacer function keeps `$&`-style sequences in the text literal.
60
+ return template.includes("{text}") ? template.replaceAll("{text}", () => text) : `${template}${text}`;
61
+ }
62
+ /**
63
+ * The document template's part of the embedding fingerprint: empty without a
64
+ * template, so vectors embedded without one stay current.
65
+ */
66
+ export function documentTemplateFingerprint(config) {
67
+ const template = resolveEmbeddingProfile(config).documentTemplate;
68
+ if (!template)
69
+ return "";
70
+ return `|doc:${createHash("sha256").update(template).digest("hex").slice(0, 12)}`;
71
+ }
@@ -187,8 +187,7 @@ export function isContextExceededResponse(status, body) {
187
187
  * Resolve the effective in-flight request window for `RemoteEmbedder.embedBatch`.
188
188
  * Default (unset `embedding.concurrency`): 1 for a loopback endpoint, 2 for a
189
189
  * remote one, via the shared `defaultConcurrencyForEndpoint`
190
- * (`src/core/loopback.ts`), the same lowest-common-denominator rule
191
- * `getDefaultLlmConcurrency` (`src/indexer/indexer.ts`) uses.
190
+ * (`src/core/loopback.ts`).
192
191
  *
193
192
  * `embedding.concurrency` (#954) overrides this default in
194
193
  * either direction, bounded 1-16 at the config schema — added after field
@@ -428,7 +427,7 @@ export class RemoteEmbedder {
428
427
  textBatches.splice(dispatchedBatchCount, textBatches.length - dispatchedBatchCount, ...replanned);
429
428
  }
430
429
  warnVerbose(`[embed] provider rejected a ${rejectedRequestTokens}-token request as over its context; request budget lowered to ${effectiveTokenBudget.toLocaleString()} for the rest of this run`);
431
- commitBatch(rejectedIndices, rejectedIndices.map(() => undefined), undefined, {
430
+ commitBatch(rejectedIndices, rejectedIndices.map(() => undefined), {
432
431
  batchIndex: rejectedBatchIndex,
433
432
  batchCount: textBatches.length,
434
433
  docCount: rejectedIndices.length,
@@ -471,7 +470,7 @@ export class RemoteEmbedder {
471
470
  // fabricated "batch-request-failed" skip (#954). Checked (and rethrown)
472
471
  // once the pool drains, the same way `signal?.aborted` is today.
473
472
  let firstOnBatchError;
474
- const commitBatch = (indices, embeddings, model, outcome) => {
473
+ const commitBatch = (indices, embeddings, outcome) => {
475
474
  if (!onBatch)
476
475
  return;
477
476
  // Once persistence has failed once, an already in-flight batch that
@@ -481,7 +480,7 @@ export class RemoteEmbedder {
481
480
  if (firstOnBatchError !== undefined)
482
481
  return;
483
482
  try {
484
- onBatch(indices, embeddings, model, outcome);
483
+ onBatch(indices, embeddings, outcome);
485
484
  }
486
485
  catch (err) {
487
486
  firstOnBatchError = err;
@@ -523,16 +522,14 @@ export class RemoteEmbedder {
523
522
  const requestTimeoutMs = scaleEmbeddingTimeoutMs(configuredTimeoutMs, requestTokens, effectiveTokenBudget);
524
523
  const requestStart = Date.now();
525
524
  let batchEmbeddings;
526
- let responseModel;
527
525
  let outcome;
528
526
  let failureReason;
529
527
  try {
530
- const { vectors, model } = await this.requestBatch(batch, headers, ollamaOpts, requestTimeoutMs, signal);
528
+ const vectors = await this.requestBatch(batch, headers, ollamaOpts, requestTimeoutMs, signal);
531
529
  for (let k = 0; k < indices.length; k++) {
532
530
  results[indices[k]] = vectors[k];
533
531
  }
534
532
  batchEmbeddings = indices.map((i) => results[i]);
535
- responseModel = model;
536
533
  outcome = "stored";
537
534
  }
538
535
  catch (err) {
@@ -571,7 +568,7 @@ export class RemoteEmbedder {
571
568
  // failed or succeeded yet, so there is nothing to persist:
572
569
  // `embeddings` are all `undefined` and the materializer's onBatch
573
570
  // must not touch storage for this event.
574
- commitBatch(indices, indices.map(() => undefined), undefined, {
571
+ commitBatch(indices, indices.map(() => undefined), {
575
572
  batchIndex,
576
573
  batchCount: textBatches.length,
577
574
  docCount: indices.length,
@@ -635,7 +632,7 @@ export class RemoteEmbedder {
635
632
  outcome = "failed";
636
633
  failureReason = message;
637
634
  }
638
- commitBatch(indices, batchEmbeddings, responseModel, {
635
+ commitBatch(indices, batchEmbeddings, {
639
636
  batchIndex,
640
637
  batchCount: textBatches.length,
641
638
  docCount: indices.length,
@@ -665,7 +662,7 @@ export class RemoteEmbedder {
665
662
  // Never made a request — excluded from the default-level per-batch
666
663
  // line (there is no request outcome to report), but still counted
667
664
  // in the run's oversized-skip total via `onSkip` above.
668
- commitBatch([idx], [undefined], undefined, {
665
+ commitBatch([idx], [undefined], {
669
666
  batchIndex,
670
667
  batchCount: textBatches.length,
671
668
  docCount: 1,
@@ -701,11 +698,8 @@ export class RemoteEmbedder {
701
698
  return results;
702
699
  }
703
700
  /**
704
- * Send one batch request and return its embeddings in input order, plus the
705
- * server-reported `model` id when the response body carried one (#955) —
706
- * used by the embedding-fingerprint canary to verify a config-string
707
- * rename against what the endpoint actually served, not just re-assert the
708
- * configured string. Throws on any failure.
701
+ * Send one batch request and return its embeddings in input order. Throws
702
+ * on any failure.
709
703
  *
710
704
  * `timeoutMs` is the caller's ALREADY-SCALED per-request timeout (#954
711
705
  * — see {@link scaleEmbeddingTimeoutMs}), not re-resolved here:
@@ -756,7 +750,7 @@ export class RemoteEmbedder {
756
750
  }
757
751
  results.push(l2Normalize(d.embedding));
758
752
  }
759
- return { vectors: results, model: typeof json.model === "string" && json.model ? json.model : undefined };
753
+ return results;
760
754
  }
761
755
  buildHeaders() {
762
756
  const headers = { "Content-Type": "application/json" };
@@ -7,8 +7,6 @@
7
7
  */
8
8
  const FEATURE_LOCATION = {
9
9
  memory_inference: (cfg) => cfg.index?.memory?.enabled ?? true,
10
- graph_extraction: (cfg) => cfg.index?.graph?.enabled ?? true,
11
- metadata_enhance: (cfg) => cfg.index?.metadataEnhance?.enabled ?? false,
12
10
  // #951: a real implementation of the dead `curate_rerank` key removed in
13
11
  // 0.8.0. Off by default — it requires a `search.curateRerank.endpoint` a
14
12
  // caller must explicitly configure.
@@ -79,15 +77,9 @@ export function isProcessEnabled(section, processName, config) {
79
77
  return false;
80
78
  // Index passes are first-class 0.9 entries.
81
79
  if (section === "index") {
82
- if (processName === "metadata_enhance" || processName === "metadataEnhance") {
83
- return config.index?.metadataEnhance?.enabled ?? true;
84
- }
85
80
  if (processName === "memory_inference" || processName === "memoryInference") {
86
81
  return isLlmFeatureEnabled(config, "memory_inference");
87
82
  }
88
- if (processName === "graph_extraction" || processName === "graphExtraction") {
89
- return isLlmFeatureEnabled(config, "graph_extraction");
90
- }
91
83
  }
92
84
  return false;
93
85
  }
@@ -3,8 +3,7 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import { warn } from "../core/warn.js";
5
5
  import { cloneExecutionJsonObject } from "../execution/json.js";
6
- import { lowerResolvedExecutionRequest } from "../integrations/agent/execution-lowering.js";
7
- import { prepareInlineExecution } from "../integrations/agent/inline-execution.js";
6
+ import { buildExecution, resolveExecution } from "../integrations/agent/execution.js";
8
7
  const NO_LOWERING_NOTICES = Object.freeze([]);
9
8
  function own(value, key) {
10
9
  return value !== undefined && Object.hasOwn(value, key);
@@ -39,14 +38,13 @@ export function resolveIndexPassExecution(passName, config) {
39
38
  ...indexExecutionDefaults(defaults),
40
39
  ...(!own(defaults, "engine") && fallbackLlmEngine ? { engine: fallbackLlmEngine } : {}),
41
40
  };
42
- const prepared = prepareInlineExecution({
41
+ const prepared = resolveExecution({
43
42
  content: "",
44
43
  config,
45
- invocationKind: "direct",
46
44
  invocationDefaults,
47
45
  current: indexExecutionDefaults(pass),
48
46
  });
49
- const lowered = lowerResolvedExecutionRequest(prepared.request, prepared.config);
47
+ const lowered = buildExecution(prepared.request, prepared.runner);
50
48
  if (lowered.runner.kind !== "llm") {
51
49
  warn("[akm] Index pass %s requires an LLM engine; %s is not one. Skipping this pass.", passName, selectedEngine);
52
50
  return Object.freeze({ runner: undefined, notices: NO_LOWERING_NOTICES });
@@ -68,7 +68,7 @@ const DERIVED_MEMORY_JSON_SCHEMA = {
68
68
  * feature gate, error classification, and onFallback hook are honoured uniformly
69
69
  * (Fix C5).
70
70
  */
71
- export async function compressMemoryToDerivedMemory(llmRunner, body, signal, akmConfig, onFallback, telemetry, onRetryAttempt, onNotices, lease) {
71
+ export async function compressMemoryToDerivedMemory(llmRunner, body, signal, akmConfig, onFallback, telemetry, onRetryAttempt, onNotices) {
72
72
  const trimmedBody = body.trim();
73
73
  if (!trimmedBody)
74
74
  return undefined;
@@ -83,7 +83,6 @@ export async function compressMemoryToDerivedMemory(llmRunner, body, signal, akm
83
83
  feature: "memory_inference",
84
84
  akmConfig,
85
85
  runner: llmRunner,
86
- ...(lease ? { lease } : {}),
87
86
  messages: [
88
87
  { role: "system", content: SYSTEM_PROMPT },
89
88
  { role: "user", content: userPrompt },
@@ -2,8 +2,8 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import { ConfigError } from "../core/errors.js";
5
- import { acquireLoweredExecutionDispatchLease, dispatchLoweredExecutionRequest, lowerResolvedExecutionRequestWithRunner, } from "../integrations/agent/execution-lowering.js";
6
- import { prepareInlineExecutionWithRunner } from "../integrations/agent/inline-execution.js";
5
+ import { buildExecution, resolveExecution } from "../integrations/agent/execution.js";
6
+ import { runExecution } from "../integrations/agent/runner-dispatch.js";
7
7
  import { isContextSizeError, LlmCallError } from "./client.js";
8
8
  import { isLlmFeatureEnabled, tryLlmFeature, } from "./feature-gate.js";
9
9
  /**
@@ -62,22 +62,6 @@ function dispatchFailure(result) {
62
62
  const message = result.error ?? result.stderr ?? result.reason ?? "LLM dispatch failed";
63
63
  return result.llmErrorCode ? new LlmCallError(message, result.llmErrorCode) : new Error(message);
64
64
  }
65
- /**
66
- * Validate one already-selected symbolic LLM runner before an operation makes
67
- * any durable mutation. Callers must apply their feature/authorization gates
68
- * first. Acquisition crosses the canonical prepare -> lower -> lease boundary,
69
- * so required credentials are snapshotted by the same central authority as a
70
- * real call without contacting the provider.
71
- */
72
- export async function preflightStructuredLlmRunner(runner) {
73
- const prepared = prepareInlineExecutionWithRunner({
74
- content: "Validate the selected LLM runner before operation dispatch.",
75
- runner,
76
- invocationKind: "direct",
77
- });
78
- const lowered = lowerResolvedExecutionRequestWithRunner(prepared.request, prepared.runner);
79
- return acquireLoweredExecutionDispatchLease(lowered);
80
- }
81
65
  export async function callStructured(opts) {
82
66
  const { feature, akmConfig, enabled, messages, request, parse, onError, fallback, onFallback } = opts;
83
67
  // A disabled feature owns a true no-work path: it does not need a runner,
@@ -97,19 +81,16 @@ export async function callStructured(opts) {
97
81
  const terminal = requireTerminalUserMessage(messages);
98
82
  const prepareInvocation = () => {
99
83
  const current = resolveStructuredCurrent(opts.current, request);
100
- const prepared = prepareInlineExecutionWithRunner({
84
+ const prepared = resolveExecution({
101
85
  content: terminal.content,
102
86
  conversation: terminal.conversation,
103
87
  runner,
104
- invocationKind: "direct",
105
88
  ...(current ? { current } : {}),
106
- ...(opts.authorizeTools ? { authorizeTools: opts.authorizeTools } : {}),
107
89
  });
108
- const lowered = lowerResolvedExecutionRequestWithRunner(prepared.request, prepared.runner);
90
+ const lowered = buildExecution(prepared.request, prepared.runner);
109
91
  opts.onNotices?.(lowered.notices);
110
92
  return async () => {
111
- const result = await dispatchLoweredExecutionRequest(lowered, {
112
- ...(opts.lease ? { lease: opts.lease } : {}),
93
+ const result = await runExecution(lowered, {
113
94
  ...(request?.chat ? { chat: request.chat } : {}),
114
95
  ...(request?.onRetryAttempt ? { onRetryAttempt: request.onRetryAttempt } : {}),
115
96
  ...(own(request, "signal") ? { runOptions: { signal: request?.signal } } : {}),
@@ -1,6 +1,29 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * Generic `md` / `html` / `text` rendering of a shaped output envelope (D7).
6
+ *
7
+ * Every command gets `json`, `jsonl`, and `yaml` for free because those are
8
+ * serializations of the envelope rather than renderings of it. `md`, `html`,
9
+ * and `text` are renderings, and before D7 only `akm health` had `md`/`html`:
10
+ * `md` silently emitted the JSON envelope everywhere else and `html` threw.
11
+ * `text` had the same silent-JSON gap for any command with no registered
12
+ * text formatter, closed later than `md`/`html` — see `renderGenericText`
13
+ * below for why it is its own function rather than a reuse of
14
+ * `renderGenericMarkdown`.
15
+ *
16
+ * These functions close that gap structurally rather than per command. A
17
+ * command that registers a bespoke renderer (`akm health`) still wins; every
18
+ * other command falls back to a real rendering derived from whatever its
19
+ * envelope happens to contain. The shape is discovered, not declared, so a new
20
+ * command is covered the day it is added.
21
+ *
22
+ * Deliberately dependency-free apart from the shared detail types and
23
+ * `escapeHtml`: this module sits underneath the per-command renderer
24
+ * registries and must not import them.
25
+ */
26
+ import { escapeHtml } from "./html-render.js";
4
27
  /**
5
28
  * True when `value` is a non-empty array of plain objects — the shape worth
6
29
  * rendering as a table rather than as a nested list. Uniformity is judged on
@@ -106,17 +129,6 @@ export function renderGenericMarkdown(command, value) {
106
129
  return `${rendered}\n`;
107
130
  }
108
131
  // ── HTML ─────────────────────────────────────────────────────────────────────
109
- const HTML_ESCAPES = {
110
- "&": "&amp;",
111
- "<": "&lt;",
112
- ">": "&gt;",
113
- '"': "&quot;",
114
- "'": "&#39;",
115
- };
116
- /** Escape every value that reaches the document — this is untrusted content. */
117
- function escapeHtml(text) {
118
- return text.replace(/[&<>"']/g, (char) => HTML_ESCAPES[char] ?? char);
119
- }
120
132
  function htmlTable(rows) {
121
133
  const columns = tableColumns(rows);
122
134
  if (columns.length === 0)