akm-cli 0.10.261012-beta → 0.10.261014-beta

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 (518) hide show
  1. package/CHANGELOG.md +710 -3
  2. package/README.md +15 -0
  3. package/SECURITY.md +11 -10
  4. package/STABILITY.md +47 -51
  5. package/dist/assets/hints/cli-hints-full.md +21 -19
  6. package/dist/assets/hints/cli-hints-short.md +3 -4
  7. package/dist/assets/opencode/akm-plugin.js +177 -0
  8. package/dist/assets/stash-skeleton/README.md +1 -1
  9. package/dist/assets/tasks/core/improve.yml +1 -1
  10. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
  11. package/dist/assets/ui/config.js +27 -10
  12. package/dist/assets/workflows/workflow-template.md +2 -2
  13. package/dist/cli/clack.js +3 -1
  14. package/dist/cli/selection.js +33 -0
  15. package/dist/cli/shared.js +14 -1
  16. package/dist/cli/unknown-flags.js +6 -37
  17. package/dist/cli.js +69 -48
  18. package/dist/commands/agent/agent-dispatch.js +17 -25
  19. package/dist/commands/agent/contribute-cli.js +9 -8
  20. package/dist/commands/command/command-cli.js +4 -8
  21. package/dist/commands/command/command-execution.js +25 -39
  22. package/dist/commands/command/execution-source-loader.js +10 -14
  23. package/dist/commands/completions.js +1 -1
  24. package/dist/commands/config-cli.js +14 -5
  25. package/dist/commands/env/child-env.js +12 -14
  26. package/dist/commands/env/env-binding.js +47 -58
  27. package/dist/commands/env/env-cli.js +22 -24
  28. package/dist/commands/env/env.js +10 -58
  29. package/dist/commands/env/secret-cli.js +11 -29
  30. package/dist/commands/env/secret.js +3 -10
  31. package/dist/commands/health/checks.js +10 -849
  32. package/dist/commands/health/connections-and-harnesses-check.js +109 -0
  33. package/dist/commands/health/egress.js +3 -3
  34. package/dist/commands/health/html-report.js +9 -10
  35. package/dist/commands/health/plugin-staleness.js +18 -11
  36. package/dist/commands/health/report-view-model.js +16 -12
  37. package/dist/commands/health/scheduler-binary.js +1 -1
  38. package/dist/commands/health/semantic-search-check.js +85 -0
  39. package/dist/commands/health/type-directory-check.js +0 -3
  40. package/dist/commands/health.js +30 -42
  41. package/dist/commands/improve/consolidate/pair-pass.js +10 -25
  42. package/dist/commands/improve/consolidate.js +10 -15
  43. package/dist/commands/improve/distill.js +5 -17
  44. package/dist/commands/improve/eligibility.js +1 -3
  45. package/dist/commands/improve/execution.js +37 -40
  46. package/dist/commands/improve/extract-cli.js +6 -11
  47. package/dist/commands/improve/extract-prompt.js +2 -2
  48. package/dist/commands/improve/extract.js +67 -97
  49. package/dist/commands/improve/improve-cli.js +22 -128
  50. package/dist/commands/improve/improve-report.js +1 -1
  51. package/dist/commands/improve/improve-strategies.js +25 -108
  52. package/dist/commands/improve/improve.js +10 -14
  53. package/dist/commands/improve/loop-stages.js +3 -0
  54. package/dist/commands/improve/memory/memory-improve.js +1 -1
  55. package/dist/commands/improve/preparation.js +8 -13
  56. package/dist/commands/improve/reflect.js +203 -332
  57. package/dist/commands/improve/retrieval-scope.js +1 -1
  58. package/dist/commands/improve/session-asset.js +3 -2
  59. package/dist/commands/improve/stage.js +87 -115
  60. package/dist/commands/lint/base-linter.js +3 -3
  61. package/dist/commands/lint/env-key-rules.js +7 -6
  62. package/dist/commands/lint/index.js +3 -3
  63. package/dist/commands/models-cli.js +103 -63
  64. package/dist/commands/proposal/drain.js +26 -39
  65. package/dist/commands/proposal/proposal-cli.js +14 -18
  66. package/dist/commands/proposal/propose-cli.js +4 -2
  67. package/dist/commands/proposal/propose.js +37 -64
  68. package/dist/commands/proposal/repository.js +17 -17
  69. package/dist/commands/proposal/validators/proposal-validators.js +3 -6
  70. package/dist/commands/read/curate.js +10 -6
  71. package/dist/commands/read/registry-search.js +2 -48
  72. package/dist/commands/read/search-cli.js +1 -8
  73. package/dist/commands/read/search.js +5 -6
  74. package/dist/commands/read/show.js +6 -29
  75. package/dist/commands/remember.js +25 -40
  76. package/dist/commands/sources/add-cli.js +8 -63
  77. package/dist/commands/sources/bundle-cli.js +8 -9
  78. package/dist/commands/sources/bundle-config-ops.js +2 -2
  79. package/dist/commands/sources/info.js +12 -1
  80. package/dist/commands/sources/init.js +1 -1
  81. package/dist/commands/sources/installed-stashes.js +119 -63
  82. package/dist/commands/sources/migration-help.js +1 -1
  83. package/dist/commands/sources/plugin-upgrade.js +8 -15
  84. package/dist/commands/sources/schema-repair.js +4 -10
  85. package/dist/commands/sources/source-add.js +2 -2
  86. package/dist/commands/sources/source-clone.js +31 -7
  87. package/dist/commands/sources/source-manage.js +4 -4
  88. package/dist/commands/targets.js +175 -0
  89. package/dist/commands/tasks/explain.js +104 -69
  90. package/dist/commands/tasks/tasks-cli.js +9 -11
  91. package/dist/commands/tasks/tasks.js +75 -97
  92. package/dist/commands/ui/api.js +11 -3
  93. package/dist/commands/ui/redact.js +5 -31
  94. package/dist/commands/ui/workspace-actions.js +1 -1
  95. package/dist/commands/workflow/plan.js +48 -9
  96. package/dist/commands/workflow-cli.js +40 -45
  97. package/dist/core/adapter/adapters/agent-skills-adapter.js +10 -11
  98. package/dist/core/adapter/adapters/akm-adapter.js +36 -41
  99. package/dist/core/adapter/adapters/akm-lint.js +10 -12
  100. package/dist/core/adapter/adapters/akm-metadata.js +2 -2
  101. package/dist/core/adapter/adapters/akm-task-adapter.js +8 -9
  102. package/dist/core/adapter/adapters/akm-workflow-adapter.js +5 -5
  103. package/dist/core/adapter/adapters/claude-adapter.js +1 -1
  104. package/dist/core/adapter/adapters/dotenv-adapter.js +7 -6
  105. package/dist/core/adapter/adapters/generic-files-adapter.js +5 -5
  106. package/dist/core/adapter/adapters/index.js +3 -4
  107. package/dist/core/adapter/adapters/llm-wiki-adapter.js +12 -14
  108. package/dist/core/adapter/adapters/okf-adapter.js +8 -10
  109. package/dist/core/adapter/adapters/opencode-adapter.js +1 -1
  110. package/dist/core/adapter/adapters/shared.js +3 -3
  111. package/dist/core/adapter/adapters/tool-dir-shared.js +7 -25
  112. package/dist/core/adapter/adapters/website-snapshot-adapter.js +3 -3
  113. package/dist/core/adapter/detect-adapter.js +1 -1
  114. package/dist/core/adapter/execution-source.js +13 -35
  115. package/dist/core/adapter/registry.js +1 -1
  116. package/dist/core/adapter/validate-context.js +2 -4
  117. package/dist/core/asset/asset-placement.js +1 -1
  118. package/dist/core/asset/asset-ref.js +3 -3
  119. package/dist/core/asset/resolve-ref.js +5 -0
  120. package/dist/core/bundle-rename.js +12 -4
  121. package/dist/core/closest-match.js +37 -0
  122. package/dist/core/common.js +37 -57
  123. package/dist/core/config/config-io.js +26 -18
  124. package/dist/core/config/config-schema.js +19 -106
  125. package/dist/core/config/config-sources.js +3 -3
  126. package/dist/core/config/config-types.js +4 -4
  127. package/dist/core/config/config-walker.js +50 -77
  128. package/dist/core/config/config.js +438 -109
  129. package/dist/core/config/convert-engine-references.js +114 -0
  130. package/dist/core/config/convert-engines-shared.js +40 -0
  131. package/dist/core/config/convert-engines.js +300 -0
  132. package/dist/core/config/convert-models-overlay.js +137 -0
  133. package/dist/core/config/credentials.js +304 -0
  134. package/dist/core/config/engine-semantics.js +3 -3
  135. package/dist/core/config/migrate-keys.js +222 -0
  136. package/dist/core/config/model-aliases.js +37 -0
  137. package/dist/core/config/models-file.js +34 -0
  138. package/dist/core/config/retired-engines.js +53 -0
  139. package/dist/core/config/schema/connections.js +41 -0
  140. package/dist/core/config/schema/embedding.js +2 -2
  141. package/dist/core/config/schema/harnesses.js +41 -0
  142. package/dist/core/config/schema/improve-processes.js +9 -28
  143. package/dist/core/config/schema/improve.js +36 -1
  144. package/dist/core/config/schema/index-config.js +18 -20
  145. package/dist/core/config/schema/primitives.js +42 -17
  146. package/dist/core/config/schema/search.js +6 -11
  147. package/dist/core/config/schema/sources-bundles.js +9 -9
  148. package/dist/core/config/schema/workflow.js +2 -6
  149. package/dist/core/config/unusable-entries.js +66 -0
  150. package/dist/core/content-safety.js +3 -6
  151. package/dist/core/endpoint-url.js +47 -0
  152. package/dist/core/env-secret-ref.js +84 -73
  153. package/dist/core/errors.js +10 -16
  154. package/dist/core/extra-params.js +3 -3
  155. package/dist/core/improve-result.js +8 -9
  156. package/dist/core/json-schema.js +1 -1
  157. package/dist/core/lesson-lint.js +1 -1
  158. package/dist/core/llm-inference.js +80 -0
  159. package/dist/core/parse.js +2 -2
  160. package/dist/core/paths.js +33 -10
  161. package/dist/core/recognition-util.js +8 -10
  162. package/dist/core/redaction.js +94 -55
  163. package/dist/core/ref-token.js +82 -0
  164. package/dist/core/secret-value.js +14 -0
  165. package/dist/core/state/migrations.js +17 -22
  166. package/dist/core/structured.js +2 -68
  167. package/dist/core/subprocess.js +63 -22
  168. package/dist/core/type-presentation.js +10 -14
  169. package/dist/core/write-source.js +20 -4
  170. package/dist/execution/input-contract.js +3 -6
  171. package/dist/execution/notices.js +49 -0
  172. package/dist/execution/resolved-request.js +24 -40
  173. package/dist/execution/source.js +21 -45
  174. package/dist/execution/target-ref.js +2 -2
  175. package/dist/indexer/bundle-identity-guard.js +6 -5
  176. package/dist/indexer/ensure-index.js +1 -1
  177. package/dist/indexer/index-writer-lock.js +1 -1
  178. package/dist/indexer/indexer.js +46 -42
  179. package/dist/indexer/installations.js +12 -22
  180. package/dist/indexer/lookup/adapter-concept-owner.js +40 -14
  181. package/dist/indexer/materialize-embeddings.js +20 -16
  182. package/dist/indexer/passes/memory-inference.js +21 -50
  183. package/dist/indexer/passes/metadata.js +5 -5
  184. package/dist/indexer/scan/doc-to-entry.js +1 -1
  185. package/dist/indexer/scan/drain-dir.js +9 -11
  186. package/dist/indexer/search/db-search.js +9 -7
  187. package/dist/indexer/search/search-source.js +42 -22
  188. package/dist/indexer/usage/usage-events.js +2 -3
  189. package/dist/indexer/walk/index-context.js +2 -1
  190. package/dist/indexer/walk/matchers.js +3 -11
  191. package/dist/indexer/walk/path-resolver.js +13 -68
  192. package/dist/indexer/walk/walker.js +32 -26
  193. package/dist/integrations/agent/akm-read-tools.js +81 -0
  194. package/dist/integrations/agent/config.js +1 -1
  195. package/dist/integrations/agent/detect.js +32 -36
  196. package/dist/integrations/agent/execution.js +130 -428
  197. package/dist/integrations/agent/index.js +1 -1
  198. package/dist/integrations/agent/profiles.js +24 -28
  199. package/dist/integrations/agent/prompts.js +17 -30
  200. package/dist/integrations/agent/request-lowering.js +67 -101
  201. package/dist/integrations/agent/resolution.js +332 -0
  202. package/dist/integrations/agent/runner-dispatch.js +156 -181
  203. package/dist/integrations/agent/runner.js +20 -70
  204. package/dist/integrations/agent/runtime-port.js +4 -0
  205. package/dist/integrations/agent/runtime.js +10 -0
  206. package/dist/integrations/agent/spawn.js +65 -190
  207. package/dist/integrations/harnesses/aider/index.js +19 -39
  208. package/dist/integrations/harnesses/amazonq/index.js +17 -32
  209. package/dist/integrations/harnesses/claude/index.js +59 -28
  210. package/dist/integrations/harnesses/claude/session-log.js +7 -5
  211. package/dist/integrations/harnesses/codex/index.js +19 -31
  212. package/dist/integrations/harnesses/copilot/index.js +17 -35
  213. package/dist/integrations/harnesses/gemini/index.js +18 -34
  214. package/dist/integrations/harnesses/harness.js +36 -0
  215. package/dist/integrations/harnesses/index.js +20 -51
  216. package/dist/integrations/harnesses/opencode/agent-builder.js +132 -100
  217. package/dist/integrations/harnesses/opencode/index.js +11 -33
  218. package/dist/integrations/harnesses/opencode/roots.js +50 -0
  219. package/dist/integrations/harnesses/opencode/runtime/binary.js +206 -0
  220. package/dist/integrations/harnesses/opencode/runtime/command.js +152 -0
  221. package/dist/integrations/harnesses/opencode/runtime/index.js +177 -0
  222. package/dist/integrations/harnesses/opencode/runtime/tar.js +107 -0
  223. package/dist/integrations/harnesses/opencode/session-log-v1.js +15 -7
  224. package/dist/integrations/harnesses/opencode/session-log-v2.js +72 -48
  225. package/dist/integrations/harnesses/opencode/session-log.js +58 -137
  226. package/dist/integrations/harnesses/opencode/version.js +34 -53
  227. package/dist/integrations/harnesses/openhands/index.js +13 -37
  228. package/dist/integrations/harnesses/pi/index.js +21 -32
  229. package/dist/integrations/lockfile.js +1 -1
  230. package/dist/integrations/session-logs/index.js +11 -31
  231. package/dist/llm/client.js +93 -111
  232. package/dist/llm/embedder.js +19 -34
  233. package/dist/llm/embedders/connection.js +31 -0
  234. package/dist/llm/embedders/local-model-files.js +56 -0
  235. package/dist/llm/embedders/local.js +146 -115
  236. package/dist/llm/embedders/remote.js +26 -23
  237. package/dist/llm/embedders/types.js +1 -1
  238. package/dist/llm/index-passes.js +33 -39
  239. package/dist/llm/memory-infer.js +67 -77
  240. package/dist/llm/model-list.js +35 -0
  241. package/dist/llm/rerank-client.js +8 -14
  242. package/dist/llm/structured-call.js +45 -99
  243. package/dist/llm/structured.js +60 -0
  244. package/dist/output/renderers.js +2 -8
  245. package/dist/output/shapes/helpers.js +18 -44
  246. package/dist/output/shapes/passthrough.js +1 -0
  247. package/dist/output/shapes.js +1 -7
  248. package/dist/output/text/command-format.js +41 -39
  249. package/dist/output/text/health-format.js +8 -2
  250. package/dist/output/text/helpers.js +1 -1
  251. package/dist/output/text/migrate.js +12 -0
  252. package/dist/output/text/models.js +3 -2
  253. package/dist/output/text/registry-commands.js +1 -2
  254. package/dist/output/text/show-directives.js +16 -28
  255. package/dist/output/text/show-format.js +0 -2
  256. package/dist/output/text/targets-table.js +70 -0
  257. package/dist/output/text/workflow-format.js +44 -15
  258. package/dist/output/text.js +1 -1
  259. package/dist/registry/providers/skills-sh.js +1 -28
  260. package/dist/registry/providers/static-index.js +1 -71
  261. package/dist/runtime.js +6 -2
  262. package/dist/scripts/akm-migrate-node.js +47095 -44905
  263. package/dist/scripts/akm-migrate.js +46946 -44755
  264. package/dist/setup/detect.js +28 -273
  265. package/dist/setup/endpoint.js +36 -0
  266. package/dist/setup/semantic-assets.js +13 -19
  267. package/dist/setup/setup-flags.js +77 -0
  268. package/dist/setup/setup-plan.js +144 -0
  269. package/dist/setup/setup.js +134 -358
  270. package/dist/setup/steps/connection-shared.js +49 -101
  271. package/dist/setup/steps/connection.js +121 -524
  272. package/dist/setup/steps/embeddings.js +151 -0
  273. package/dist/setup/steps/harnesses.js +118 -0
  274. package/dist/setup/steps/platforms.js +2 -81
  275. package/dist/setup/steps/tasks.js +1 -2
  276. package/dist/setup/steps.js +10 -0
  277. package/dist/setup/summary.js +67 -0
  278. package/dist/sources/freshness.js +16 -21
  279. package/dist/sources/providers/git-provider.js +2 -9
  280. package/dist/sources/providers/provider-utils.js +13 -5
  281. package/dist/sources/resolve.js +12 -16
  282. package/dist/sources/snapshot-fetchers/robots.js +11 -12
  283. package/dist/sources/snapshot-fetchers/secret-seam.js +2 -4
  284. package/dist/sources/snapshot-fetchers/website-ingest.js +8 -15
  285. package/dist/sources/snapshot-fetchers/x.js +1 -1
  286. package/dist/standalone/onnxruntime-library.js +52 -0
  287. package/dist/storage/repositories/improve-ledger-repository.js +1 -1
  288. package/dist/storage/repositories/improve-runs-repository.js +0 -13
  289. package/dist/storage/repositories/index-entries-repository.js +2 -2
  290. package/dist/storage/repositories/proposals-repository.js +2 -2
  291. package/dist/storage/repositories/task-history-repository.js +2 -2
  292. package/dist/storage/repositories/workflow-runs-repository.js +44 -129
  293. package/dist/storage/sqlite-read-snapshot.js +33 -29
  294. package/dist/tasks/embedded.js +1 -1
  295. package/dist/tasks/log-redaction.js +7 -119
  296. package/dist/tasks/prepare/prepare-support.js +8 -7
  297. package/dist/tasks/prepare/prepare.js +8 -9
  298. package/dist/tasks/prepare/script-capture.js +9 -25
  299. package/dist/tasks/run/attempt-lifecycle.js +17 -35
  300. package/dist/tasks/run/load-task.js +54 -27
  301. package/dist/tasks/run/run-command-task.js +15 -10
  302. package/dist/tasks/run/run-native-task.js +8 -21
  303. package/dist/tasks/run/run-task.js +5 -8
  304. package/dist/tasks/run/run-workflow-task.js +14 -21
  305. package/dist/tasks/run/task-history.js +9 -17
  306. package/dist/tasks/run/task-log.js +1 -5
  307. package/dist/tasks/scheduler-invocation.js +13 -18
  308. package/dist/tasks/scheduler-sync.js +0 -1
  309. package/dist/tasks/source/bounded-document.js +31 -117
  310. package/dist/tasks/source/parse-task-source.js +0 -1
  311. package/dist/tasks/source/project-v4.js +5 -3
  312. package/dist/tasks/source/task-input-diagnostics.js +3 -4
  313. package/dist/tasks/source/task-source-v4.js +48 -72
  314. package/dist/tasks/source-v3.js +2 -5
  315. package/dist/tasks/task-run-reserved-flags.js +1 -2
  316. package/dist/workflows/authoring/authoring.js +2 -7
  317. package/dist/workflows/compile.js +1 -15
  318. package/dist/workflows/concurrency-policy.js +4 -4
  319. package/dist/workflows/exec/child-workflow.js +1 -4
  320. package/dist/workflows/exec/dispatch-redaction.js +35 -86
  321. package/dist/workflows/exec/environment.js +13 -77
  322. package/dist/workflows/exec/exec-unit.js +14 -55
  323. package/dist/workflows/exec/frozen-judge.js +26 -28
  324. package/dist/workflows/exec/native-executor.js +126 -71
  325. package/dist/workflows/exec/run-workflow.js +38 -42
  326. package/dist/workflows/exec/step-work.js +13 -17
  327. package/dist/workflows/exec/unit-dispatch.js +7 -21
  328. package/dist/workflows/freeze/environment.js +14 -119
  329. package/dist/workflows/freeze/freeze.js +14 -33
  330. package/dist/workflows/freeze/step-values.js +6 -13
  331. package/dist/workflows/freeze/targets/child-workflow.js +3 -5
  332. package/dist/workflows/freeze/targets/command.js +9 -15
  333. package/dist/workflows/freeze/targets/shell.js +0 -3
  334. package/dist/workflows/freeze/task-bindings.js +0 -1
  335. package/dist/workflows/parser.js +50 -59
  336. package/dist/workflows/plan.js +8 -2
  337. package/dist/workflows/renderer.js +83 -9
  338. package/dist/workflows/resource-limits.js +2 -2
  339. package/dist/workflows/runtime/run-plan.js +38 -23
  340. package/dist/workflows/runtime/runs.js +55 -93
  341. package/dist/workflows/runtime/workflow-asset-loader.js +55 -86
  342. package/dist/workflows/source-files.js +7 -19
  343. package/docs/README.md +10 -16
  344. package/docs/architecture/README.md +2 -37
  345. package/docs/architecture/adapters.md +2 -2
  346. package/docs/architecture/akm-core-principles.md +256 -118
  347. package/docs/architecture/architecture.md +283 -99
  348. package/docs/architecture/improvement.md +8 -2
  349. package/docs/architecture/internals/classification.md +1 -3
  350. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +7 -6
  351. package/docs/architecture/internals/health-advisories.md +35 -74
  352. package/docs/architecture/internals/improve-workflow.md +27 -26
  353. package/docs/architecture/internals/indexing.md +3 -3
  354. package/docs/architecture/internals/storage-locations.md +48 -15
  355. package/docs/architecture/persisted-data-compat.md +10 -6
  356. package/docs/architecture/specs/okf-support.md +9 -11
  357. package/docs/architecture/specs/ref.md +7 -9
  358. package/docs/architecture/testing/testing-workflow.md +172 -52
  359. package/docs/architecture/workflow-engine.md +51 -34
  360. package/docs/guides/README.md +0 -1
  361. package/docs/guides/author-bundles.md +15 -20
  362. package/docs/guides/author-workflows.md +93 -71
  363. package/docs/guides/bundles.md +20 -16
  364. package/docs/guides/discover-and-load.md +1 -1
  365. package/docs/guides/getting-started.md +49 -3
  366. package/docs/guides/improve-the-library.md +10 -4
  367. package/docs/guides/recipes/headless-install.md +11 -16
  368. package/docs/guides/run-workflows.md +29 -20
  369. package/docs/guides/scheduling.md +2 -2
  370. package/docs/guides/use-with-any-agent.md +20 -22
  371. package/docs/integration/bundling-akm.md +19 -9
  372. package/docs/maintainers/README.md +2 -6
  373. package/docs/maintainers/release-checklist.md +73 -126
  374. package/docs/migration/README.md +10 -3
  375. package/docs/migration/release-notes/0.10.0.md +81 -16
  376. package/docs/migration/release-notes/0.6.0.md +1 -1
  377. package/docs/migration/release-notes/0.7.0.md +1 -1
  378. package/docs/migration/release-notes/0.9.0.md +1 -1
  379. package/docs/migration/release-notes/README.md +1 -1
  380. package/docs/migration/v0.9-to-v0.10.md +300 -60
  381. package/docs/migration/v0.9.1-to-v0.9.2.md +6 -5
  382. package/docs/posts/config-v2-lessons-16.md +1 -1
  383. package/docs/posts/llm-mode-reflect-13.md +1 -1
  384. package/docs/posts/release-0.6.0.md +11 -11
  385. package/docs/posts/release-0.8.0.md +4 -4
  386. package/docs/posts/workflows-vaults-09.md +1 -1
  387. package/docs/reference/README.md +1 -1
  388. package/docs/reference/asset-types.md +2 -2
  389. package/docs/reference/cli.md +477 -388
  390. package/docs/reference/configuration.md +569 -550
  391. package/docs/reference/data-and-telemetry.md +9 -6
  392. package/docs/reference/env-and-secrets.md +72 -15
  393. package/docs/reference/refs.md +3 -20
  394. package/docs/reference/registry.md +12 -38
  395. package/docs/reference/supported-formats.md +1 -1
  396. package/docs/reference/tasks.md +22 -11
  397. package/docs/reference/ui-api.md +14 -9
  398. package/docs/reference/workflow-schema.md +199 -154
  399. package/docs/reference/workflows.md +4 -6
  400. package/package.json +9 -11
  401. package/schemas/akm-config.json +1696 -2922
  402. package/schemas/akm-task.json +4 -4
  403. package/schemas/akm-workflow.json +36 -9
  404. package/ROADMAP.md +0 -112
  405. package/dist/assets/models.json +0 -35
  406. package/dist/commands/health/engine-usage.js +0 -45
  407. package/dist/commands/sources/dangerous-env-audit.js +0 -134
  408. package/dist/core/activation-policy.js +0 -67
  409. package/dist/core/config/schema/engines.js +0 -160
  410. package/dist/core/config/schema/execution.js +0 -23
  411. package/dist/core/spawn-env.js +0 -268
  412. package/dist/execution/directory-identity.js +0 -78
  413. package/dist/integrations/agent/builder-shared.js +0 -33
  414. package/dist/integrations/agent/builders.js +0 -43
  415. package/dist/integrations/agent/engine-fallback.js +0 -59
  416. package/dist/integrations/agent/engine-resolution.js +0 -333
  417. package/dist/integrations/agent/model-map.js +0 -475
  418. package/dist/integrations/harnesses/aider/agent-builder.js +0 -107
  419. package/dist/integrations/harnesses/aider/result-extractor.js +0 -53
  420. package/dist/integrations/harnesses/amazonq/agent-builder.js +0 -138
  421. package/dist/integrations/harnesses/amazonq/result-extractor.js +0 -48
  422. package/dist/integrations/harnesses/claude/agent-builder.js +0 -106
  423. package/dist/integrations/harnesses/claude/config-import.js +0 -67
  424. package/dist/integrations/harnesses/claude/result-extractor.js +0 -67
  425. package/dist/integrations/harnesses/codex/agent-builder.js +0 -150
  426. package/dist/integrations/harnesses/codex/result-extractor.js +0 -110
  427. package/dist/integrations/harnesses/copilot/agent-builder.js +0 -117
  428. package/dist/integrations/harnesses/copilot/result-extractor.js +0 -178
  429. package/dist/integrations/harnesses/gemini/agent-builder.js +0 -114
  430. package/dist/integrations/harnesses/gemini/result-extractor.js +0 -149
  431. package/dist/integrations/harnesses/opencode/config-import.js +0 -149
  432. package/dist/integrations/harnesses/opencode/model-config.js +0 -33
  433. package/dist/integrations/harnesses/opencode/model-work-agent.js +0 -115
  434. package/dist/integrations/harnesses/opencode/session-log-types.js +0 -12
  435. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -44
  436. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -1052
  437. package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +0 -199
  438. package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +0 -254
  439. package/dist/integrations/harnesses/opencode-sdk/wire.js +0 -66
  440. package/dist/integrations/harnesses/openhands/agent-builder.js +0 -120
  441. package/dist/integrations/harnesses/openhands/result-extractor.js +0 -135
  442. package/dist/integrations/harnesses/pi/agent-builder.js +0 -89
  443. package/dist/integrations/harnesses/pi/result-extractor.js +0 -168
  444. package/dist/integrations/harnesses/shared.js +0 -18
  445. package/dist/integrations/harnesses/types.js +0 -55
  446. package/dist/llm/feature-gate.js +0 -115
  447. package/dist/output/shapes/models-list.js +0 -16
  448. package/dist/output/shapes/registry-search.js +0 -10
  449. package/dist/setup/detected-engines.js +0 -136
  450. package/dist/setup/engine-config.js +0 -97
  451. package/dist/setup/harness-config-import.js +0 -47
  452. package/dist/setup/providers.js +0 -14
  453. package/dist/setup/steps/semantic.js +0 -39
  454. package/dist/workflows/authoring/scope-key.js +0 -79
  455. package/dist/workflows/exec/lowering-notices.js +0 -23
  456. package/dist/workflows/source-semantics.js +0 -110
  457. package/docs/architecture/0.10-process-rules.md +0 -832
  458. package/docs/architecture/akm-architecture-decision-history.md +0 -2055
  459. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +0 -550
  460. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +0 -72
  461. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +0 -142
  462. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +0 -189
  463. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +0 -97
  464. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +0 -108
  465. package/docs/architecture/decisions/0006-task-source-version-routing.md +0 -124
  466. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +0 -83
  467. package/docs/architecture/decisions/0008-task-binding-normalization.md +0 -88
  468. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +0 -80
  469. package/docs/architecture/decisions/0010-driver-protocol-cut.md +0 -36
  470. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +0 -125
  471. package/docs/architecture/decisions/README.md +0 -62
  472. package/docs/architecture/internals/functional-contract-patterns.md +0 -340
  473. package/docs/architecture/internals/registry-network-boundary.md +0 -57
  474. package/docs/architecture/internals/search.md +0 -248
  475. package/docs/architecture/reviews/env-secret-access.md +0 -319
  476. package/docs/architecture/runtime-boundary-design.md +0 -153
  477. package/docs/architecture/specs/0.9.0-close-out-plan.md +0 -361
  478. package/docs/architecture/specs/0.9.0-decisions.md +0 -532
  479. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +0 -745
  480. package/docs/architecture/specs/0.9.0-open-items-register.md +0 -135
  481. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +0 -740
  482. package/docs/architecture/specs/0.9.0-release-surface-review.md +0 -636
  483. package/docs/architecture/specs/agent-command-engine-model-design.md +0 -513
  484. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +0 -501
  485. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +0 -291
  486. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +0 -2059
  487. package/docs/architecture/specs/di-seams-plan.md +0 -539
  488. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +0 -275
  489. package/docs/architecture/specs/fact-asset-type.md +0 -142
  490. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +0 -634
  491. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +0 -72
  492. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +0 -152
  493. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +0 -352
  494. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +0 -300
  495. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +0 -402
  496. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +0 -758
  497. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +0 -645
  498. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +0 -602
  499. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +0 -27
  500. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +0 -27
  501. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +0 -74
  502. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +0 -15
  503. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +0 -132
  504. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +0 -147
  505. package/docs/architecture/specs/stash-conventions-code-spec.md +0 -275
  506. package/docs/architecture/specs/stash-organization-conventions.md +0 -377
  507. package/docs/architecture/specs/task-workflow-format-unification.md +0 -721
  508. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +0 -231
  509. package/docs/architecture/specs/workflow-format-unification.md +0 -432
  510. package/docs/architecture/testing/manual-testing-checklist.md +0 -3411
  511. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +0 -924
  512. package/docs/architecture/testing/task-workflow-manual-tests.md +0 -1720
  513. package/docs/guides/claude-code-vs-akm-workflows.md +0 -29
  514. package/docs/guides/knowledge-management.md +0 -18
  515. package/docs/maintainers/curate-workmap.md +0 -335
  516. package/docs/migration/v0.5-to-v0.6.md +0 -759
  517. package/docs/migration/v0.7-to-v0.8.md +0 -1378
  518. package/docs/plans/0.9.2-agent-command-workflow-plan.md +0 -423
@@ -43,7 +43,7 @@ export function loadRetrievalScope(access, stashDir) {
43
43
  }
44
44
  if (!stashDir)
45
45
  return;
46
- // Blocker 1 (second review round): a pair-pass ledger row must NOT mark
46
+ // A pair-pass ledger row must NOT mark
47
47
  // an asset "processed" — unlike every other stage, the pair pass judges
48
48
  // material against its NEIGHBOURS, not on its own merits, so its own
49
49
  // attempt is not usage evidence the proactive lane
@@ -112,8 +112,9 @@ export function buildSessionAccessInstructions(harness, logPath, sessionId) {
112
112
  if (harness === "opencode") {
113
113
  return [
114
114
  `Open the SQLite database at ${JSON.stringify(logPath)} in read-only mode.`,
115
- "Query: SELECT m.data, p.data FROM message AS m JOIN part AS p ON p.message_id = m.id WHERE m.session_id = ? AND p.session_id = ? ORDER BY m.time_created, p.time_created;",
116
- `Bind both parameters to ${JSON.stringify(sessionId)}.`,
115
+ "If it has a session_v2 table (OpenCode 2), query: SELECT type, data FROM session_message WHERE session_id = ? ORDER BY seq;",
116
+ "otherwise (OpenCode 1), query: SELECT m.data, p.data FROM message AS m JOIN part AS p ON p.message_id = m.id WHERE m.session_id = ? AND p.session_id = ? ORDER BY m.time_created, p.time_created;",
117
+ `Bind the session parameters (one in the first query, both in the second) to ${JSON.stringify(sessionId)}.`,
117
118
  ].join("\n");
118
119
  }
119
120
  return `Read with: cat ${logPath}`;
@@ -1,13 +1,13 @@
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
- import { getImproveProcessConfig } from "../../core/config/config.js";
4
+ import { SHIPPED_ALIAS } from "../../core/config/model-aliases.js";
5
5
  import { ConfigError } from "../../core/errors.js";
6
+ import { effectiveRequestFields, thinkingSetting } from "../../core/llm-inference.js";
6
7
  import { parseEmbeddedJsonResponse } from "../../core/parse.js";
7
- import { defaultFeedback } from "../../core/structured.js";
8
8
  import { warn } from "../../core/warn.js";
9
- import { runnerLlmConnection } from "../../integrations/agent/runner.js";
10
- import { callStructured, dispatchFailureReason, dispatchFailureResult, } from "../../llm/structured-call.js";
9
+ import { isRefused, structuredLoop } from "../../llm/structured.js";
10
+ import { callStructured } from "../../llm/structured-call.js";
11
11
  import { currentLlmStage, withLlmStage } from "../../llm/usage-telemetry.js";
12
12
  import { isProceduralRejection } from "../proposal/proposal-types.js";
13
13
  import { createProposal, listProposalsReadOnly, proposalContentHash, recordGateDecision, } from "../proposal/repository.js";
@@ -16,65 +16,47 @@ import { resolveImproveExecution } from "./execution.js";
16
16
  export function errMessage(e) {
17
17
  return e instanceof Error ? e.message : String(e);
18
18
  }
19
- /** The lowering notices a stage's dispatches emitted, each once. */
20
- export function noticeSet(forward) {
21
- const byKey = new Map();
22
- const add = (notices) => {
23
- for (const notice of notices)
24
- byKey.set(JSON.stringify(notice), notice);
25
- forward?.(notices);
26
- };
27
- const list = () => Object.freeze([...byKey.values()]);
28
- return { add, list, fields: () => (byKey.size > 0 ? { notices: list() } : {}) };
29
- }
30
19
  /**
31
20
  * A stage's runner: the one the improve plan froze for it (an own
32
- * `llmRunner` key, `null` meaning "none"), else the process engine cascade.
21
+ * `llmRunner` key, `null` meaning "none"), else the one the process resolves to now.
33
22
  */
34
- export function stageRunner(frozen, config, profile, processName, onNotices) {
23
+ export function stageRunner(frozen, config, processName, onNotices) {
35
24
  if (Object.hasOwn(frozen, "llmRunner"))
36
25
  return frozen.llmRunner ?? undefined;
37
- const resolved = resolveImproveExecution({
38
- config,
39
- profile,
40
- process: getImproveProcessConfig(processName, profile),
41
- processName,
42
- });
26
+ const resolved = resolveImproveExecution({ config, processName, alias: SHIPPED_ALIAS.improve });
43
27
  if (resolved)
44
28
  onNotices?.(resolved.notices);
45
29
  return resolved?.runner;
46
30
  }
47
31
  /**
48
- * One model call. Provider trouble (transport error, timeout, abort, a
49
- * disabled feature) comes back as `{ ok: false }`; only a configuration
50
- * failure throws. A reply to a call with `request.responseSchema` that the
51
- * stage's own `parse` rejects gets one corrective retry; the last reply comes
52
- * back either way, and the caller parses it again.
32
+ * The stage's call under the structured loop: each dispatch is one
33
+ * {@link callStageOnce}, and the correction a refused reply earns is appended
34
+ * to the prompt. The loop's own result comes back, so a caller that must tell a
35
+ * refused reply (and read what the parser said) from a failed call can.
53
36
  */
54
- export async function callStage(call) {
55
- const reply = await callStageOnce(call);
56
- if (!reply.ok || !call.request?.responseSchema)
57
- return reply;
58
- if ((call.parse ?? parseEmbeddedJsonResponse)(reply.raw) !== undefined)
59
- return reply;
60
- const feedback = defaultFeedback({ reason: "parse_error", errors: [] });
61
- const retry = await callStageOnce({ ...call, prompt: `${call.prompt}\n\n${feedback}` });
62
- // A retry that fails in transport keeps the first reply, which the caller may still accept.
63
- return retry.ok ? retry : reply;
64
- }
65
- /** Timeout and abort come from the dispatch's own reason, whatever the runner's kind. */
66
- function failureReason(err) {
67
- const reason = dispatchFailureReason(err);
68
- return reason === "timeout" || reason === "aborted" ? reason : "error";
37
+ export function callStageLoop(call, parse, correct) {
38
+ return structuredLoop({
39
+ dispatch: (correction) => callStageOnce(correction ? { ...call, prompt: `${call.prompt}\n\n${correction.text}` } : call),
40
+ parse,
41
+ ...(correct ? { correct } : {}),
42
+ });
69
43
  }
70
- /** A failed call: its reason and message, and the dispatch's own result when it reached a transport. */
71
- function failedCall(err) {
72
- const result = dispatchFailureResult(err);
73
- return { ok: false, reason: failureReason(err), error: errMessage(err), ...(result ? { result } : {}) };
44
+ /**
45
+ * One model call. Provider trouble (transport error, timeout, abort) comes back
46
+ * as `{ ok: false }`; only a configuration failure throws. A reply to a call with `request.responseSchema` that the
47
+ * stage's own `parse` rejects gets one corrective retry (the structured loop);
48
+ * the last reply comes back either way, and the caller parses it again.
49
+ */
50
+ export async function callStage(call) {
51
+ if (!call.request?.responseSchema)
52
+ return callStageOnce(call);
53
+ const parse = call.parse ?? parseEmbeddedJsonResponse;
54
+ const loop = await callStageLoop(call, (raw) => parse(raw) === undefined ? { ok: false, errors: ["no parseable JSON"] } : { ok: true, value: raw });
55
+ return loop.ok || isRefused(loop) ? { ok: true, raw: loop.raw } : loop;
74
56
  }
75
57
  /**
76
- * One dispatch with no validation, for a caller that parses and repairs the
77
- * reply itself (reflect's repair turn, extract's own structured loop).
58
+ * One dispatch with no validation: the loop's dispatch ({@link callStageLoop}),
59
+ * and a caller's own (reflect's repair turn carries a conversation).
78
60
  */
79
61
  export async function callStageOnce(call) {
80
62
  const messages = [
@@ -82,43 +64,19 @@ export async function callStageOnce(call) {
82
64
  ...(call.history ?? []),
83
65
  { role: "user", content: call.prompt },
84
66
  ];
85
- let failure;
86
- try {
87
- const dispatch = () => callStructured({
88
- feature: call.feature,
89
- ...(call.gate
90
- ? { akmConfig: call.gate.config, ...(call.gate.enabled !== undefined ? { enabled: call.gate.enabled } : {}) }
91
- : {}),
92
- runner: call.runner,
93
- messages,
94
- ...(call.request ? { request: call.request } : {}),
95
- ...(call.current ? { current: call.current } : {}),
96
- ...(call.onNotices ? { onNotices: call.onNotices } : {}),
97
- parse: (r) => r ?? "",
98
- onError: (_cls, err) => {
99
- failure = failedCall(err);
100
- return undefined;
101
- },
102
- fallback: undefined,
103
- onFallback: (event) => {
104
- failure ??= { ok: false, reason: event.reason, ...(event.error ? { error: event.error.message } : {}) };
105
- },
106
- });
107
- // Usage is credited to the engine that serves the call, which for a gate's own judge
108
- // (#1011) is not the stage's planned engine.
109
- const stage = currentLlmStage();
110
- const raw = await (stage === undefined
111
- ? dispatch()
112
- : withLlmStage(stage, dispatch, { engine: call.runner.engine }));
113
- return raw === undefined ? (failure ?? { ok: false, reason: "error" }) : { ok: true, raw };
114
- }
115
- catch (err) {
116
- if (err instanceof ConfigError)
117
- throw err;
118
- return failedCall(err);
119
- }
67
+ const dispatch = () => callStructured({
68
+ runner: call.runner,
69
+ messages,
70
+ ...(call.request ? { request: call.request } : {}),
71
+ ...(call.current ? { current: call.current } : {}),
72
+ ...(call.onNotices ? { onNotices: call.onNotices } : {}),
73
+ });
74
+ // Usage is credited to the connection or harness that serves the call, which for a gate's own judge
75
+ // (#1011) is not the one the stage planned.
76
+ const stage = currentLlmStage();
77
+ return stage === undefined ? dispatch() : withLlmStage(stage, dispatch, { engine: call.runner.name });
120
78
  }
121
- /** Attribute a stage's LLM calls to its process and planned engine (the usage report). */
79
+ /** Attribute a stage's LLM calls to its process and planned connection or harness (the usage report). */
122
80
  const STAGE_LABELS = {
123
81
  reflect: "reflect",
124
82
  distill: "distill",
@@ -128,7 +86,7 @@ const STAGE_LABELS = {
128
86
  validation: "validation",
129
87
  };
130
88
  export function attributeStage(plan, process, fn) {
131
- return withLlmStage(STAGE_LABELS[process], fn, { engine: plan?.processes[process].runner?.engine, process });
89
+ return withLlmStage(STAGE_LABELS[process], fn, { engine: plan?.processes[process].runner?.name, process });
132
90
  }
133
91
  /** How many prior rejected proposals are shown to the model as "don't repeat this". */
134
92
  export const MAX_REJECTED_PROPOSALS = 3;
@@ -187,31 +145,41 @@ export function stageJudgedProposal(stash, proposal, judged, proposalsCtx) {
187
145
  return proposal;
188
146
  }
189
147
  }
148
+ /** Whether `improve.qualityGate` sets where the judge runs, or only how. */
149
+ function gateNamesAJudge(gate) {
150
+ return ["connection", "harness", "model", "timeoutMs", "llm"].some((key) => Object.hasOwn(gate, key));
151
+ }
190
152
  /**
191
- * The judge a quality gate names for itself (#1011): the gate's `engine`,
192
- * `model`, `timeoutMs` and `llm` over the process's own settings, as
193
- * `processes.triage.judgment` resolves over triage. `undefined` when the gate
194
- * is off or sets none of them, so the caller keeps its own judge. The engine
195
- * may be of any kind; config validation has required one that confines the
196
- * model-work tool policy. Throws when they resolve to no engine at all,
197
- * before anything is generated: the gate never falls back to another judge.
153
+ * The judge of a process's quality gate (#1011). Its layers are the improve-wide
154
+ * `improve.connection` / `improve.harness`, then `improve.qualityGate`'s
155
+ * connection or harness, model, timeout and inference, asking for the `judge`
156
+ * alias when neither names a model. What the run selected (`--connection`,
157
+ * `--harness`, `--model`) is nearer than all of these. The process's own `improve.processes.<name>`
158
+ * settings (its `model`, `llm`, connection) are the generation call's and do not
159
+ * reach the judge, so a `reasoning` model chosen for the writer is not the one
160
+ * that judges it. `undefined` when the strategy turns the gate off or no
161
+ * connection or harness is configured, so the caller keeps its own. The judge
162
+ * may be a connection or a harness; a harness that cannot confine the
163
+ * model-work tool policy runs unrestricted, with a notice. Throws when
164
+ * `improve.qualityGate` names a judge that resolves to nothing, before anything
165
+ * is generated: the gate never falls back to another judge.
198
166
  */
199
- export function resolveQualityGateJudge(config, profile, processName, onNotices) {
200
- const process = profile?.processes?.[processName];
201
- const gate = process?.qualityGate;
202
- if (!gate || gate.enabled === false)
203
- return undefined;
204
- if (!["engine", "model", "timeoutMs", "llm"].some((key) => Object.hasOwn(gate, key)))
167
+ export function resolveQualityGateJudge(config, profile, processName, onNotices, run) {
168
+ if (profile?.processes?.[processName]?.qualityGate?.enabled === false)
205
169
  return undefined;
170
+ const gate = config.improve?.qualityGate;
206
171
  const resolved = resolveImproveExecution({
207
172
  config,
208
173
  processName: `${processName}-quality-judge`,
209
- ...(profile ? { profile } : {}),
210
- ...(process ? { process } : {}),
211
- current: gate,
174
+ alias: SHIPPED_ALIAS.judge,
175
+ ...(gate ? { current: gate } : {}),
176
+ ...(run ? { run } : {}),
212
177
  });
213
178
  if (!resolved) {
214
- throw new ConfigError(`The ${processName} quality gate's judge has no engine. Set processes.${processName}.qualityGate.engine.`, "INVALID_CONFIG_FILE");
179
+ if (gate && gateNamesAJudge(gate)) {
180
+ throw new ConfigError("The quality gate's judge has no connection or harness. Set improve.qualityGate.connection.", "INVALID_CONFIG_FILE");
181
+ }
182
+ return undefined;
215
183
  }
216
184
  onNotices?.(resolved.notices);
217
185
  return resolved.runner;
@@ -275,12 +243,13 @@ function buildChangedRegion(sourceContent, candidateContent) {
275
243
  return boundedDocument(`Removed or replaced:\n${removed || "(none)"}\n\nAdded or replacement:\n${added || "(none)"}`);
276
244
  }
277
245
  /**
278
- * What the judge may do with tools when it runs on an agent engine: verify a
246
+ * What the judge may do with tools when it runs on a harness: verify a
279
247
  * fact the revision adds or alters, and nothing else. The plain judge's prompt
280
248
  * is unchanged (its rubric is tuned and measured without this paragraph).
281
249
  */
282
- function reflectJudgeToolRules(ref) {
283
- const asset = ref ? `The asset is \`${ref}\`: read it with akm_show, ` : "Read an asset with akm_show ";
250
+ function reflectJudgeToolRules(ref, tool) {
251
+ const read = tool === "akm_show" ? "akm_show" : `\`akm show ${ref ?? "<ref>"}\``;
252
+ const asset = ref ? `The asset is \`${ref}\`: read it with ${read}, ` : `Read an asset with ${read} `;
284
253
  return `Tools: ${asset}or an asset the changed region names, only to verify a fact the revision adds or alters; the text above already shows every change. Do not search, do not read anything else, and do not use a tool to judge structure or wording. One or two reads at most. Before scoring, check two lists: (1) every statement the revision adds: find each in the asset, or as a fact the feedback states about the subject, and score QUALITY 1-2 if any is in neither; a statement is found only when the asset or the feedback says it, in any words: a new step, cause, consequence or detail that merely seems to follow is not found; feedback says what to fix and is not content, so an added statement about how the asset was used, found or verified is unsupported; (2) every fact, caveat and field of the source: find each in the revision, and score PRESERVATION 1-3 if any is missing. A read that finds nothing wrong raises no score above what these lists support. Then reply with the JSON.`;
285
254
  }
286
255
  /**
@@ -291,7 +260,7 @@ function reflectJudgeToolRules(ref) {
291
260
  const REFLECT_JUDGE_INTRO = "You are evaluating a proposed revision of an existing akm asset's frontmatter. The revision may change only the `description`, the `when_to_use` and the title (a level-1 heading added when the body has none); the body is unchanged.";
292
261
  const REFLECT_JUDGE_NEGATIVE = "This revision answers negative feedback. It cannot change the body, so it need not resolve the feedback: judge only the fields it changes, and never fault it for a field it leaves as it was. Most negative feedback says the asset did not help with a task it was retrieved for: a retrieval miss, not a defect. It justifies changing a field only when the field claims more than the body covers (narrow it to what the body covers), or when the feedback calls the asset stale, outdated, superseded or historical (a new `when_to_use` must then name the version or date the body records). Feedback about a task the asset never claims to cover justifies no change. Repairing a missing or broken field is always needed, whatever the feedback says.";
293
262
  const REFLECT_JUDGE_MAINTENANCE = "This revision is maintenance: there is no negative feedback. Only a missing or broken field needs a change; rewording a sound `description` or `when_to_use` is churn, however accurate.";
294
- /** Judge prompt for an in-place revision. `tools` is set when the judge runs on an agent engine. */
263
+ /** Judge prompt for an in-place revision. `tools` is set when the judge runs on a harness. */
295
264
  export function buildReflectJudgePrompt(candidateContent, sourceContent, feedback, tools) {
296
265
  return [
297
266
  REFLECT_JUDGE_INTRO,
@@ -323,7 +292,7 @@ export function buildReflectJudgePrompt(candidateContent, sourceContent, feedbac
323
292
  buildChangedRegion(sourceContent, candidateContent),
324
293
  "```",
325
294
  "",
326
- ...(tools ? [reflectJudgeToolRules(tools.ref), ""] : []),
295
+ ...(tools ? [reflectJudgeToolRules(tools.ref, tools.tool), ""] : []),
327
296
  'Return ONLY valid JSON, no prose: {"scores": {"need": <1-5 integer>, "preservation": <1-5 integer>, "quality": <1-5 integer>}, "reason": "<one sentence>"}',
328
297
  ].join("\n");
329
298
  }
@@ -405,7 +374,7 @@ export function judgeResponseSchema(keys) {
405
374
  */
406
375
  async function runQualityJudge(feature, config, prompt, keys, chat, options) {
407
376
  const resolved = !options.runnerSelectionFrozen && !options.llmRunner
408
- ? resolveImproveExecution({ config, processName: `${feature}-judge` })
377
+ ? resolveImproveExecution({ config, processName: `${feature}-judge`, alias: SHIPPED_ALIAS.judge })
409
378
  : null;
410
379
  if (resolved)
411
380
  options.onNotices?.(resolved.notices);
@@ -414,17 +383,17 @@ async function runQualityJudge(feature, config, prompt, keys, chat, options) {
414
383
  return {
415
384
  pass: false,
416
385
  score: -1,
417
- reason: "no engine configured — cannot judge, routed to review",
386
+ reason: "no connection or harness configured — cannot judge, routed to review",
418
387
  reviewNeeded: true,
419
388
  };
420
389
  const outcome = await callStage({
421
- feature,
422
390
  runner,
423
391
  system: "Return only valid JSON. No prose.",
424
392
  prompt,
425
393
  request: {
426
- // Off unless the judge's own engine enables thinking (a slower, separate judge engine, #1011).
427
- enableThinking: runnerLlmConnection(runner)?.enableThinking === true,
394
+ // Off unless the judge's own connection enables thinking (a slower, separate judge, #1011).
395
+ enableThinking: runner.kind === "connection" &&
396
+ thinkingSetting(effectiveRequestFields(runner.request, runner.inference)) === true,
428
397
  temperature: 0,
429
398
  responseSchema: judgeResponseSchema(keys),
430
399
  ...(Object.hasOwn(options, "timeoutMs") ? { timeoutMs: options.timeoutMs } : {}),
@@ -457,8 +426,11 @@ export function runLessonQualityJudge(config, lessonContent, sourceContent, chat
457
426
  }
458
427
  /** Judge an in-place reflect revision without new-lesson novelty criteria. */
459
428
  export function runReflectQualityJudge(config, candidateContent, sourceContent, feedback, chat, options = {}) {
460
- // A judge on an agent engine gets the tool rules; the runner is the frozen one or none.
461
- const tools = options.llmRunner && options.llmRunner.kind !== "llm" ? { ref: options.ref } : undefined;
429
+ // A judge on a harness gets the tool rules, in the spelling its harness has; the runner is the frozen one or none.
430
+ const judge = options.llmRunner;
431
+ const tools = judge && judge.kind !== "connection"
432
+ ? { ref: options.ref, tool: judge.platform === "opencode" ? "akm_show" : "akm show" }
433
+ : undefined;
462
434
  const prompt = buildReflectJudgePrompt(candidateContent, sourceContent, feedback, tools);
463
435
  return runQualityJudge("proposal_quality_gate", config, prompt, REFLECT_JUDGE_CRITERIA, chat, options);
464
436
  }
@@ -318,9 +318,9 @@ function localRefMissingRelPath(refType, refName, allRoots) {
318
318
  }
319
319
  /**
320
320
  * 0.9.0 grammar recognition: fully-qualified `bundle//conceptId` body-refs
321
- * (`BUNDLE_REF_RE`, the anchored prose form — spec §11.1 / ref-grammar decision
322
- * D-R3). The conceptId is reverse-translated to its legacy `type`/`name` via the
323
- * D-R2 static table (`typeNameFromConceptId`) so the SAME on-disk existence
321
+ * (`BUNDLE_REF_RE`, the anchored prose form). The conceptId is
322
+ * reverse-translated to its legacy `type`/`name` via the static table
323
+ * (`typeNameFromConceptId`) so the SAME on-disk existence
324
324
  * check applies; a conceptId whose leading segment names no known stash-subdir
325
325
  * is not a local asset ref and is skipped (foreign-adapter / cross-bundle prose).
326
326
  */
@@ -11,18 +11,19 @@
11
11
  *
12
12
  * Enforcement scope:
13
13
  * - `akm lint` reports findings as `dangerous-env-key` (non-blocking warn).
14
- * - `akm bundle add` BLOCKS install unless `--allow-dangerous-env-keys` is set (or, on TTY,
15
- * the user explicitly confirms at the prompt).
14
+ * - Nothing else consults this list. Installing a bundle is the trust
15
+ * decision, so `akm bundle add` and `akm bundle update` do not scan env
16
+ * files, and `akm env run` does not refuse a key. The
17
+ * `--allow-dangerous-env-keys` flag is a deprecated no-op.
16
18
  * - Local env writes do NOT consult this list — by design, the operator may
17
- * legitimately store any key locally. The gate exists only for third-party
18
- * stash installation.
19
+ * legitimately store any key locally.
19
20
  *
20
21
  * False-positive tradeoff:
21
22
  * A handful of keys (EDITOR, VISUAL, PAGER) are included because they are
22
23
  * invoked by many interactive tools and are a documented RCE vector when
23
24
  * sourced from untrusted environments. They will also flag on benign files
24
- * where the operator legitimately wants to set their editor — accept the
25
- * FP and bypass with `--allow-dangerous-env-keys` after review.
25
+ * where the operator legitimately wants to set their editor — the warning is
26
+ * advisory, so ignore it after review.
26
27
  */
27
28
  import fs from "node:fs";
28
29
  import { listKeys } from "../env/env.js";
@@ -237,7 +237,7 @@ export function diagnosticToLintIssue(diag) {
237
237
  };
238
238
  }
239
239
  /**
240
- * Lint a bundle through its OWN adapter's `validate()` (spec §12.1): the
240
+ * Lint a bundle through its OWN adapter's `validate()`: the
241
241
  * adapter never writes, so every finding lands in `flagged` — `fixed` is
242
242
  * always `false`/`"failed"` for a non-akm bundle regardless of `--fix`
243
243
  * (the CLI option is silently a no-op here, exactly as it already was for
@@ -497,7 +497,7 @@ export function lintAssetFile(ctx, subdir) {
497
497
  issues.push(...factDiagnostics(ctx.relPath, ctx.data));
498
498
  break;
499
499
  case "tasks":
500
- issues.push(...taskDiagnostics(ctx.relPath, ctx.raw, ctx.stashRoot));
500
+ issues.push(...taskDiagnostics(ctx.relPath, ctx.raw));
501
501
  break;
502
502
  case "memories":
503
503
  appendMemoryStubIssue(ctx, issues);
@@ -725,7 +725,7 @@ export async function akmLint(options = {}) {
725
725
  // cross-stash refs (e.g. referencing assets in dimm-city/agent-stash) are
726
726
  // not falsely flagged as missing-ref.
727
727
  const cfg = options.config ?? loadConfig();
728
- // 0.9.0 (spec §10.1): the primary stash is the defaultBundle's path.
728
+ // The primary stash is the defaultBundle's path.
729
729
  const stashRoot = options.dir ?? primaryBundlePath(cfg) ?? resolveStashDir();
730
730
  const sources = resolveSourceEntries(stashRoot, cfg);
731
731
  const configuredAdapter = sources.find((source) => path.resolve(source.path) === path.resolve(stashRoot))?.adapterId;
@@ -1,80 +1,120 @@
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
- import { isDeepStrictEqual } from "node:util";
5
- import { defineGroupCommand, defineJsonCommand, output } from "../cli/shared.js";
6
- import { loadConfig } from "../core/config/config.js";
7
- import { copyDefaultModelMap, loadModelMapLayers, mergedModelMapProfiles, mergeModelMapLayers, WILDCARD_ENGINE_KEY, } from "../integrations/agent/model-map.js";
8
4
  /**
9
- * Compute the effective alias table (#946): every (alias, column) pair from
10
- * the fully resolved map, labeled with where its value came from.
5
+ * `akm models` — the one place to see and change which model answers each alias
6
+ * (`fast`, `balanced`, `reasoning`, and any the user adds) on a connection.
11
7
  *
12
- * `source` compares the installed-only merge against the full (installed +
13
- * user) merge for the same pair — identical means the user file never
14
- * touched it. `via`/`engine` come from the raw overlaid-but-unresolved
15
- * profile (before `engine` indirection is expanded), so a column that
16
- * resolves through `{ engine: "local-fast" }` reports which engine it
17
- * borrowed its model from.
8
+ * akm models [--connection NAME] the picks, then what the endpoint lists
9
+ * akm models set <alias> <model> [--connection NAME] change one
10
+ *
11
+ * Connections only: a harness's alias map is `harnesses.<name>.models`, edited
12
+ * with `akm config set`.
18
13
  */
19
- function modelsListRows() {
20
- const config = loadConfig();
21
- const layers = loadModelMapLayers();
22
- const rawProfiles = mergedModelMapProfiles(layers.installed, layers.user);
23
- const defaultsOnly = mergeModelMapLayers(layers.installed, undefined, config.engines);
24
- const resolved = mergeModelMapLayers(layers.installed, layers.user, config.engines);
25
- const rows = [];
26
- for (const [alias, columns] of Object.entries(resolved.aliases)) {
27
- for (const [column, profile] of Object.entries(columns)) {
28
- // The wildcard default (#946) is an alias-wide fallback, not a real
29
- // platform column an operator would dispatch to; report it folded into
30
- // the real per-platform rows above instead of as its own row.
31
- if (column === WILDCARD_ENGINE_KEY)
32
- continue;
33
- const raw = rawProfiles[alias]?.[column];
34
- const via = raw?.engine !== undefined ? "engine" : "literal";
35
- const defaultProfile = defaultsOnly.aliases[alias]?.[column];
36
- const source = defaultProfile !== undefined && isDeepStrictEqual(defaultProfile, profile) ? "default" : "user";
37
- rows.push({
38
- alias,
39
- column,
40
- model: profile.model,
41
- ...(Object.hasOwn(profile, "inference") ? { inference: profile.inference } : {}),
42
- source,
43
- via,
44
- ...(via === "engine" && raw?.engine !== undefined ? { engine: raw.engine } : {}),
45
- });
46
- }
14
+ import { defineGroupCommand, defineJsonCommand, GLOBAL_OUTPUT_ARGS, output } from "../cli/shared.js";
15
+ import { defaultConnection, loadConfig, mutateConfig, } from "../core/config/config.js";
16
+ import { resolveApiKey } from "../core/config/credentials.js";
17
+ import { entryModel, entryWithModel } from "../core/config/model-aliases.js";
18
+ import { ConfigError, UsageError } from "../core/errors.js";
19
+ import { redactUrlCredentials } from "../core/redaction.js";
20
+ import { warn } from "../core/warn.js";
21
+ import { selectionNotConfigured } from "../integrations/agent/resolution.js";
22
+ import { listEndpointModels } from "../llm/model-list.js";
23
+ const CONNECTION_ARG = {
24
+ connection: {
25
+ type: "string",
26
+ description: "The connection to show or change (default: the default connection)",
27
+ },
28
+ };
29
+ /** The connection to show or change: the one named, else the default. */
30
+ function targetConnection(config, name) {
31
+ if (name !== undefined) {
32
+ const connection = config.connections?.[name];
33
+ if (connection)
34
+ return { name, connection };
35
+ throw selectionNotConfigured(config, "connection", name);
47
36
  }
48
- rows.sort((left, right) => left.alias === right.alias ? left.column.localeCompare(right.column) : left.alias.localeCompare(right.alias));
49
- return rows;
37
+ const found = defaultConnection(config);
38
+ if (found)
39
+ return found;
40
+ throw new ConfigError("No connection is configured, so there are no model aliases to show or change. Run `akm setup` to add one.", "LLM_NOT_CONFIGURED");
41
+ }
42
+ /** The models the connection's endpoint lists, or none when it cannot say. */
43
+ async function availableModels(name, connection, probe) {
44
+ if (!probe)
45
+ return [];
46
+ const apiKey = resolveApiKey(connection.apiKey, { connection: name }, connection.endpoint);
47
+ const listed = await listEndpointModels({ endpoint: connection.endpoint, ...(apiKey ? { apiKey } : {}) });
48
+ if (listed.ok)
49
+ return listed.models;
50
+ warn(`Could not list models from ${redactUrlCredentials(connection.endpoint)} (${listed.error}).`);
51
+ return [];
50
52
  }
51
- /** Operator-owned model-map lifecycle commands. Alias expansion is consumed through the runtime API. */
53
+ /** Probing is the default, so only the opt-out is declared; citty parses `--no-probe` as `probe: false` (see `setup`'s flag in `cli.ts`). */
54
+ const PROBE_ARG = {
55
+ "no-probe": {
56
+ type: "boolean",
57
+ description: "Do not ask the endpoint which models it lists.",
58
+ },
59
+ };
60
+ const probes = (args) => args.probe !== false;
52
61
  export const modelsCommand = defineGroupCommand({
53
- meta: { name: "models", description: "Inspect and customize model intent alias defaults" },
62
+ meta: {
63
+ name: "models",
64
+ description: "Show which model answers each alias on a connection, then the models its endpoint lists; `models set` changes one",
65
+ },
66
+ // The group runs the list itself, so it declares the output flags a leaf command would get from `defineJsonCommand`.
67
+ args: { ...GLOBAL_OUTPUT_ARGS, ...CONNECTION_ARG, ...PROBE_ARG },
68
+ // `akm models` is itself the list, so the bare group is not a usage error here.
69
+ async defaultRun({ args }) {
70
+ const { name, connection } = targetConnection(loadConfig(), args.connection);
71
+ const aliases = Object.fromEntries(Object.entries(connection.models ?? {}).map(([alias, entry]) => [alias, entryModel(entry)]));
72
+ output("models", { connection: name, aliases, available: await availableModels(name, connection, probes(args)) });
73
+ },
54
74
  subCommands: {
55
- "copy-defaults": defineJsonCommand({
75
+ set: defineJsonCommand({
56
76
  meta: {
57
- name: "copy-defaults",
58
- description: "Copy AKM's installed models.json into the user configuration directory",
77
+ name: "set",
78
+ description: "Make a model answer an alias on a connection, e.g. `akm models set reasoning glm-5`; an alias with request fields keeps them",
59
79
  },
60
80
  args: {
61
- overwrite: {
62
- type: "boolean",
63
- default: false,
64
- description: "Confirm replacing an existing regular user models.json file",
65
- },
66
- },
67
- run({ args }) {
68
- output("models", copyDefaultModelMap({ overwrite: args.overwrite === true }));
69
- },
70
- }),
71
- list: defineJsonCommand({
72
- meta: {
73
- name: "list",
74
- description: "Show the effective model intent alias table and where each mapping resolved from",
81
+ alias: { type: "positional", required: true, description: "Alias: fast, balanced, reasoning, or your own" },
82
+ model: { type: "positional", required: true, description: "The model's name on the endpoint" },
83
+ ...CONNECTION_ARG,
84
+ ...PROBE_ARG,
75
85
  },
76
- run() {
77
- output("models-list", { rows: modelsListRows() });
86
+ async run({ args }) {
87
+ const alias = args.alias.trim();
88
+ const model = args.model.trim();
89
+ if (!alias || !model) {
90
+ throw new UsageError("Name an alias and a model: `akm models set <alias> <model>`.", "MISSING_REQUIRED_ARGUMENT");
91
+ }
92
+ const { name, connection } = targetConnection(loadConfig(), args.connection);
93
+ const available = await availableModels(name, connection, probes(args));
94
+ if (available.length > 0 && !available.includes(model)) {
95
+ warn(`"${model}" is not among the models ${name} lists; setting it anyway.`);
96
+ }
97
+ const before = connection.models?.[alias];
98
+ mutateConfig((current) => {
99
+ const target = targetConnection(current, name);
100
+ const held = target.connection.models?.[alias];
101
+ return {
102
+ ...current,
103
+ connections: {
104
+ ...current.connections,
105
+ [name]: {
106
+ ...target.connection,
107
+ models: { ...target.connection.models, [alias]: entryWithModel(held, model) },
108
+ },
109
+ },
110
+ };
111
+ });
112
+ output("models-set", {
113
+ connection: name,
114
+ alias,
115
+ model,
116
+ previous: before === undefined ? null : entryModel(before),
117
+ });
78
118
  },
79
119
  }),
80
120
  },