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
@@ -117,13 +117,15 @@ Failures classified by akm emit a JSON error envelope on **stderr** before
117
117
  exiting; stdout is normally left empty:
118
118
 
119
119
  ```json
120
- {"ok": false, "error": "<message>", "hint": "<optional hint>"}
120
+ {"ok": false, "error": "<message>", "code": "<stable code>", "hint": "<optional hint>"}
121
121
  ```
122
122
 
123
- The `hint` field is present only when actionable remediation is available
124
- (e.g. a suggested flag or alternate command). Agents should check
125
- `ok === false` on the parsed stderr envelope or a non-zero exit code to
126
- detect failure. Scripts can rely on the exit code alone.
123
+ The `code` field is the stable machine-readable code of a classified akm error
124
+ (`INVALID_CONFIG_FILE`, `MISSING_REQUIRED_ARGUMENT`, ...); an unexpected
125
+ internal error has none. The `hint` field is present only when actionable
126
+ remediation is available (e.g. a suggested flag or alternate command). Agents
127
+ should check `ok === false` on the parsed stderr envelope or a non-zero exit
128
+ code to detect failure. Scripts can rely on the exit code alone.
127
129
 
128
130
  Every success envelope produced by the passthrough stamp — `config`, `clone`,
129
131
  `models`, `task-*`, `workflow-*`, `registry-*`, and the rest of that shared
@@ -179,32 +181,75 @@ hijacking your real default bundle.
179
181
 
180
182
  ### setup
181
183
 
182
- Run the interactive first-run wizard.
184
+ Run the first-run wizard.
183
185
 
184
186
  ```sh
185
187
  akm setup
186
- ```
187
-
188
- The setup wizard configures AKM in two steps:
189
-
190
- **Step 1 — Small model connection** (for background processing)
191
- Configures the OpenAI-compatible endpoint and model used for `akm improve`
192
- and `akm remember --enrich`. Supports Ollama,
193
- OpenAI, LM Studio, or any custom endpoint. Skipping disables enrichment features.
194
-
195
- **Step 2 — Agent connection** (for agentic commands)
196
- Configures how `akm improve`, `akm proposal new`, and `akm task run` dispatch AI sessions.
197
- Options:
198
- - **Same connection** — reuse the Step 1 endpoint with a (optionally different) model
199
- - **New connection** — separate endpoint, model, and API key
200
- - **Installed CLI agent** — use an installed agent binary (opencode, claude, codex, etc.)
201
- - **None** — agentic commands disabled with a clear warning
202
-
203
- A feature capability summary is shown at the end of setup.
204
-
205
- The wizard also lets you choose a bundle directory, review registries, and add bundle
206
- sources. When you save, akm writes the config file, initializes the bundle directory,
207
- and builds the search index.
188
+ akm setup --endpoint http://localhost:11434/v1 --yes # no prompts
189
+ ```
190
+
191
+ The wizard asks, in order:
192
+
193
+ 1. **Agent programs.** Which installed agent programs (Claude Code, Codex,
194
+ OpenCode, ...) akm may use; each is shown with whether akm can limit it to
195
+ reading and searching for its own model calls. With several, you pick the
196
+ default. For OpenCode, setup asks the program the harness will run (its `bin`,
197
+ else `opencode` on `PATH`) for `--version` and treats a version it cannot read
198
+ as OpenCode 1. When a harness that cannot be restricted is enabled for akm's
199
+ model calls, setup says "Model work on `<name>` cannot be restricted: it can
200
+ edit files and run commands." where you choose, and in its summary line.
201
+ 2. **Model calls.** Whether the default agent program also takes akm's own
202
+ model calls (improve, judging, extraction). It is asked only when a harness is
203
+ enabled and there is no connection yet and no `--endpoint`, because a
204
+ connection always takes model calls; answering no leads to a connection. A no
205
+ that no connection follows is saved as `modelWork: false` on that harness, so
206
+ model calls stay off (the summary says so and points at `akm setup
207
+ --endpoint`) rather than falling back to it. A `modelWork: false` already
208
+ saved is the question's default and stays through `--yes`; only a yes clears
209
+ it. With `--yes` the answer is yes only for a harness akm can limit to reading
210
+ and searching for its own model calls, and whose `modelWork: false` is not
211
+ already saved.
212
+ 3. **Connection.** An OpenAI-compatible endpoint, its API key (typed at a masked
213
+ prompt and stored in `credentials.json`, never in `config.json`), and one model
214
+ per alias (`fast`, `balanced`, `reasoning`) picked from the models the
215
+ endpoint lists. Change a pick later with `akm models set`.
216
+ 4. **Embeddings.** A model the default connection serves, akm's built-in local
217
+ embedder, another endpoint, or off. The serving connection is the default of
218
+ the config as this run will save it: a further `--name` connection does not
219
+ serve embeddings, its models are not offered, and with several connections
220
+ none called `default`, `--embedding <model>` refuses and asks you to name one
221
+ default or pass `--embedding-endpoint`.
222
+ 5. **Save.** The config is written, the bundle directory initialized, and a
223
+ summary says what runs where.
224
+
225
+ Flags answer one question each; `--yes` takes the detected default for every
226
+ question left, so nothing is prompted. Without a terminal, `akm setup` refuses
227
+ unless `--yes` or `--from` is given.
228
+
229
+ | Flag | Answers |
230
+ |---|---|
231
+ | `--endpoint <url>` | The connection to add or update (the first is named `default`) |
232
+ | `--api-key-env <NAME>` | The environment variable holding its key (`apiKey: "$NAME"`) |
233
+ | `--name <name>` | A further connection, with `--endpoint` |
234
+ | `--harness <a,b>` | Agent programs to enable; the first is the default |
235
+ | `--embedding <model\|local\|off>` | Embeddings |
236
+ | `--embedding-endpoint <url>`, `--embedding-api-key-env <NAME>` | Another endpoint serving the embedding model |
237
+ | `--from <file>` | A config file (JSON or YAML) to merge |
238
+ | `--dir <path>`, `--no-init` | The bundle directory; skip scaffolding it |
239
+ | `--no-probe` | Offline: the endpoint is not contacted and its models are not listed; a connection added this way has no model until `akm models set` names one |
240
+
241
+ The detected defaults are: when no agent program is configured yet, every one
242
+ found on `PATH` is enabled and the first found is the default. If no connection
243
+ exists, model calls go to that program when akm can limit it to reading and searching; otherwise a
244
+ local OpenAI-compatible server (Ollama on 11434, LM Studio on 1234, or a server
245
+ on 8080), when one answers, becomes the connection `default`. Each alias takes
246
+ the connection's current pick, else the first model the endpoint lists that is
247
+ not an embedding model. Embeddings turn on only for a new default connection
248
+ whose endpoint lists an embedding model.
249
+
250
+ The wizard also lets you review registries and add bundle sources. A scripted run
251
+ prints its result with a `runs` object saying what runs where: `modelCalls`,
252
+ `agentWork` and `embeddings`.
208
253
 
209
254
  ### index
210
255
 
@@ -225,7 +270,9 @@ Returns stats: `totalEntries`, `generatedMetadata`, `directoriesScanned`,
225
270
  breakdown in milliseconds. Use `--verbose` to print the indexing mode,
226
271
  semantic-search settings, and phase-by-phase progress to stderr while the
227
272
  index is being built. Malformed workflow assets are skipped with file-path
228
- warnings instead of aborting the full run.
273
+ warnings instead of aborting the full run. `verification.embeddingRuntime` is
274
+ `onnxruntime-node` when the local embedder embedded in this run; it is absent
275
+ for a remote embedding provider and when nothing was embedded locally.
229
276
 
230
277
  **Progress in non-verbose JSON mode (default output format, #954):** even
231
278
  without `--verbose`, phase-start messages and the embedding heartbeat
@@ -323,6 +370,7 @@ Returns a JSON object with:
323
370
  | `searchModes` | Active search modes (`fts`, optionally `semantic` and `hybrid`) |
324
371
  | `semanticSearch` | Semantic search status: `mode`, `status`, and optional `reason`/`message` |
325
372
  | `registries` | Configured registries |
373
+ | `connectionsAndHarnesses` | The connections, harnesses and work that runs on them, as the rows `akm health` reports under its `connections-and-harnesses` check, without contacting anything: each connection's endpoint and whether its key is held, each harness's platform and whether its binary is on `PATH`, and for each kind of work the connection or harness and model it resolves to |
326
374
  | `sourceProviders` | Configured sources (filesystem, git, website, npm) |
327
375
  | `indexStats` | Index stats: `entryCount`, `byType` (per-asset-type breakdown), `links` (declared links per kind with `total` and `unresolved`; absent when the index holds none), `lastBuiltAt`, `hasEmbeddings`, `unreadable` (index.db exists but the filesystem refuses to read it — a permissions problem), `unavailable` (index.db is readable but the SQLite-level read didn't complete: locked by another akm process, a newer layout this akm can't understand, or a corrupt file) |
328
376
 
@@ -366,14 +414,13 @@ akm health --report --window-compare 7d --format html
366
414
  | `--window-compare` | Compare the current window against the prior window of the same duration (e.g. `24h`, `7d`). With `--report`, overrides the default trend window. |
367
415
  | `--group-by` | Group rows by `run` (one row per `improve_runs` entry). Omit for the default summary. |
368
416
  | `--windows` | Explicit comparison window(s) as `name=...,since=ISO,until=ISO` (repeatable, up to 4). Mutually exclusive with `--window-compare`. |
369
- | `--no-probe` | Skip the `default-llm-engine` / `configured-engines` reachability probes, the `cli-version` update check, and the `scheduler-binary` version check (for an offline or air-gapped host). |
417
+ | `--no-probe` | Skip the `connections-and-harnesses` reachability probes and harness `--version` runs, the `cli-version` update check, the `plugin-version` newest-tag lookup, and the `scheduler-binary` version check (for an offline or air-gapped host). |
370
418
 
371
419
  The command reads `state.db`, verifies that the required tables exist, performs a
372
420
  write-read probe against the events stream, inspects `task_history`, checks the
373
- default agent engine, and summarizes recent `improve_*` events. Unless
421
+ configured connections and harnesses (the `connections-and-harnesses` table), and summarizes recent `improve_*` events. Unless
374
422
  `--no-probe` is given, it also sends a bounded (3s timeout) reachability probe
375
- to the `default-llm-engine` and every `configured-engines` LLM connection (and
376
- an SDK engine's LLM fallback), one probe per distinct endpoint, checks the
423
+ to each connection's endpoint, one probe per distinct endpoint, checks the
377
424
  installed akm-cli version against the latest GitHub release (`cli-version`),
378
425
  runs the scheduler's recorded akm binary with `--version` to check it
379
426
  against the running CLI (`scheduler-binary`).
@@ -383,8 +430,8 @@ Primary result fields:
383
430
  | Field | Description |
384
431
  | --- | --- |
385
432
  | `status` | Overall health verdict: `pass`, `warn`, or `fail` |
386
- | `hardChecks` | Deterministic checks such as `state-db-schema`, `state-db-round-trip`, `state-db-integrity`, `state-db-migrations`, `active-runs`, `default-engine`, `model-map-files`, `default-llm-engine`, `configured-engines`, and `active-improve-strategy` |
387
- | `advisories` | Non-fatal warnings including `semantic-search-runtime`, `session-extraction` (akmExtract pipeline health), `cli-version` (installed vs latest release), `thinking-control` (an `enableThinking: false` engine whose recorded usage still shows reasoning tokens), and `engine-last-used` (an engine bound to an enabled improve process with no recorded use in 30 days) |
433
+ | `hardChecks` | Deterministic checks such as `state-db-schema`, `state-db-round-trip`, `state-db-integrity`, `state-db-migrations`, `active-runs`, `connections-and-harnesses`, and `semantic-search` |
434
+ | `advisories` | Non-fatal warnings including `session-extraction` (akmExtract pipeline health), `cli-version` (installed vs latest release), and `scheduler-binary` |
388
435
  | `metrics` | Aggregate task/runtime metrics: `taskFailRate`, `agentFailureRate`, `stuckActiveRuns` |
389
436
  | `improve` | Recent improve-loop counts derived from `improve_invoked`, `improve_skipped`, and `improve_completed` events |
390
437
 
@@ -401,36 +448,50 @@ It `fail`s only when a pending migration could not be applied — naming it and
401
448
  pointing at `akm migrate apply` — rather than the command crashing. Read this
402
449
  check's `status` instead of grepping akm's error text.
403
450
 
404
- `default-llm-engine` and `configured-engines` probe reachability (not just
405
- configuration) for a `kind: "llm"` engine — an unreachable endpoint is a hard
406
- `fail` for `default-llm-engine` and a `warn` for any other engine. `--no-probe`
407
- skips this. When a required credential is missing from the shell but an
408
- `env/` asset defines the same variable name, the warn names that asset's ref
409
- (never the variable name) and points at `akm env run <ref> -- ...`.
410
- `active-improve-strategy` names the resolved engine per process
411
- in its evidence and message, so a strategy-level `engine` pin that shadows
412
- `defaults.llmEngine` is visible without config archaeology.
451
+ `connections-and-harnesses` is one table: a row for each configured connection (endpoint, whether
452
+ its key is held, whether the endpoint answers) and harness (platform, whether
453
+ its binary is found, and with a probe its `--version`), then a row for each kind of work
454
+ (`improve`, `judges`, `agents`, `extract`, `enrich`, `index`, `embedding`,
455
+ `curate-rerank`) naming the connection or harness and the model it resolves to.
456
+ The rows are in `evidence.rows`, each typed `connection`, `harness` or `process`;
457
+ the text format always prints them. It is a `warn` when a key variable is unset,
458
+ an endpoint does not answer (the probes, and the harness `--version` runs, are skipped by `--no-probe`), a harness is not
459
+ installed, or the config leaves a kind of work unresolvable, and `unknown` when
460
+ nothing is configured.
461
+
462
+ `semantic-search` reports what the last `akm index` recorded about semantic
463
+ search, with the index's entry and vector counts read now. It loads no model and
464
+ sends no request. It `pass`es when every entry has a vector (and a local model
465
+ embedded on `onnxruntime-node`) or `semanticSearchMode` is `off`; `warn`s when
466
+ vectors lag the entries (`akm index` embeds the rest), local embeddings ran on
467
+ another runtime, or this platform has no native ONNX Runtime library
468
+ (Alpine/musl, Intel macOS: keyword search is all there is, so the message says to
469
+ set `semanticSearchMode` to `off` or `embedding.endpoint` to a remote service);
470
+ `fail`s, with the recorded reason, when the last index found semantic search
471
+ `blocked` (an embedding endpoint or model download failed) or `unavailable` for
472
+ a cause that can be fixed (the library is there but did not load: a missing
473
+ package or addon, a `noexec` temp or cache directory); and is `unknown` before
474
+ the first index. Search never reads this record: a query still
475
+ tries semantic search and falls back to keyword search on its own. A fix shows
476
+ here after the next `akm index`. `evidence` carries the recorded `status`,
477
+ `unavailable` (`platform` or `load`), `provider`, `runtime`, `reason`, the index's `builtAt`, `entryCount` and
478
+ `embeddingCount`. `akm health --report --format html` shows it as the Semantic
479
+ Search line: `OK`, `OFF`, `BLOCKED`, `UNAVAILABLE` or `UNKNOWN`.
413
480
 
414
481
  `cli-version` compares the installed akm-cli version against the latest
415
482
  GitHub release — the same source `akm upgrade` trusts — and `warn`s with the
416
483
  upgrade command when a newer release exists. `--no-probe`, offline, or a
417
484
  rate-limited request all degrade it to `unknown`, never a false `warn`.
418
485
 
419
- `engine-last-used` checks, for every engine bound to an enabled process in
420
- the active improve strategy, whether it has a recorded `llm_usage` call in
421
- the last 30 days (independent of `--since`). It `warn`s naming the idle
422
- engine and its bound process, and stays `unknown` — not a noisy `warn` —
423
- until at least one improve run has been recorded (started) in that window,
424
- so a fresh install is quiet.
425
-
426
486
  The `session-extraction` advisory is derived from the `extract_sessions_seen`
427
487
  ledger for the last 7 days — not `improve_runs`, which the hook-driven `akm
428
488
  proposal extract --session-id ...` invocation never writes. It reports
429
489
  `unknown` when nothing was recorded in the window (cannot tell "off on
430
490
  purpose" from "broken"), `warn` when every session in the window was skipped
431
491
  for an infrastructure reason (`llm_unavailable`, `read_failed`, `exception`,
432
- `locked_concurrent`) — naming the reason and, when recorded, the engine — and
433
- `pass` otherwise, with per-outcome counts.
492
+ `locked_concurrent`) — naming the reason and, when recorded, the connection or
493
+ harness it ran on, as `engine "<name>"` — and `pass` otherwise, with
494
+ per-outcome counts.
434
495
 
435
496
  ### metrics
436
497
 
@@ -468,7 +529,7 @@ Result sections (`schemaVersion: 1`):
468
529
  | `feedback` | Positive and negative totals, per-asset valence, per-tag counts, and the most recent negatives with their reasons |
469
530
  | `utility` | A ten-bucket histogram of `utility_scores`, the lowest and highest assets, and how many indexed entries were never used |
470
531
  | `outcomes` | The assets with the lowest `outcome_score` |
471
- | `llm` | `akm health`'s LLM usage aggregate (by stage, process and engine) |
532
+ | `llm` | `akm health`'s LLM usage aggregate (`byStage`, `byProcess`, and `byEngine`, keyed by the name of the connection or harness) |
472
533
  | `index`, `tasks`, `proposals`, `workflows` | Index runs and median time, task runs and fail rate, proposals by status and accept rate by source, workflow runs and tokens by model |
473
534
  | `rows` | The raw usage and LLM rows of the window; see below |
474
535
  | `notes` | Anything that limits what the numbers mean |
@@ -504,7 +565,7 @@ the matching CLI commands use, so the UI and the CLI report the same numbers.
504
565
  | --- | --- |
505
566
  | Overview | Overall health, failing and warning check counts and the akm version; the health checks grouped by status with expandable evidence; metrics tiles; the last 10 improve runs (result, duration, model calls and failures, sync, triage) with bars; and a 14-day stacked usage chart (search, curate, show, feedback). |
506
567
  | Bundles | Cards including disabled bundles, source, component writability, settings origin, Git and index state. Explicit add, update, confirmed removal, enabled/writable settings and default-bundle/write-target controls use existing AKM operations. |
507
- | Config | The effective config as a collapsible tree with a `default` / `file` / `extends:<ref>` source badge on every key, the engines table and the `AKM_*` environment. |
568
+ | Config | The effective config as a collapsible tree with a `default` / `file` / `extends:<ref>` source badge on every key, the connections and harnesses tables and the `AKM_*` environment. |
508
569
  | Proposals | The pending queue grouped by source (filter by source) with age and gate decision, a Recent tab of accepted, rejected and reverted proposals with reasons, and a detail page with the unified diff and, for retirements, the pair judgment. The detail page has Accept (after an inline confirmation) and Reject (with a required reason); the pending list has checkboxes and an Accept selected bar that accepts several in one commit. |
509
570
  | Changes | Recent stash commits as a timeline by day, each tagged by origin (`improve-sync`, `accept`, `remember`, `sync`, `other`) with its changed paths. |
510
571
  | Search | Search or browse the existing index grouped by path, with type/bundle, current/all/historical and user/agent/run/channel scope controls. Asset detail includes safe Markdown tables/tasks, indexed relative links, heading navigation, source, per-file Git history/diffs and explicit feedback with reasons/tags. New knowledge supports Markdown source and preview through `akm import`, without overwriting existing files. |
@@ -617,7 +678,6 @@ kept.
617
678
  | `--type` | `skill`, `command`, `agent`, `knowledge`, `instruction`, `workflow`, `script`, `memory`, `env`, `secret`, `lesson`, `task`, `session`, `fact`, `any` | `any` | Filter by asset type. Free-form and unvalidated — an unknown type returns no hits. Also accepts any adapter-defined type (e.g. `website`) — see [Bundle Types](bundle-types.md) for the open types each adapter emits. |
618
679
  | `--limit` | number | `20` | Maximum results |
619
680
  | `--from` | `local`, `registry`, `all` | `local` | Where to search |
620
- | `--assets` | flag | `false` | Include asset-level registry results (only meaningful with `--from registry\|all`; folds in the retired `akm registry search --assets`) |
621
681
  | `--filter` | `<key>=<value>` | _(none)_ | Scope filter — repeatable. Valid keys: `user`, `agent`, `run`, `channel`. Example: `--filter user=alice --filter channel=ops`. Narrows the result set; ranking is unchanged. |
622
682
  | `--include-proposed` | flag | `false` | Include entries with `quality: "proposed"` in the result set. Default search excludes them; `generated` and `curated` quality entries are always included. Unknown quality values warn once and remain searchable. |
623
683
  | `--belief` | `all`, `current`, `historical` | `current` | Belief filter on any asset. `current` keeps unflagged/active/asserted assets; `historical` keeps deprecated/contradicted/superseded/archived assets. Labels do not establish truth. |
@@ -654,7 +714,7 @@ assembled into the shape registry by the `src/output/shapes.ts` barrel:
654
714
  | Level | Local bundle hits | Registry hits |
655
715
  | --- | --- | --- |
656
716
  | `brief` (default) | `type`, `name`, `ref`, `action`, `estimatedTokens` | `name`, `installRef`, `score` |
657
- | `normal` | `type`, `name`, `description`, `action`, `score`, `estimatedTokens`, optional `warnings`/`quality`/`keys` | `name`, `description`, `action`, `installRef`, `score`, optional `warnings` |
717
+ | `normal` | `type`, `name`, `ref`, `description`, `action`, `score`, `estimatedTokens`, optional `warnings`/`quality`/`keys` | `name`, `description`, `action`, `installRef`, `score`, optional `warnings` |
658
718
  | `full` | full hit object (includes `ref`, `origin`, `tags`, `whyMatched`, optional `warnings`, optional `quality`, timings, bundle metadata) | full hit object |
659
719
  | `agent` | `name`, `ref`, `type`, `path`, `editable`, conditional `editHint`, `description`, `action`, `score`, optional `estimatedTokens`/`keys` | no local access fields |
660
720
 
@@ -874,7 +934,7 @@ Returns type-specific payloads:
874
934
  | command | `template`, `description` |
875
935
  | agent | `prompt`, `description`, `modelHint` |
876
936
  | knowledge | `content` — the whole document, or one section via `#fragment` |
877
- | workflow | `workflowTitle`, `workflowParameters`, `steps` (each step's `orchestration` summary names its engine/model, or — for an [exec step](https://github.com/itlackey/akm/blob/main/docs/reference/workflow-schema.md#what-akm-show-reports-for-an-exec-step) — its `exec.command` and no engine at all) |
937
+ | workflow | `workflowTitle`, `workflowParameters`, `steps` (each step's `orchestration` summary names its `engine` (the connection or harness it runs on) and model, or — for an [exec step](https://github.com/itlackey/akm/blob/main/docs/reference/workflow-schema.md#what-akm-show-reports-for-an-exec-step) — its `exec.command` and no engine at all) |
878
938
  | memory | `content` |
879
939
  | env | `keys` (key names only — values and comment text never returned) |
880
940
  | lesson | `content` plus `when_to_use` surfaced from frontmatter |
@@ -898,17 +958,15 @@ Author, inspect, and execute structured workflow assets.
898
958
  akm workflow create ship-release --print
899
959
  akm workflow create ship-release
900
960
  akm workflow create ship-release --from ./ship-release.md
901
- akm workflow run workflows/ship-release --version 1.2.3
961
+ akm workflow run workflows/ship-release --version 1.2.3 # always starts a new run
902
962
  akm workflow run <run-id> # continue an active partial run
903
- akm workflow run workflows/ship-release --new # start a fresh run even if one is already active
904
963
  akm workflow status <run-id>
905
964
  akm workflow status workflows/ship-release
906
965
  akm workflow status 7c115132 # 8+ char run-id prefix also works
907
- akm workflow resume <run-id>
966
+ akm workflow resume <run-id> # re-activate a blocked or failed run, then run <run-id>
908
967
  akm workflow abandon <run-id>
909
968
  akm workflow list --active
910
969
  akm workflow list --children # also list child workflow runs (Experimental)
911
- akm workflow list --all-scopes # include runs started from a different working directory
912
970
  akm workflow plan workflows/ship-release # compile+freeze preview, zero writes
913
971
  ```
914
972
 
@@ -920,10 +978,10 @@ Subcommands:
920
978
  | Subcommand | Description |
921
979
  | --- | --- |
922
980
  | `create <name>` | Validate and write a Markdown workflow under `workflows/`. `--path <dir>` places it in a subdirectory; `--from <file>` imports content; `--force` overwrites; `--print` prints the template that would be written instead of writing it |
923
- | `run <run-id\|ref>` | Canonical start/resume/execute command. A ref starts a run or resumes the active run in the current scope (announced as `resumed: true`, see below); a run id continues that exact active run. `--new` starts a fresh run even when one is already active. Executes until completion, failure, verification rejection, interruption, or an explicit limit |
924
- | `status <run-id\|ref>` | Show the full run state, including all step statuses. `--units` also lists per-unit rows from the run journal (diagnostics only). Renders a `children:` tree when the run composes child workflows. `--all-scopes` widens the ref-fallthrough lookup (only reached when the target does not resolve to a run id) to every scope instead of just the current one |
925
- | `list` | List workflow runs (optionally filtered by `--ref`; `--active` shows only `status=active` runs, excluding `blocked`/`failed`/`completed`). Child workflow runs (the Experimental `unit: { workflow: … }` step) are excluded unless `--children` is passed. `--all-scopes` searches every scope instead of only the current one (#942) |
926
- | `resume <run-id>` | Flip a `blocked` or `failed` run back to `active`. Completed runs cannot be resumed |
981
+ | `run <run-id\|ref>` | Canonical start/execute command. A ref always starts a new run (other active runs of the ref produce one warning, see below); a run id continues that exact active run. Executes until completion, failure, verification rejection, interruption, or an explicit limit |
982
+ | `status <run-id\|ref>` | Show the full run state, including all step statuses. `--units` also lists per-unit rows from the run journal (diagnostics only). Renders a `children:` tree when the run composes child workflows. A ref shows its most recently updated run. `--all-scopes` is a deprecated no-op |
983
+ | `list` | List workflow runs (optionally filtered by `--ref`; `--active` shows only `status=active` runs, excluding `blocked`/`failed`/`completed`). Child workflow runs (the Experimental `unit: { workflow: … }` step) are excluded unless `--children` is passed. Lists every run on the host, most recently updated first, from any working directory. `--all-scopes` is a deprecated no-op |
984
+ | `resume <run-id>` | Flip a `blocked` or `failed` run back to `active` so `run <run-id>` can continue it; it executes nothing. Completed runs cannot be resumed |
927
985
  | `abandon <run-id>` | Mark a run failed so it stops counting as active (`resume` can reopen it) |
928
986
  | `plan <ref>` | **Evolving.** Compile and freeze a workflow WITHOUT publishing a run: the canonical step graph, per-step frozen target kinds, task/child expansion, input bindings, source read set, and lowering notices — zero durable writes. Returns the full JSON envelope by default, like every other command; pass `--format text` for a human-readable summary |
929
987
 
@@ -968,8 +1026,9 @@ Schema before persisting the run:
968
1026
 
969
1027
  A bare boolean flag means `true`. Hyphen/underscore aliases are not inferred:
970
1028
  declared `include_processes` requires `--include_processes`, not
971
- `--include-processes`. Parameters can be supplied only when a new run is
972
- created; a later invocation against an active run rejects parameter flags.
1029
+ `--include-processes`. Parameters are accepted on every ref start (a ref
1030
+ always starts a new run); passing them with a run id is rejected, because that
1031
+ run already has its parameters.
973
1032
  The old `--params <json>` bag is removed.
974
1033
 
975
1034
  | Flag | Description |
@@ -977,15 +1036,16 @@ The old `--params <json>` bag is removed.
977
1036
  | `--max-steps <n>` | Stop once this many steps have finished, leaving a partial run active. Must be at least 1. |
978
1037
  | `--max-retries <n>` | When a step fails, reopen the same run and retry the failed step up to this many additional times. Range: 0 through 100; default 0. Gate rejection and interruption are not retried. |
979
1038
  | `--timeout <duration>` | Abort the whole invocation after `N`, `Nms`, `Ns`, or `Nm`; bare `N` is milliseconds. The active step remains resumable. |
980
- | `--new` | Start a fresh run even when one is already active for this ref, instead of resuming it. The existing active run is left untouched — it is never abandoned automatically. A workflow ref only: passing a run id with `--new` is a usage error (exit 2). Parameter flags are allowed together with `--new`, since it is starting a new run. |
981
- | `--skip-if-locked` | If another akm process is already driving this run (it holds the run's lock file: `RUN_LEASE_HELD`), or `state.db` is busy with another writer (`STATE_DB_CONTENDED`), skip gracefully (exit 0) instead of failing (exit 75, `TransientError`). The envelope reports `{ skipped: { reason: "lock-held" \| "state-db-contended", message } }`. Every other failure (a bad flag, an unresolvable target) still fails loudly regardless of this flag. Use for high-frequency scheduled runs so they don't pile up failures while a longer-running invocation is in progress — same family as `improve --skip-if-locked`. |
1039
+ | `--new` | Deprecated, no effect (accepted through 0.10): a workflow ref always starts a new run. |
1040
+ | `--skip-if-locked` | If another akm process is already driving this run (it holds the run's lock file: `RUN_LEASE_HELD`), when starting a ref an active run of that ref is held by a live process, or `state.db` is busy with another writer (`STATE_DB_CONTENDED`), skip gracefully (exit 0) instead of failing (exit 75, `TransientError`). The envelope reports `{ skipped: { reason: "lock-held" \| "state-db-contended", message } }`. Every other failure (a bad flag, an unresolvable target) still fails loudly regardless of this flag. Use for high-frequency scheduled runs so they don't pile up failures while a longer-running invocation is in progress — same family as `improve --skip-if-locked`. |
982
1041
 
983
- **Resuming an active run is announced, not silent.** Passing a ref that
984
- already has an active run in the current scope resumes that run rather than
985
- starting a new one (unchanged since #485) — but the envelope now carries
986
- `resumed: true` alongside the resumed run's `run.id`, and the default text
987
- output leads with `resuming existing run <id> for <ref>; pass --new to start
988
- a fresh run`. Pass `--new` to start a second, independent run instead.
1042
+ **A ref always starts a new run.** `workflow run <ref>` never resumes: use
1043
+ `workflow run <run-id>` to continue a run and `workflow resume <run-id>` to
1044
+ reopen a blocked or failed one so `run <run-id>` can continue it. When other
1045
+ runs of the same ref are still active, the start prints one warning naming
1046
+ their ids and the `akm workflow run <id>` / `akm workflow abandon <id>`
1047
+ commands, and starts anyway. `--skip-if-locked` is the guard for scheduled callers: it skips (exit
1048
+ 0) instead of starting when an active run of the ref is held by a live process.
989
1049
 
990
1050
  The result includes the current `run`, an `executed` step report list, a
991
1051
  `stepsProcessed` count of the steps that finished, and optional `done`,
@@ -1012,20 +1072,16 @@ budget is left. `gate.max_loops` (1–100) is the per-step ceiling;
1012
1072
  from the unit journal so they hold across resumes.
1013
1073
 
1014
1074
  `run` is Experimental and does not consult `experimental.workflowEngine`. Every
1015
- non-empty `### gate` requires `workflow.judgeEngine` to name a configured LLM
1016
- or agent engine before a new run can be frozen. Gate evaluation is fail-closed.
1075
+ non-empty `### gate` needs a connection or a harness to judge it before a new
1076
+ run can be frozen (the judge runs where model work runs; see
1077
+ [Configuration](configuration.md#where-each-process-runs)). Gate evaluation is
1078
+ fail-closed.
1017
1079
 
1018
- Workflow runs are scoped to the current working context, not globally across all
1019
- repos or directories. akm resolves that context from the nearest `.akm/config.json`
1020
- ancestor when present, otherwise the nearest git root, otherwise the bundle root
1021
- when the cwd is inside it, otherwise the cwd itself. In practice this means:
1022
-
1023
- - `workflow run workflows/<name>` resumes the active run for the current project/worktree/directory (announced with `resumed: true`), or starts one when none is active. `--new` always starts a fresh run.
1024
- - `workflow status workflows/<name>` resolves the most-recently-updated run in the current scope only, unless `--all-scopes` is passed.
1025
- - `workflow list` shows runs for the current scope only, unless `--all-scopes` is passed. Its envelope always carries a top-level `scopeKey` naming the scope that was searched (`null` under `--all-scopes`), so an empty `runs: []` is never indistinguishable from "nothing anywhere".
1026
- - Direct run-id commands like `workflow status <run-id>`, `workflow resume <run-id>`, and `workflow abandon <run-id>` still work even if the run was started from another directory.
1027
- - A scheduled task runs from the scheduler's cwd, so its runs sit in a different scope from your shell's: find the run id with `akm task history <task-id> --limit 1` (`detail.runId`), then run `akm workflow status <run-id>` from any directory, or use `workflow list --all-scopes`.
1028
- - Starting a ref by name (`workflow run workflows/<name>`) never collides across scopes — each scope can hold its own active run of the same ref — but if an active run of that ref exists in a *different* scope, the started run's envelope carries a `warnings[]` entry naming that run's id, scope, and start time, with the `akm workflow run <id>` / `akm workflow abandon <id>` remedy, so a stray run in another scope does not go unnoticed (#942).
1080
+ Workflow runs are identified by run id, and workflows by ref; neither depends
1081
+ on the working directory. `workflow list` and `workflow status workflows/<name>`
1082
+ see every run on the host, from any directory, so the runs of a scheduled task
1083
+ (which runs from the scheduler's cwd) appear exactly as runs started from your
1084
+ shell do. `akm show` reports no run state; it belongs under `akm workflow`.
1029
1085
 
1030
1086
  #### workflow create
1031
1087
 
@@ -1061,17 +1117,18 @@ affect the in-flight run.
1061
1117
  akm workflow status <run-id>
1062
1118
  akm workflow status workflows/ship-release
1063
1119
  akm workflow status <run-id> --units # also list per-unit rows from the run journal
1064
- akm workflow status workflows/ship-release --all-scopes # resolve across every scope, not just the current one
1065
1120
  ```
1066
1121
 
1067
1122
  Accepts a run id, a unique 8+ character run-id prefix, or a workflow ref.
1068
1123
  When given a workflow ref, resolves to the most-recently-updated run for that
1069
- ref in the current working scope, unless `--all-scopes` is passed (only
1070
- relevant when the target does not resolve to a run id; a run id is always
1071
- scope-agnostic, `--all-scopes` or not, #942). `--units` adds per-unit rows
1124
+ ref on this host. `--all-scopes` is a deprecated no-op. `--units` adds per-unit rows
1072
1125
  (unit id, status, failure reason, and any result/error diagnostic text) from
1073
1126
  the run journal — diagnostics only; step evidence stays deterministic and is
1074
- unaffected.
1127
+ unaffected. A failed unit's row also carries an `orchestration` object (in
1128
+ text, `argv:`, `cwd:`, `env:` and `ref:` lines): the step's argv, cwd and env
1129
+ refs from the frozen plan, and the bundle-qualified ref each `${ref}` token,
1130
+ env ref and child workflow resolves to right now (`not found` when no bundle
1131
+ owns it).
1075
1132
 
1076
1133
  #### workflow plan
1077
1134
 
@@ -1093,8 +1150,7 @@ a run, or to inspect a workflow's shape without side effects.
1093
1150
 
1094
1151
  Two output modes:
1095
1152
 
1096
- - **No `--format`** (the default for this command only — every other verb
1097
- defaults to JSON): a human-readable text summary.
1153
+ - **`--format text`**: a human-readable text summary.
1098
1154
  - **`--format json`**: the full envelope — `ok`, `ref`, `title`,
1099
1155
  `sourceFormat`, `sourcePath`, `irVersion`, `planHash`, `published` (always
1100
1156
  `false`, so a consumer can never mistake this for a run envelope),
@@ -1110,7 +1166,7 @@ Text-mode example:
1110
1166
  ```
1111
1167
  workflow: team//workflows/release (markdown)
1112
1168
  source: workflows/release.md
1113
- plan: irVersion 5, hash 4f2ba91c3d0e… (not published)
1169
+ plan: irVersion 8, hash 4f2ba91c3d0e… (not published)
1114
1170
  limits: maxConcurrency 4; budget max_units 50, max_tokens 100000
1115
1171
  params: channel, version
1116
1172
  steps:
@@ -1126,14 +1182,23 @@ read set:
1126
1182
  workflows/release-checklist.md
1127
1183
  ```
1128
1184
 
1185
+ Each step also lists what it will run and what that names, from the same
1186
+ projection `akm show` prints: `argv:` (JSON, so word boundaries survive),
1187
+ `cwd:`, `env:` and one `ref:` line per `${ref}` token in the argv or cwd, per
1188
+ `env:` entry and per child `workflow:`, in the form `ref: ${team//scripts/x.ts}
1189
+ -> team//scripts/x.ts (argv)`. In JSON this is each step's `orchestration`
1190
+ object, with `refs[]` (`ref`, `resolved`, `in`). A ref no bundle owns fails the
1191
+ plan with an error that names it. The resolved ref is a name, never a value or
1192
+ a path.
1193
+
1129
1194
  **Secret-free by construction.** Neither mode ever prints a resolved
1130
1195
  reference value (references resolve at pre-attempt, not here), request
1131
1196
  content (`request.command.content`, `request.persona`, `request.conversation`,
1132
1197
  `request.runtime.environment`), a script's `bytesBase64`, or any credential —
1133
1198
  only binding *shapes* (`inputBindings[].name`/`.kind`, a literal's `.value`,
1134
1199
  a reference's `.from`), environment binding *names* (`environment[].kind`/
1135
- `.name`, an `env-ref`'s `.ref`/`.keys`/`.secretNames`), and engine *names*
1136
- (`gate.judgeEngine`).
1200
+ `.name`, an `env-ref`'s `.ref`), and connection and harness *names*
1201
+ (`orchestration.engine`, `gate.judgeEngine`).
1137
1202
 
1138
1203
  #### workflow resume
1139
1204
 
@@ -1141,8 +1206,9 @@ a reference's `.from`), environment binding *names* (`environment[].kind`/
1141
1206
  akm workflow resume <run-id>
1142
1207
  ```
1143
1208
 
1144
- Flips a `blocked` or `failed` run back to `active`. Completed runs cannot be
1145
- resumed. Use `workflow list` to find runs by status.
1209
+ Flips a `blocked` or `failed` run back to `active`; it does not execute
1210
+ anything. Run `akm workflow run <run-id>` afterwards to continue it. Completed
1211
+ runs cannot be resumed. Use `workflow list` to find runs by status.
1146
1212
 
1147
1213
  Workflow markdown contract:
1148
1214
 
@@ -1198,9 +1264,10 @@ akm bundle add https://docs.example.com --max-pages 100 --max-depth 5
1198
1264
  | `--writable` | Mark a git source as writable so `akm sync` also pushes (default: false) |
1199
1265
  | `--options` | Provider options as JSON (e.g. `'{"ref":"main"}'`) |
1200
1266
  | `--allow-insecure-transport` | Allow a plain-HTTP source URL after explicitly accepting transport substitution risk |
1201
- | `--allow-dangerous-env-keys` | Allow reviewed process-hijacking env keys in the installed bundle; does not permit plain HTTP |
1267
+ | `--allow-dangerous-env-keys` | Deprecated, no effect. `bundle add` no longer scans env files for process-hijacking keys. Accepted through 0.10 so existing scripts keep working. |
1202
1268
  | `--max-pages` | Maximum pages to crawl for website sources (default: 50) |
1203
1269
  | `--max-depth` | Maximum crawl depth for website sources (default: 3) |
1270
+ | `--credential` | Git HTTPS bearer credential, stored as a reference and never a literal token: `$VAR`, `${VAR}`, or an akm ref such as `${secrets/gitea_token}` (`${team//secrets/gitea_token}` for a secret in another bundle). Resolved only when git runs |
1204
1271
 
1205
1272
  To index only a subdirectory of a git bundle, set the component `root` after
1206
1273
  adding it:
@@ -1214,16 +1281,18 @@ akm bundle update <name>
1214
1281
  `root` is relative to the detected stash root of the checkout, not always the
1215
1282
  repo root, and takes effect on the next `bundle update` or `akm index`.
1216
1283
 
1217
- #### Dangerous env key audit
1284
+ #### Env files and process-hijacking keys
1285
+
1286
+ Installing a bundle is the trust decision. `akm bundle add` and `akm bundle
1287
+ update` do not scan a bundle's `env/` files, never prompt, and never roll an
1288
+ install back over the keys an env file sets, so a bundle whose `env/*.env` sets
1289
+ `PATH` installs and refreshes unattended with no flag. `akm env run`, `akm
1290
+ secret run` and workflow `env:` bindings inject what the bundle defines.
1218
1291
 
1219
- When `akm bundle add` installs a bundle that contains env files, it recursively scans
1220
- every `.env`-suffixed file under `env/` (the same "real env file" test used
1221
- everywhere else — a bare `.env` or any name ending `.env`, at any depth) for
1222
- environment variable names that can be used for process-execution hijacking. A
1223
- non-`.env` file under `env/` (e.g. `env/notes.txt`) is never scanned — such a
1224
- file is never sourced as environment variables by any akm codepath, so a
1225
- dangerous key sitting in its contents cannot hijack anything. The flagged key
1226
- set is 41 literal names plus 2 regex pattern families (`src/commands/lint/env-key-rules.ts`):
1292
+ `akm lint` still reports env keys that can hijack a process
1293
+ (`dangerous-env-key`, non-blocking), for bundle authors who want to review their
1294
+ own files. The flagged key set is 41 literal names plus 2 regex pattern families
1295
+ (`src/commands/lint/env-key-rules.ts`):
1227
1296
  `LD_PRELOAD`, `LD_LIBRARY_PATH`, `LD_AUDIT`, `LD_DEBUG`, `LD_BIND_NOW`,
1228
1297
  `LD_PROFILE`, `LD_ASSUME_KERNEL`, `LD_TRACE_LOADED_OBJECTS`,
1229
1298
  `DYLD_INSERT_LIBRARIES`, `DYLD_LIBRARY_PATH`, `DYLD_FRAMEWORK_PATH`, `PATH`,
@@ -1233,21 +1302,7 @@ set is 41 literal names plus 2 regex pattern families (`src/commands/lint/env-ke
1233
1302
  `RUBYOPT`, `PERL5LIB`, `PERL5OPT`, `JAVA_TOOL_OPTIONS`, `JDK_JAVA_OPTIONS`,
1234
1303
  `_JAVA_OPTIONS`, `GIT_SSH_COMMAND`, `GIT_EXTERNAL_DIFF`, `GIT_PAGER`,
1235
1304
  `GIT_EDITOR`, `EDITOR`, `VISUAL`, and `PAGER` (41 literals), plus any key
1236
- matching `^BASH_FUNC_` (Shellshock-class injection) or `^GIT_CONFIG_` (git
1237
- config override injection).
1238
-
1239
- When dangerous keys are found, `akm bundle add` pauses and prompts for
1240
- confirmation (default: No). In non-interactive mode (CI, scripts) the
1241
- install fails with **exit 1** unless `--allow-dangerous-env-keys` is passed, and the
1242
- freshly-installed bundle is rolled back before the process exits.
1243
-
1244
- ```sh
1245
- # Interactive: prompts before continuing
1246
- akm bundle add github:owner/repo-with-sensitive-env
1247
-
1248
- # Non-interactive: fails unless bypassed
1249
- akm bundle add github:owner/repo-with-sensitive-env --allow-dangerous-env-keys
1250
- ```
1305
+ matching `^BASH_FUNC_` or `^GIT_CONFIG_`.
1251
1306
 
1252
1307
  Bundle publishers: see the [Author Bundles guide](https://github.com/itlackey/akm/blob/main/docs/guides/author-bundles.md#env-security)
1253
1308
  for guidance on env files that legitimately need these keys.
@@ -1263,8 +1318,9 @@ akm bundle add https://www.agentic-patterns.com/ --name agent-patterns
1263
1318
  akm bundle add https://docs.example.com/guide --name guide --max-pages 200
1264
1319
  ```
1265
1320
 
1266
- Pages are cached locally and refreshed every 12 hours. The crawl stays within
1267
- the same origin (hostname) and skips static assets (images, CSS, JS, etc.).
1321
+ Pages are cached locally when the bundle is added and re-crawled only by
1322
+ `akm bundle update`. The crawl stays within the same origin (hostname) and
1323
+ skips static assets (images, CSS, JS, etc.).
1268
1324
 
1269
1325
  Use `--max-pages` and `--max-depth` to control how many pages are fetched and
1270
1326
  how many link levels deep the crawler goes. These values are persisted in your
@@ -1314,7 +1370,7 @@ akm bundle remove my-provider --yes # Skip the confirmation prompt
1314
1370
  ### bundle update
1315
1371
 
1316
1372
  Update one bundle, or refresh every configured bundle with `--all`. Git, npm,
1317
- and website candidates are staged and audited before they replace the active
1373
+ and website candidates are staged before they replace the active
1318
1374
  generation. Filesystem bundles require no hydration; update reconciles their
1319
1375
  current files into the index immediately.
1320
1376
 
@@ -1322,39 +1378,39 @@ current files into the index immediately.
1322
1378
  akm bundle update npm:@scope/pkg
1323
1379
  akm bundle update --all
1324
1380
  akm bundle update --all --force # Force fresh download even if version is unchanged
1325
- akm bundle update npm:@scope/pkg --allow-dangerous-env-keys # Explicitly approve reviewed dangerous env keys
1326
1381
  ```
1327
1382
 
1328
1383
  | Flag | Description |
1329
1384
  | --- | --- |
1330
1385
  | `--all` | Update all managed sources |
1331
- | `--force` | Delete cached extraction before re-downloading |
1332
- | `--allow-dangerous-env-keys` | Permit a staged update containing dangerous environment keys after warning. Without it, an interactive terminal prompts with a default of No; non-interactive use fails closed. |
1333
- | `-y`, `--yes` | Deprecated, no effect. An update no longer asks before deleting the previous install directory of a read-only bundle whose content moved; that directory is a re-fetchable cache. Accepted through 0.10 so existing scripts keep working. |
1334
-
1335
- The audit examines key names in `.env`-suffixed files under the staged
1336
- component root. Publisher lint suppressions do not bypass it. Rejection or an
1337
- audit/publication/index failure preserves the prior active bytes, lock/config
1386
+ | `--force` | Fetch again even when the upstream revision is unchanged |
1387
+ | `--allow-dangerous-env-keys` | Deprecated, no effect. An update no longer scans env files for process-hijacking keys. Accepted through 0.10 so existing scripts keep working. |
1388
+ | `-y`, `--yes` | Deprecated, no effect. An update never asks before pruning old install directories of a read-only bundle; they are a re-fetchable cache. Accepted through 0.10 so existing scripts keep working. |
1389
+
1390
+ A read-only git or npm bundle whose upstream revision still matches its lock
1391
+ is left exactly as it is: nothing is fetched or replaced, and the update
1392
+ reports it as unchanged. A real revision change installs the new revision
1393
+ beside the old one, keeps the immediately previous revision directory (a task
1394
+ or workflow may still be running from it) and removes older ones. A revision
1395
+ directory another bundle still references is kept.
1396
+
1397
+ A publication or index failure preserves the prior active bytes, lock/config
1338
1398
  generation, and searchable index for that bundle.
1339
1399
 
1340
- Writable Git updates resolve configured roots to their physical checkout,
1341
- reject component symlinks that escape it, and re-audit the exact materialized
1342
- worktree before activation. AKM holds its source/index writer lease through
1343
- that check and commit, and rechecks after the index pass at the final database
1344
- commit boundary. All AKM writers cooperate with this lease. A non-cooperating
1345
- local process can still edit ordinary files because POSIX/Windows filesystems
1346
- provide no mandatory recursive directory lock: writes observed by either
1347
- generation check make the update fail and restore the pre-update checkout, but
1348
- a write racing after the final filesystem read cannot be guaranteed detectable
1349
- and a write during compensation can be overwritten. Do not edit a writable
1350
- checkout from another process while its update is running.
1400
+ A writable Git update is fetched into a staged copy of the checkout beside the
1401
+ live one, so a failed fetch leaves the live checkout, the lock and the index
1402
+ untouched. The live checkout is then fast-forwarded to exactly the staged
1403
+ commit (`git merge --ff-only`), which refuses, and changes nothing, when local
1404
+ commits have diverged or the merge would overwrite local work. AKM holds its
1405
+ source/index writer lease through that fast-forward and the index pass; all AKM
1406
+ writers cooperate with this lease, but a non-cooperating local process is not
1407
+ excluded. Do not edit a writable checkout from another process while its update
1408
+ is running.
1351
1409
 
1352
1410
  The index and its update-owned state maintenance share one deferred SQLite
1353
1411
  transaction. WAL readers continue to see the last committed generation while a
1354
1412
  full update index pass runs, and competing writers wait for that pass to commit
1355
- or roll back. The semantic-status JSON file is a recomputable advisory: failure
1356
- to refresh it after the database commit warns but does not undo a committed
1357
- bundle update.
1413
+ or roll back.
1358
1414
 
1359
1415
  This boundary guarantees rollback for handled process faults (throws and
1360
1416
  SQLite commit failures); it is not an abrupt-termination or cross-database
@@ -1371,9 +1427,9 @@ durable usage state.
1371
1427
 
1372
1428
  Reports per-entry change flags: `changed.version`, `changed.revision`, and
1373
1429
  `changed.any`. With `--all`, each bundle is isolated: successful entries appear
1374
- in `processed`/`plainSynced`; rejected entries report `status: "blocked"` and a
1375
- security code; provider or transaction errors report `status: "failed"`. The
1376
- command continues with later bundles without half-publishing a blocked one.
1430
+ in `processed`/`plainSynced`; provider or transaction errors report
1431
+ `status: "failed"` and a code. The command continues with later bundles without
1432
+ half-publishing a failed one.
1377
1433
 
1378
1434
  ### bundle rename
1379
1435
 
@@ -1397,7 +1453,11 @@ config `bundles` key; `defaultBundle`/`defaultWriteTarget` when they name the
1397
1453
  old id; every `scheduler.enabled[].ref` with the old `<old>//` prefix; the
1398
1454
  lockfile entry id; every indexed entry's `bundle_id`/ref; and this tool's own
1399
1455
  state rows that name the old bundle (`proposals.ref`, a pending proposal's
1400
- write target, and workflow `task_history.target_ref`). Reported, never
1456
+ write target, workflow `task_history.target_ref`, and `workflow_runs.workflow_ref`). The result's
1457
+ `activeWorkflowRuns` lists the active and blocked runs of the renamed bundle,
1458
+ each with its `status`: their frozen plans keep the old qualified refs, so
1459
+ continue them with `akm workflow run <id>` (after `akm workflow resume <id>` for
1460
+ a blocked one) or give up with `akm workflow abandon <id>`. Reported, never
1401
1461
  rewritten: refs inside the bundle's own CONTENT (cross-references, `uses:` in
1402
1462
  a task, `supersededBy`) — the result's `contentRefs` lists the indexed files
1403
1463
  that still spell the old `<old>//` prefix so you can fix them by hand. A real
@@ -1462,17 +1522,18 @@ stopping the CLI upgrade.
1462
1522
  | Claude Code | `claude` is on `PATH`, the `akm-plugins` marketplace is configured and `akm@akm-plugins` is installed | `claude plugin marketplace update akm-plugins`, then `claude plugin update akm@akm-plugins` |
1463
1523
  | Codex | `codex` is on `PATH` and `akm@akm-plugins` is installed from the `akm-plugins` marketplace | `codex plugin marketplace upgrade akm-plugins` (this also refreshes the installed plugin cache) |
1464
1524
  | OpenCode 1 | `akm-opencode` is cached at `$XDG_CACHE_HOME/opencode/packages/akm-opencode@latest` (default `~/.cache/opencode/...`) and `opencode` is on `PATH` | If npm's `akm-opencode@latest` differs from the cached version and no OpenCode process is running: the cache directory is moved to the trash (never deleted), then `opencode debug config` is run from a temporary directory to fetch the new version. While OpenCode runs the update is `deferred` to a later `akm upgrade`. |
1465
- | OpenCode 2 | `akm-opencode-v2` is named under `"plugins"` in the global OpenCode config (`opencode.json` or `.jsonc`) and cached at `$XDG_CACHE_HOME/opencode/npm/akm-opencode-v2@latest/<build>/`, and the `opencode` on `PATH` is OpenCode 2 | If npm's `akm-opencode-v2@latest` differs from the cached version (the newest `<build>` folder): `opencode plugin update <spec>` is run from a temporary directory, with the spec as the config names it. OpenCode 2 installs the new build into a fresh `<build>` folder and the running service keeps the old one until it restarts, so nothing is moved to the trash and the update is not deferred while OpenCode runs. Listed only on a host that has the plugin, so an OpenCode 1 host reports exactly what it did before. |
1525
+ | OpenCode 2 | `akm-opencode-v2` is named under `"plugins"` in the global OpenCode config (`opencode.json` or `.jsonc`) and cached at `$XDG_CACHE_HOME/opencode/npm/akm-opencode-v2@latest/<build>/`, and the `opencode2` on `PATH` (else the `opencode`) is OpenCode 2 | If npm's `akm-opencode-v2@latest` differs from the cached version (the newest `<build>` folder): `opencode plugin update <spec>` is run from a temporary directory, with the spec as the config names it. OpenCode 2 installs the new build into a fresh `<build>` folder and the running service keeps the old one until it restarts, so nothing is moved to the trash and the update is not deferred while OpenCode runs. Listed only on a host that has the plugin, so an OpenCode 1 host reports exactly what it did before. |
1466
1526
 
1467
1527
  The two OpenCode plugins never touch each other: `akm-opencode` is only looked
1468
1528
  for in OpenCode 1's cache and `plugin` key, `akm-opencode-v2` only in OpenCode
1469
- 2's cache and `plugins` key. Before moving a cache, akm reads `opencode
1470
- --version` and skips the plugin when the `opencode` on `PATH` is the other
1471
- major, since only the matching major can re-create that cache; akm never
1529
+ 2's cache and `plugins` key. Before moving a cache, akm reads `--version` of the
1530
+ binary that owns it (`opencode` for OpenCode 1; for OpenCode 2 `opencode2` when
1531
+ it is on `PATH`, else `opencode`) and skips the plugin when that binary is the
1532
+ other major, since only the matching major can re-create that cache; akm never
1472
1533
  installs or replaces `opencode`. A spec that appears only under the legacy
1473
- `plugin` key for OpenCode 2 is skipped with a note (move it to `plugins`). Which OpenCode major akm itself drives is
1474
- [detected from the engine's binary](configuration.md#engines), independent of this
1475
- step.
1534
+ `plugin` key for OpenCode 2 is skipped with a note (move it to `plugins`). akm's
1535
+ own runtime does not depend on this step: it runs its own pinned OpenCode binary,
1536
+ fetched by akm (see [Configuration](configuration.md#without-a-harness)).
1476
1537
 
1477
1538
  OpenCode 2 has its own updater, `opencode plugin check` and `opencode plugin update`,
1478
1539
  which akm uses for `akm-opencode-v2`. Two things to know when you run them by
@@ -1918,7 +1979,7 @@ exact fix with `--replace`, `--with` and `--source`: akm checks that each
1918
1979
  `--replace` text appears exactly once and that the frontmatter still parses,
1919
1980
  records nothing if either check fails, and applies the edit at once, with no
1920
1981
  review or gate: it files a `feedback` proposal and accepts it in the same command
1921
- (the accept is a normal one, committed to a git-backed bundle, and
1982
+ (gate decision `manual-fix`, `src/commands/feedback-cli.ts`; the accept is a normal one, committed to a git-backed bundle, and
1922
1983
  `akm proposal revert` undoes it). If the accept refuses, the proposal is
1923
1984
  rejected, the file is left alone and the command fails. The asset stays eligible
1924
1985
  for improve like any other.
@@ -1932,7 +1993,9 @@ helped (it raises its ranking) and does not trigger a rewrite. Feedback
1932
1993
  changes `akm search` and `akm curate` ranking at once, with no reindex: each
1933
1994
  recorded positive raises the asset's score and each negative lowers it, the
1934
1995
  same way for every asset, so an asset with 5 positives ranks higher than one
1935
- with 2, and each further vote counts for a little less. The effect is small: it
1996
+ with 2, and each further vote counts for a little less. A hit's fused score is
1997
+ multiplied by `1 + 0.03 × (ln(1 + positives) − ln(1 + negatives))`
1998
+ (`FEEDBACK_WEIGHT` in `src/indexer/search/ranking.ts`). The effect is small: it
1936
1999
  reorders close matches and does not override relevance. Only feedback recorded
1937
2000
  as the user counts, not feedback from improve, task or audit runs; the output's
1938
2001
  `rankingUpdate.applied` says which it was (`true`, or `false` with a `reason`).
@@ -2078,13 +2141,22 @@ wrapper over the standalone `akm-migrate` executable (installed alongside
2078
2141
  akm 0.9.15 and later wrote so the CLI proper reads only current schemas. The steps,
2079
2142
  in order:
2080
2143
 
2081
- 1. config.json rewritten in its current shape (`configFile`): retired and
2082
- unknown keys dropped, `configVersion` bumped — the same pipeline every
2083
- load already runs in memory, so this only persists it, under a backup. A
2084
- config older than 0.9.15 (the legacy `stashDir`/`sources[]`/`installed`
2085
- layout, an `extraParams` key that shadows a first-class engine field) is
2086
- not converted by 0.10 and blocks this step: run `akm migrate apply` under
2087
- akm 0.9.x first;
2144
+ 1. config.json rewritten in its current shape (`configFile`): unknown keys
2145
+ dropped, `configVersion` bumped, and the `engines` / `defaults` form converted
2146
+ to `connections` / `harnesses` — the same conversion every load already
2147
+ runs in memory, so this only persists it, under a backup. The keys akm no
2148
+ longer reads from config (an engine's `apiKeyFile`, a literal or
2149
+ `${secrets/...}` `apiKey`, and the same on a connection, `embedding` or
2150
+ `search.curateRerank`) move to `credentials.json`, one note per key and
2151
+ never its value; a key that cannot be moved stays where it was, with a
2152
+ note. A leftover `models.json` is folded into the `models` of the
2153
+ connections and harnesses it names, then moved to `config-backups/` in the
2154
+ cache directory. A connection or harness akm cannot use stays in the file as
2155
+ written, with a note on what to fix. What each retired key becomes is the
2156
+ table in [Configuration](configuration.md#the-engines-form). A config older
2157
+ than 0.9.15 (the legacy `stashDir`/`sources[]`/`installed` layout) is not
2158
+ converted by 0.10 and blocks this step: run `akm migrate apply` under akm
2159
+ 0.9.x first;
2088
2160
  2. pending `state.db` migrations, historical-destructive ones included, with
2089
2161
  a verified sibling safety copy (`stateMigrations`) — the only path besides
2090
2162
  `akm upgrade` that admits released migration 018, which an ordinary
@@ -2094,7 +2166,13 @@ in order:
2094
2166
  (`taskFiles`) under one backup directory per run, each emitted document
2095
2167
  re-parsed by the runtime v4 parser first; a file the planner cannot
2096
2168
  convert unambiguously is reported `blocked` and left alone;
2097
- 4. superseded residue removed (`deadResidue`): pre-0.9.0 `.akm` leftovers in
2169
+ 4. the retired `engine:` key on commands, agents, workflows and task sources
2170
+ rewritten to `connection:` or `harness:` by what the name is now
2171
+ (`assetEngineKeys`), under one backup directory per run. The run that has
2172
+ rewritten every such key it can reach forgets the old engine names and adds one
2173
+ note to `assetEngineKeys.notes` listing each renamed engine and the flag that
2174
+ replaces it (see [The `engines` form](configuration.md#the-engines-form));
2175
+ 5. superseded residue removed (`deadResidue`): pre-0.9.0 `.akm` leftovers in
2098
2176
  the stash, and the transaction-journal, maintenance-barrier, lock-mutex and
2099
2177
  version-stamp files older releases kept under `$DATA`, `$STATE` and
2100
2178
  `$CONFIG`.
@@ -2137,7 +2215,7 @@ akm config get output.format # Read one key
2137
2215
  akm config get output.format --show-source # Read one key, with where it came from
2138
2216
  akm config set output.detail full # Set one key
2139
2217
  akm config set output.detail full --silent # Set without the post-write config dump on stdout
2140
- akm config unset llm # Remove an optional key
2218
+ akm config unset embedding # Remove an optional key
2141
2219
  akm config path # Print path to config file
2142
2220
  akm config diff other-host/config.json # Effective-config differences, secrets redacted
2143
2221
  ```
@@ -2149,10 +2227,17 @@ Subcommands:
2149
2227
  | `get <key>` | Read one config key (the effective, post-`extends` value). `--show-source` wraps it as `{ value, source }`, where `source` is `local`, `extends:<ref>`, or `default`. |
2150
2228
  | `list` | List current configuration |
2151
2229
  | `set <key> <value>` | Set one config key; prints the resulting config with `ok: true` |
2152
- | `unset <key>` | Unset an optional key, or a whole `embedding`/engine section; prints the resulting config with `ok: true` |
2230
+ | `unset <key>` | Unset an optional key, or a whole `embedding`, connection or harness section; prints the resulting config with `ok: true` |
2153
2231
  | `path` | Print the config file path (`akm info` reports the bundle, config, data, cache and state directories). Load-bearing: `config path` is the one subcommand the CLI still allows to run when the on-disk config itself fails to load, so you always have a way to locate a broken config. |
2154
2232
  | `diff <path\|bundle//path>` | Compare this instance's effective config (its own `extends` already applied) against another config file or bundle-relative file (loaded through the same loader — its `extends` honoured too); prints sorted `{ path, local, other }` rows for every differing leaf, secrets redacted on both sides. |
2155
2233
 
2234
+ A key that holds an API key (`connections.<name>.apiKey`, `embedding.apiKey`,
2235
+ `search.curateRerank.apiKey`) accepts a `$VAR` reference and rejects a literal
2236
+ key: keys live in the environment or in `credentials.json`, never in
2237
+ `config.json` (see [Credentials](configuration.md#credentials)). A connection or
2238
+ harness name that is not lowercase kebab-case, or a harness entry that names no
2239
+ platform, is refused before anything is written.
2240
+
2156
2241
  `set` and `unset` accept `--silent` to suppress the post-write config dump
2157
2242
  entirely — nothing is printed on stdout, and the exit code is the status (the
2158
2243
  write still happens and errors still print) — use it from hooks and CI
@@ -2171,34 +2256,24 @@ See [configuration.md](configuration.md) for details.
2171
2256
 
2172
2257
  ### models
2173
2258
 
2174
- Manage the installed and operator-owned model intent map. Bare `akm models`
2175
- is a usage error; use `list` to inspect the effective table or `copy-defaults`
2176
- when you want an editable full map.
2259
+ Show which model answers each alias (`fast`, `balanced`, `reasoning`, and any
2260
+ you add) on a connection, then the models its endpoint lists, and change one.
2261
+ Connections only: a harness's alias map is `harnesses.<name>.models`, edited
2262
+ with `akm config set`. Run `akm models --help` for the options.
2177
2263
 
2178
2264
  ```sh
2179
- akm models list
2180
- akm models copy-defaults
2181
- akm models copy-defaults --overwrite
2265
+ akm models # The default connection's picks and the endpoint's models
2266
+ akm models --connection cloud # Another connection
2267
+ akm models --no-probe # The picks only; the endpoint is not contacted
2268
+ akm models set reasoning glm-5 # Make glm-5 answer "reasoning"
2182
2269
  ```
2183
2270
 
2184
- `list` shows the fully resolved alias table — one row per (alias, column)
2185
- pair with its `model`, optional `inference`, `source` (`default`: unchanged
2186
- from the installed file; `user`: touched by the user overlay), and `via`
2187
- (`literal`: a model string; `engine`: borrowed from a configured
2188
- `engines.<name>` connection, in which case the row also names that `engine`).
2189
- Read-only; it never writes `models.json`.
2190
-
2191
- `copy-defaults` validates the packaged version-1 `models.json`, then stages and
2192
- syncs it beside the normal AKM configuration target. Creation uses an atomic
2193
- no-replace publish and fails safely on filesystems that cannot provide it.
2194
- `--overwrite` performs an atomic pathname replacement after a best-effort
2195
- regular-file identity recheck; it never dereferences a symlink, but portable
2196
- filesystems do not offer a conditional rename that locks the previously
2197
- observed inode. Symlinks and other non-regular targets observed during checks
2198
- are refused. See
2199
- [Model-map files](configuration.md#model-map-files) for schema, overlay, and
2200
- resolution semantics — including the `engine` field (0.9.15) that lets a
2201
- column borrow its model from a configured engine instead of a literal string.
2271
+ `akm models` prints `{ connection, aliases, available }`. `set` writes
2272
+ `connections.<name>.models.<alias>`; an alias whose entry carries request fields
2273
+ keeps them and changes the model. A model the endpoint does not list is written
2274
+ with a warning. With no connection configured both commands say so and point at
2275
+ `akm setup`. A `--connection` that is not configured fails as any named target
2276
+ does: exit 78, the configured connections listed and the closest name suggested.
2202
2277
 
2203
2278
  ### help
2204
2279
 
@@ -2276,9 +2351,9 @@ names only; `run` and `export` are the supported value-use paths.
2276
2351
 
2277
2352
  ```sh
2278
2353
  akm env list
2279
- akm env create prod # creates env/prod.env (mode 0600)
2280
- akm env create prod --from-file ./.env # ingest an existing .env
2281
- akm env create prod --path staging # creates env/staging/prod.env
2354
+ akm env create env/prod # creates env/prod.env (mode 0600)
2355
+ akm env create env/prod --from-file ./.env # ingest an existing .env
2356
+ akm env create env/prod --path staging # creates env/staging/prod.env
2282
2357
  $EDITOR "$(akm env path env/prod --quiet)" # edit the file directly
2283
2358
  akm env run env/prod -- npm test # run a command with the whole file injected
2284
2359
  akm env run env/prod -- $SHELL # interactive shell with the env loaded
@@ -2289,6 +2364,14 @@ akm env remove env/prod --yes # remove the whole env file
2289
2364
  akm does not manage individual keys — edit the `.env` file directly (`$EDITOR
2290
2365
  "$(akm env path <ref>)"`). `env remove <ref>` removes the whole file.
2291
2366
 
2367
+ Every `<ref>` is a full akm ref, `[bundle//]env/<name>`; there is no bare-name
2368
+ form (`akm env run prod` is a usage error naming `env/<name>`). A value in the
2369
+ file can embed a `${ref}` token: `${secrets/name}` (or `${bundle//secrets/name}`)
2370
+ is replaced with the secret's value when the env is injected, and any other
2371
+ asset ref with its absolute path. A `${...}` body that is not an akm ref, such
2372
+ as `${HOME}`, is left as text. A ref no bundle owns fails the run and nothing
2373
+ is injected. See [Environment & Secrets](env-and-secrets.md#the-ref-token).
2374
+
2292
2375
  Env mutations (`create`, `remove`) pick their write destination the same way
2293
2376
  every other write command does: an explicit `--bundle <source>` wins, else
2294
2377
  `defaultWriteTarget`, else the working bundle. The chosen source must be
@@ -2305,7 +2388,7 @@ Subcommands:
2305
2388
  | --- | --- |
2306
2389
  | `list` | List all env files across all bundles with key names only |
2307
2390
  | `run <ref> -- <command>` | Run a command with the env injected. `--only` / `--except` filter which keys are injected; `--clean` starts from a minimal inherited environment |
2308
- | `create <name>` | Create an env file. Empty by default; seed with `--from-file <path>` or `--from-stdin` |
2391
+ | `create <ref>` | Create an env file (a full ref such as `env/prod`). Empty by default; seed with `--from-file <path>` or `--from-stdin` |
2309
2392
  | `path <ref>` | Print the absolute env file path (Docker `_FILE` / `--env-file` / direct editing). `--quiet` suppresses the warning |
2310
2393
  | `export <ref> --out <file>` | Write a safe sourceable `export` script to a file (never to stdout) |
2311
2394
  | `remove <ref>` | Delete an env file (and its `.sensitive` marker) |
@@ -2322,7 +2405,7 @@ akm env run env/prod --only A,B -- cmd # inject only A and B
2322
2405
  akm env run env/prod --except DEBUG -- cmd
2323
2406
  akm env run env/prod --clean -- cmd
2324
2407
  akm env run env/prod --clean --inherit SSH_AUTH_SOCK -- cmd
2325
- akm env run third-party//env/prod --allow-dangerous-env-keys -- cmd
2408
+ akm env run team//env/prod -- cmd # an env in an installed bundle
2326
2409
  ```
2327
2410
 
2328
2411
  Runs the command with the env file's values injected **directly into the child
@@ -2331,12 +2414,12 @@ However, the child process controls its own stdout/stderr: if it prints its
2331
2414
  environment, those values will appear in your terminal or agent transcript.
2332
2415
  `--only` / `--except` (comma-separated key names, mutually exclusive) restrict
2333
2416
  which env-file keys are injected. `--clean` starts from a minimal inherited
2334
- environment (PATH/HOME/locale/terminal basics) instead of inheriting the full
2335
- parent environment; use `--inherit KEY1,KEY2` to pass specific parent vars
2336
- through in clean mode. Before spawning, the injected key names are scanned for
2337
- known process-hijacking variables (`LD_PRELOAD`, `PATH`, `GIT_CONFIG_*`, ...):
2338
- a first-party bundle warns and proceeds; a third-party-sourced bundle is refused
2339
- unless the reviewed run explicitly passes `--allow-dangerous-env-keys`.
2417
+ environment (PATH/HOME/locale/terminal basics, and the names Windows needs to
2418
+ start a process) instead of inheriting the full parent environment; use `--inherit KEY1,KEY2` to pass specific parent vars
2419
+ through in clean mode. Installing a bundle is the trust decision, so `env run`
2420
+ injects what the env file defines whichever bundle it comes from, including keys
2421
+ such as `PATH` or `LD_PRELOAD`; it does not warn or block. `--allow-dangerous-env-keys`
2422
+ is a deprecated no-op, accepted through 0.10 so existing scripts keep working.
2340
2423
 
2341
2424
  > The single-key `run <ref>/KEY` form was removed. To inject one value, store it
2342
2425
  > as a [secret](#secret) and use `akm secret run secrets/<name> <VAR> -- …`, or
@@ -2351,12 +2434,12 @@ unless the reviewed run explicitly passes `--allow-dangerous-env-keys`.
2351
2434
  #### env create
2352
2435
 
2353
2436
  ```sh
2354
- akm env create prod # empty
2355
- akm env create prod --from-file ./.env # seed from an existing .env (byte-for-byte)
2356
- printf 'A=1\nB=2\n' | akm env create prod --from-stdin
2357
- akm env create prod --path staging # creates env/staging/prod.env
2358
- akm env create prod --sensitive # hidden from `env list` and the search index
2359
- akm env create prod --bundle team # write to the `team` source
2437
+ akm env create env/prod # empty
2438
+ akm env create env/prod --from-file ./.env # seed from an existing .env (byte-for-byte)
2439
+ printf 'A=1\nB=2\n' | akm env create env/prod --from-stdin
2440
+ akm env create env/prod --path staging # creates env/staging/prod.env
2441
+ akm env create env/prod --sensitive # hidden from `env list` and the search index
2442
+ akm env create env/prod --bundle team # write to the `team` source
2360
2443
  ```
2361
2444
 
2362
2445
  | Flag | Description |
@@ -2445,6 +2528,10 @@ AKM_VALUE="$TOKEN" akm secret set secrets/api --from-env AKM_VALUE
2445
2528
  akm secret run secrets/deploy-token GITHUB_TOKEN -- gh release create v1.0.0
2446
2529
  ```
2447
2530
 
2531
+ Every `<ref>` is a full akm ref, `[bundle//]secrets/<name>`; a bare name
2532
+ (`akm secret run deploy-token ...`) is a usage error naming `secrets/<name>`. The
2533
+ value is read with surrounding whitespace trimmed.
2534
+
2448
2535
  Subcommands:
2449
2536
 
2450
2537
  | Subcommand | Description |
@@ -2496,8 +2583,9 @@ akm secret run secrets/deploy-token GITHUB_TOKEN --clean -- gh auth status
2496
2583
 
2497
2584
  Runs one subprocess with the secret's value set as `$VAR` in the child's
2498
2585
  environment. **The value never appears in akm's structured output** — it is
2499
- passed directly to the child process. The target variable name is validated and
2500
- known process-hijacking names (`LD_PRELOAD`, `PATH`, etc.) are rejected.
2586
+ passed directly to the child process. The target variable name is validated as
2587
+ an environment variable name; process-hijacking names such as `LD_PRELOAD` or
2588
+ `PATH` are injected like any other.
2501
2589
  `--clean` starts from a minimal inherited environment instead of inheriting the
2502
2590
  full parent environment; use `--inherit KEY1,KEY2` to pass specific parent vars
2503
2591
  through in clean mode.
@@ -2572,10 +2660,12 @@ These commands define the self-improvement and agent-dispatch surface.
2572
2660
  ### command run
2573
2661
 
2574
2662
  Resolve a stored command through its owning bundle adapter and execute one
2575
- fresh session through the common engine/model cascade:
2663
+ fresh session. It runs on the default harness, else on akm's own runtime over
2664
+ the default connection, unless a flag or the command's own frontmatter names a
2665
+ connection or harness (see [Configuration](configuration.md#where-each-process-runs)):
2576
2666
 
2577
2667
  ```sh
2578
- akm command run <command-ref> [--arguments <exact-text>] [--agent <selector>] [--engine <name>] [--model <id-or-alias>] [--timeout-ms <ms>] [--cwd <path>] [--dry-run]
2668
+ akm command run <command-ref> [--arguments <exact-text>] [--agent <selector>] [--connection <name> | --harness <name>] [--model <id-or-alias>] [--timeout-ms <ms>] [--cwd <path>] [--dry-run]
2579
2669
  ```
2580
2670
 
2581
2671
  `--dry-run` does not dispatch and does not materialize credentials.
@@ -2585,26 +2675,26 @@ akm command run <command-ref> [--arguments <exact-text>] [--agent <selector>] [-
2585
2675
  | `<command-ref>` | Local indexed command ref, optionally bundle-qualified (for example `commands/review` or `team//commands/review`) |
2586
2676
  | `--arguments <exact-text>` | Exact string substituted for every literal `$ARGUMENTS`; it is not trimmed, tokenized, quoted, or recursively expanded |
2587
2677
  | `--agent <selector>` | Portable `agents/...` ref or a native harness selector |
2588
- | `--engine <name>` | Current-invocation engine override |
2589
- | `--model <id-or-alias>` | Current-invocation exact model or operator model-map alias |
2678
+ | `--connection <name>` / `--harness <name>` | Current-invocation connection or harness override (mutually exclusive) |
2679
+ | `--model <id-or-alias>` | Current-invocation model: an alias (`fast`, `balanced`, `reasoning`) or an exact name |
2590
2680
  | `--timeout-ms <ms>` | Current-invocation timeout override |
2591
2681
  | `--cwd <path>` | Current-invocation workspace override |
2592
- | `--dry-run` | Resolve, authorize, and lower the command without dispatching or materializing credentials |
2682
+ | `--dry-run` | Resolve and lower the command without dispatching or materializing credentials |
2593
2683
 
2594
2684
  Commands and portable personas are rendered by their bundle adapter. Native
2595
2685
  frontmatter is never sent as prompt text and native files are never rewritten.
2596
2686
  The only portable template token is literal `$ARGUMENTS`. Positional, named,
2597
2687
  expression, legacy `{{...}}`, and other native-only constructs fail before
2598
- authorization or dispatch; invoke those templates through their native tool.
2688
+ dispatch; invoke those templates through their native tool.
2599
2689
  Omitting `--arguments` and passing an explicit empty string both substitute
2600
2690
  empty text, but remain distinct in the resolved request.
2601
2691
 
2602
- `akm command run ... --dry-run` performs the real adapter read, cascade/model
2603
- resolution, operator authorization or policy check, and engine lowering. It
2692
+ `akm command run ... --dry-run` performs the real adapter read, target and model
2693
+ resolution, and request lowering. It
2604
2694
  returns a successful JSON result with `schemaVersion: 1`,
2605
- `shape: "command-dry-run"`, `ok: true`, `dryRun: true`, the selected engine
2606
- name, safe `provenance`, and safe lowering `notices`. It has no fake exit code,
2607
- stdout, stderr, or duration.
2695
+ `shape: "command-dry-run"`, `ok: true`, `dryRun: true`, `engine` (the name of
2696
+ the connection or harness it would run on), safe `provenance`, and safe
2697
+ lowering `notices`. It has no fake exit code, stdout, stderr, or duration.
2608
2698
 
2609
2699
  Each provenance entry contains only `field`, `layer`, `kind`, and `via`. Each
2610
2700
  lowering notice contains `code`, `severity`, `adapter`, optional `field`, and
@@ -2625,85 +2715,70 @@ that consume stdout.
2625
2715
 
2626
2716
  ### agent
2627
2717
 
2628
- Dispatch a configured agent engine, optionally selecting a bundle agent persona
2629
- and model defaults. A nonempty tool request from that asset is not
2630
- authorization: the current CLI rejects it at the execution boundary.
2631
- Stored command assets execute only through `akm command run`; `akm agent` has
2632
- no command compatibility alias.
2718
+ Run an agent on a harness, or on akm's own runtime over a connection, optionally
2719
+ embodying a bundle agent persona. Run `akm agent --help` for the options. Stored
2720
+ command assets execute only through `akm command run`; `akm agent` has no
2721
+ command compatibility alias.
2633
2722
 
2634
2723
  ```sh
2635
- akm agent [<agent-ref>] [--engine <name>] [--prompt <text>] [--model <model>] [--timeout-ms <ms>] [--cwd <path>]
2724
+ akm agent [<agent-ref>] [--connection <name> | --harness <name>] [--prompt <text>] [--model <model>] [--timeout-ms <ms>] [--cwd <path>]
2636
2725
  ```
2637
2726
 
2638
2727
  | Argument / Flag | Description |
2639
2728
  | --- | --- |
2640
- | `<agent-ref>` | Optional agent asset ref (e.g. `agents/code-reviewer`). Resolves persona and model defaults; a nonempty tool request still requires separate operator authorization. |
2641
- | `--engine <name>` | Agent engine to use; defaults to `defaults.engine` |
2642
- | `--prompt <text>` | Task prompt to pass to the agent |
2643
- | `--model <model>` | Model override. Accepts aliases (`opus`, `sonnet`, `haiku`) or exact platform model IDs. Overrides the model in the agent asset. Resolved per platform: `opencode/claude-opus-4-7` for opencode, `claude-opus-4-7` for claude. |
2644
- | `--timeout-ms <ms>` | Override the agent CLI timeout in milliseconds |
2645
- | `--cwd <path>` | Working directory for the spawned agent (defaults to the current directory) |
2646
-
2647
- When `<agent-ref>` is provided, akm resolves the bundle agent's persona,
2648
- `modelHint`, and requested `toolPolicy`. The `--model` flag wins over any model
2649
- specified in the asset. An alias resolves per the selected `--engine`'s
2650
- model-map column (see [Model-map files](configuration.md#model-map-files)),
2651
- which — as of 0.9.15 — may itself be an `engine`-backed indirection, so
2652
- `--engine local-fast --model fast` can resolve to `local-fast`'s own
2653
- `engines.local-fast.model` instead of a hardcoded per-platform literal. The
2654
- requested tool policy never grants access by itself: authorization runs before
2655
- lowering, credentials, or provider dispatch.
2656
- The current CLI has no built-in allow-all authorizer, so a nonempty request is
2657
- rejected rather than silently weakened.
2658
- Selecting a persona or model without `--prompt` or `--prompt-stdin` is also
2659
- rejected; akm never fabricates an empty command. The
2660
- prompt-free interactive exemption applies only when no persona/model/tool/schema
2661
- or inference payload was selected.
2662
-
2663
- **Platform-specific dispatch:** akm uses a platform builder to construct the
2664
- CLI argv for each engine's harness platform. `platform: "opencode"` engines emit:
2665
- `opencode run [--model opencode/claude-opus-4-7] "<prompt>"`. `opencode run` has
2666
- no system-prompt option, so akm composes a persona into the prompt.
2667
- `platform: "claude"` engines emit:
2668
- `claude [--system-prompt "..."] [--model claude-opus-4-7] --print -- "<prompt>"`.
2669
- Agent engines may set `bin`, `args`, `workspace`, `model`, and `timeoutMs` in
2670
- config. Semantic model aliases live only in the installed/user `models.json`
2671
- files and resolve before dispatch.
2672
-
2673
- Without any `--prompt`, `<agent-ref>`, or `--model`, the agent is launched
2674
- interactively (no injected prompt, no platform-specific flags beyond the
2675
- engine's base args).
2676
-
2677
- Configure agent engines under `engines.<name>` with `kind: "agent"` and a
2678
- registered harness `platform` (see [Configuration](configuration.md)). AKM
2679
- lowers the selected engine to the spawn or embedded SDK runner with captured or
2680
- interactive stdio, hard timeout, and structured failure reasons.
2729
+ | `<agent-ref>` | Optional agent asset ref (e.g. `agents/code-reviewer`). Resolves persona and model defaults. |
2730
+ | `--connection <name>` / `--harness <name\|platform>` | Connection or harness to run on, by name, a harness also by platform (mutually exclusive); default: the default harness, else akm's own runtime over the default connection |
2731
+ | `--prompt <text>` / `--prompt-stdin` | The task. Without one the harness starts interactively. |
2732
+ | `--model <model>` | An alias (`fast`, `balanced`, `reasoning`) or an exact model name; overrides the model in the agent asset |
2733
+ | `--timeout-ms <ms>` | Override the run's timeout in milliseconds |
2734
+ | `--cwd <path>` | Working directory for the run (defaults to the current directory) |
2735
+
2736
+ With a prompt the agent runs the task, and its reply is the result's `stdout`.
2737
+ On a harness the program runs as you would run it by hand ([How akm runs a
2738
+ harness](configuration.md#how-akm-runs-a-harness)).
2739
+ When `<agent-ref>` is provided, akm resolves the bundle agent's persona and model
2740
+ default; `--model` wins over the asset. An alias is looked up on the selected
2741
+ connection or harness (see [Aliases](configuration.md#aliases)): `--harness
2742
+ claude --model reasoning` runs Claude Code's `reasoning` model, and `--connection
2743
+ local --model reasoning` the model `connections.local.models.reasoning` names.
2744
+
2745
+ Without a prompt, `akm agent --harness <name>` starts the harness interactively,
2746
+ with the terminal inherited and nothing sent to it; only a model may ride along.
2747
+ A connection has nothing to start, so `--connection` without `--prompt` is an
2748
+ error that says to pass `--prompt` or name a harness. A persona, an inference
2749
+ setting or an output schema applies to a task, so selecting one without
2750
+ `--prompt` or `--prompt-stdin` is rejected.
2681
2751
 
2682
2752
  ```sh
2683
2753
  # Interactive launch:
2684
- akm agent --engine opencode
2754
+ akm agent --harness opencode
2685
2755
 
2686
2756
  # Dispatch with a prompt only:
2687
- akm agent --engine claude --prompt "summarize recent changes"
2757
+ akm agent --harness claude --prompt "summarize recent changes"
2688
2758
 
2689
2759
  # Embody a bundle agent asset:
2690
- akm agent agents/code-reviewer --engine opencode --prompt "review src/"
2760
+ akm agent agents/code-reviewer --harness opencode --prompt "review src/"
2691
2761
 
2692
2762
  # Model override with alias:
2693
- akm agent agents/planner --engine claude --model sonnet --prompt "plan the sprint"
2763
+ akm agent agents/planner --harness claude --model reasoning --prompt "plan the sprint"
2764
+
2765
+ # Exact model name override:
2766
+ akm agent --harness opencode --model anthropic/claude-opus-4-7 --prompt "audit the API"
2694
2767
 
2695
- # Exact model ID override:
2696
- akm agent --engine opencode --model opencode/claude-opus-4-7 --prompt "audit the API"
2768
+ # On akm's own runtime, over a connection:
2769
+ akm agent --connection local --prompt "summarize recent changes"
2697
2770
  ```
2698
2771
 
2699
- Returns `{ ok, exitCode, stdout?, stderr?, durationMs, reason?, sessionId? }`; `sessionId` is the
2700
- harness's own session id when it reports one (`opencode-sdk` keeps its OpenCode session, so the run can be
2701
- found there). On
2702
- failure, `reason` is one of `timeout | spawn_failed | non_zero_exit |
2703
- parse_error`. Captured dispatches render this final envelope using the selected
2704
- akm format. Interactive child stdout/stderr remain inherited and raw. A failed
2705
- dispatch exits 1; `exitCode` in the envelope retains the child's exact status
2706
- when one exists.
2772
+ Returns `{ ok, engine, exitCode, stdout, stderr, durationMs, reason?, error?, sessionId? }`.
2773
+ `engine` is the name of the connection or harness the run used. `sessionId` is
2774
+ the run's session id when it has one: akm's own runtime reports the session it
2775
+ keeps in `<akm data dir>/opencode-runtime/data/opencode/opencode.db`, so the run
2776
+ can be found there; a harness run reports none. On
2777
+ failure, `reason` is a short code such as `timeout`, `spawn_failed`,
2778
+ `non_zero_exit` or `parse_error`. Captured dispatches render this final envelope
2779
+ using the selected akm format. Interactive child stdout/stderr remain inherited
2780
+ and raw. A failed dispatch exits 1; `exitCode` in the envelope retains the
2781
+ child's exact status when one exists.
2707
2782
 
2708
2783
  ### lint
2709
2784
 
@@ -2713,9 +2788,9 @@ stale paths, and broken refs — in body text and in
2713
2788
  `refs`/`xrefs`/`supersededBy`/`contradictedBy` frontmatter. A belief edge
2714
2789
  pointing at a memory that `akm improve` pruned resolves through the archive
2715
2790
  tombstone under `.akm/memory-cleanup/archive/` and is not reported (#884). Also reports
2716
- `dangerous-env-key` findings for env files (the same key set `akm bundle add`
2717
- enforces — see [Dangerous env key audit](#dangerous-env-key-audit) — but
2718
- non-blocking here; `lint` only warns). `--type workflows` structurally parses
2791
+ `dangerous-env-key` findings for env files (the key set described under
2792
+ [Env files and process-hijacking keys](#env-files-and-process-hijacking-keys);
2793
+ `lint` only warns). `--type workflows` structurally parses
2719
2794
  and compiles Markdown workflows; errors surface as
2720
2795
  `invalid-workflow-structure` findings (0.9.0: this is the only
2721
2796
  structural-validation surface now that `akm workflow validate` is gone).
@@ -2761,11 +2836,11 @@ akm improve memory
2761
2836
  akm improve skills/code-review
2762
2837
  akm improve workflows/release-checklist --task "reduce duplication"
2763
2838
  akm improve --skip-if-locked # for high-frequency scheduled runs: skip (exit 0) if a run is already in progress
2764
- akm improve --require-engines # for scheduled runs: abort (exit 78) instead of degrading if an engine/credential is unavailable
2839
+ akm improve --harness claude # run every call of this run, judges included, on the claude harness
2765
2840
  akm improve --no-sync # skip the pre-run and end-of-run git sync entirely (default: on for git-backed bundles)
2766
2841
  akm improve --sync --no-push # commit only, skip the push after it
2767
- akm improve --dry-run --strategy consolidate # preview consolidate's resolved engine/model routing; nothing is dispatched
2768
- akm improve lessons/my-lesson --show-prompt --format text # print the composed reflect prompt for one asset, unwrapped; no lock/index/engine call
2842
+ akm improve --dry-run --strategy consolidate # preview which connection or harness and model each consolidate process would use; nothing is dispatched
2843
+ akm improve lessons/my-lesson --show-prompt --format text # print the composed reflect prompt for one asset, unwrapped; no lock/index/model call
2769
2844
  akm improve report # LLM usage/routing report for the most recent real run
2770
2845
  akm improve report --run <id> # ...for one specific improve_runs id
2771
2846
  akm improve report --since 7d # ...aggregated over every real run started in the last 7 days
@@ -2780,11 +2855,12 @@ akm improve judge < revision.json # reflect's quality judge on one revision
2780
2855
  | `--limit <n>` | Cap the refs the run processes, highest salience first (refs routed to distill only come last). Overrides the strategy's `processes.reflect.limit` and `limit` |
2781
2856
  | `--timeout-ms <ms>` | Wall-clock budget for the run (default: `7200000` = 2 hours) |
2782
2857
  | `--require-feedback-signal` | Turn the proactive-maintenance lane off for the run, so only assets with recent feedback are planned |
2783
- | `--strategy <name>` | Override the active improve strategy (a built-in or entry under `improve.strategies`) |
2858
+ | `--strategy <name>` | Override the active improve strategy (a built-in or entry under `improve.strategies`); it chooses which processes run, never where |
2859
+ | `--connection <name>` / `--harness <name>` | Run every call of this run, judges included, on this connection or harness instead of the default; they are mutually exclusive |
2860
+ | `--model <alias\|name>` | The model for every call of this run: an alias (`fast`, `balanced`, `reasoning`) or an exact name |
2784
2861
  | `--json-to-stdout` | Also emit the full persisted JSON result on stdout for a live run. Without this flag, stdout stays empty. Dry-runs always emit their result and are never persisted. |
2785
2862
  | `--skip-if-locked` | If another improve run already holds the lock, skip gracefully (exit 0) instead of failing with "already running" (exit 75, `TransientError`, code `IMPROVE_LOCK_HELD` — field follow-up to #948: two legitimate `improve` invocations colliding on this lock is ordinary, retryable contention, not a broken config file). Use for high-frequency scheduled runs so they don't pile up failures while a longer run is in progress. |
2786
- | `--require-engines` | Abort (exit 78, before any indexing, lock, or log side effect) if the active strategy would enable a process whose engine or credential cannot be resolved in this process's environment, OR whose endpoint fails a bounded reachability probe — the same probe `akm health`'s `default-llm-engine`/`configured-engines` checks run, once per distinct endpoint. An agent engine's check is that its binary is on PATH, and an `opencode-sdk` engine's is both its binary and, when it sets `llmEngine`, that LLM fallback's endpoint. Without this flag, improve degrades gracefully: it skips the affected processes and reports them in the result's `skippedProcesses`. Recommended alongside `--skip-if-locked` for scheduled runs, since the operator's own shell can pass config validation while a scheduler's stripped-down environment (see #953) cannot. |
2787
- | `--show-prompt` | Print the composed reflect prompt (#952) for one asset and exit — before any lock, index write, or engine dispatch. Requires a fully-qualified asset ref as the scope (`akm improve lessons/my-lesson --show-prompt`); rejected with a type or whole-bundle scope. The default output format is JSON, which carries the prompt as a `prompt` field (escaped into one line) alongside the resolved `engine`/`engineKind`; pass `--format text` to print the prompt itself, unwrapped and readable by eye. |
2863
+ | `--show-prompt` | Print the composed reflect prompt (#952) for one asset and exit — before any lock, index write, or model call. Requires a fully-qualified asset ref as the scope (`akm improve lessons/my-lesson --show-prompt`); rejected with a type or whole-bundle scope. The default output format is JSON, which carries the prompt as a `prompt` field (escaped into one line) alongside `engine` (the connection or harness reflect would run on) and `engineKind` (`connection` or `harness`); pass `--format text` to print the prompt itself, unwrapped and readable by eye. |
2788
2864
  | `--sync` / `--no-sync` | Sync the git-backed primary bundle like `akm sync` (fetch and merge the upstream, commit, push) before the run, and commit (and optionally push) when it finishes. A conflict or fetch failure before the run only warns; the run continues on the local state. Default: on for git-backed bundles (per profile config). |
2789
2865
  | `--push` / `--no-push` | Push after the pre-run and end-of-run sync commits when writable with a remote configured. `--no-push` commits only, skipping the push. Default: per profile config (`true`). `sync.push` stays outside the autonomy gate — this is a per-run opt-out, not a default change. |
2790
2866
 
@@ -2876,35 +2952,36 @@ material no improve stage has processed. The planned refs are ranked by salience
2876
2952
  and cut to the limit; an explicit ref scope bypasses every gate. Use
2877
2953
  `--require-feedback-signal` to turn that lane off for the run.
2878
2954
 
2879
- When the active strategy enables a process (or the triage judgment engine)
2880
- whose engine or credential cannot be resolved in this process's environment,
2881
- the run does not silently do nothing for it: the process is skipped, and the
2882
- result carries `skippedProcesses` — an array of `{process, configKey, reason}`
2883
- entries (omitted entirely when nothing was skipped). When the process resolved
2884
- a real engine whose credential just isn't reachable here (as opposed to never
2885
- resolving an engine at all), the entry also carries the structurally resolved
2886
- `engine`/`model`/`contextLength` it would have used — never the credential
2887
- itself. `ok` and the exit code are unchanged either way, matching `extract`'s
2888
- `skipReasons` contract: consumers that need to know branch on
2889
- `skippedProcesses` (or pass `--require-engines` to abort instead of
2890
- degrading). `reason` names which engine and which credential reference (an env
2891
- var, `apiKeyFile` path, or `secret://` reference — never its value) is
2892
- missing. A `--dry-run` preview never dispatches, so it never aborts
2893
- on an unavailable credential either — even a strategy left with every process
2894
- disabled this way still returns its plan, with the affected processes in
2895
- `skippedProcesses`.
2955
+ When the active strategy enables a process (or the triage judgment) that has no
2956
+ connection or harness to run on, the run does not silently do nothing for it:
2957
+ the process is skipped, and the result carries `skippedProcesses` — an array of
2958
+ `{process, configKey, reason}` entries (omitted entirely when nothing was
2959
+ skipped). `configKey` is the setting that would place the process
2960
+ (`improve.processes.<process>.connection`) and `reason` says that no connection
2961
+ or harness is configured and points at `akm setup`. `ok` and the exit code are
2962
+ unchanged either way, matching `extract`'s `skipReasons` contract: consumers
2963
+ that need to know branch on `skippedProcesses`. When no model-calling process
2964
+ can run at all (no connection or harness is configured, or several are and none
2965
+ is called `default`), there is nothing to degrade to: the run stops at planning
2966
+ with exit 78, naming what is missing, before it takes a lock, writes the index
2967
+ or opens a log, and `--dry-run` stops the same way. No flag asks for that. (The
2968
+ 0.9 `--require-engines` is still accepted and does nothing, with one warning, so
2969
+ a task installed for 0.9 keeps running. It used to refuse the run unless every
2970
+ enabled process had a usable target; that check is gone, and `akm health`
2971
+ (`akm health && akm improve`, which stops on exit 4) is what checks whether each
2972
+ connection answers and each harness is installed.)
2896
2973
 
2897
2974
  `--timeout-ms` is a run-wide wall-clock budget: when it expires, the run
2898
- cooperatively aborts any in-flight engine request (the same `AbortSignal`
2899
- every LLM call already honors) instead of waiting out the engine's own,
2900
- much longer, per-call timeout — the run then finishes and reports normally
2975
+ cooperatively aborts any in-flight model request (the same `AbortSignal`
2976
+ every LLM call already honors) instead of waiting out the call's own,
2977
+ much longer, timeout — the run then finishes and reports normally
2901
2978
  rather than hanging past its budget. SIGTERM/SIGINT/SIGHUP end a live run
2902
2979
  the same way, within a short bounded grace period, and the process exits
2903
2980
  with a stable per-signal code (`143`/`130`/`129`) rather than needing a
2904
2981
  `kill -9`. If a live run has waited more than a few seconds without any
2905
- engine response at all, one default-level line ("Still waiting for the
2906
- first engine response...") is printed so a scheduled run's log is never
2907
- silently empty while an engine is slow or dead.
2982
+ model response at all, one default-level line ("Still waiting for the
2983
+ first model response...") is printed so a scheduled run's log is never
2984
+ silently empty while a model is slow or dead.
2908
2985
 
2909
2986
  For dry runs, `plannedRefs` is the effective post-limit work set, not every
2910
2987
  ref in the requested scope. The `plan` object preserves both views: raw scope
@@ -2922,38 +2999,35 @@ not an atomic cross-store snapshot or a reservation. Live execution re-inspects
2922
2999
  mutable inputs, so a later run can differ after index, state, filesystem,
2923
3000
  clock, or session-log changes.
2924
3001
 
2925
- `plan.processes` (#947) is the resolved process -> engine -> model routing
2926
- table: one row per improve process (`reflect`, `distill`, `consolidate`,
3002
+ `plan.processes` (#947) is the resolved process -> connection or harness -> model
3003
+ routing table: one row per improve process (`reflect`, `distill`, `consolidate`,
2927
3004
  `memoryInference`, `extract`, `validation`, `triage`,
2928
3005
  `proactiveMaintenance`), plus a `triage.judgment` row when the strategy
2929
- configures a judgment engine. Each row carries `enabled`, the resolved
2930
- `engine`, its `model` (when the engine has an LLM connection) and `engineKind`, this process's
2931
- own lowering `notices`, and — for reflect/distill/consolidate only —
2932
- `eligibleRefs`, the count of this run's `effectiveRefs` the process would act
2933
- on (`shouldSkipRef`'s allowedTypes/excludeRefPrefixes (reflect only)/
2934
- process-disabled check; a count, not a per-ref matrix, to keep the envelope
2935
- bounded). A row that could not resolve an
2936
- engine or credential carries `unavailable: {configKey, reason}` — the same
2937
- data behind `skippedProcesses` above, reshaped per process. When the process
2938
- resolved a real engine whose credential just isn't reachable here, the row
2939
- still carries that engine's `engine`/`model`/`engineKind` alongside
2940
- `unavailable`, rather than omitting them the way a never-configured process
2941
- does — so a preview can show what would have run. This table is
2942
- resolved before any dispatch on every invocation (dry or live), so
2943
- `akm improve --dry-run --strategy <name>` previews an ad-hoc
2944
- strategy override without changing config first; `akm health`'s
2945
- `active-improve-strategy` check performs the equivalent resolution but only
2946
- for the configured default strategy (`defaults.improveStrategy`), and reports
2947
- no model or per-process notices. `--dry-run` does not probe
2948
- engine reachability over the network — pair with `akm health --probe` (or the
2949
- default probe-on behavior) to check whether a named engine actually answers.
3006
+ enables a judgment. Each row carries `enabled`, `engine` (the name of the
3007
+ connection or harness it resolved to), its `model` and `engineKind`
3008
+ (`connection` or `harness`), this process's own lowering `notices`, and — for
3009
+ reflect/distill/consolidate only — `eligibleRefs`, the count of this run's
3010
+ `effectiveRefs` the process would act on (`shouldSkipRef`'s
3011
+ allowedTypes/excludeRefPrefixes (reflect only)/process-disabled check; a count,
3012
+ not a per-ref matrix, to keep the envelope bounded). A row whose process has no
3013
+ connection or harness carries `unavailable: {configKey, reason}` — the same data
3014
+ behind `skippedProcesses` above, reshaped per process. Wherever a result says
3015
+ where work ran (`agent`, `command run`, `extract`, `llm_usage` rows, a workflow
3016
+ step's summary) the field is named `engine` and always holds a connection or
3017
+ harness name; scripts can rely on it. This table is resolved
3018
+ before any dispatch on every invocation (dry or live), so
3019
+ `akm improve --dry-run --strategy <name>` previews an ad-hoc strategy override
3020
+ without changing config first; `akm health` and `akm info` print the same
3021
+ resolution for every kind of work, whichever strategy runs. `--dry-run` does not
3022
+ probe reachability over the network — run `akm health` to check whether a
3023
+ connection actually answers.
2950
3024
 
2951
3025
  `--show-prompt` (#952) is the cheapest way to exercise reflect alone: it
2952
3026
  builds the exact prompt reflect would send for one asset — the same source
2953
3027
  resolution, runner selection, feedback/schema-hint/rejected-proposal
2954
3028
  gathering `akm improve`'s live reflect step uses — and prints it
2955
- without reading a credential, so it never calls an engine. An LLM engine
2956
- receives the reply's JSON Schema as `response_format`, and an agent engine as
3029
+ without reading a credential, so it never calls a model. A connection
3030
+ receives the reply's JSON Schema as `response_format`, and a harness as
2957
3031
  an instruction that dispatch appends to this prompt. Add
2958
3032
  `--format text` (the default JSON/yaml envelope escapes the prompt into one
2959
3033
  line, which defeats a by-eye read) to confirm by eye that recent feedback is
@@ -2966,7 +3040,7 @@ destination than `memory`.
2966
3040
 
2967
3041
  #### improve report
2968
3042
 
2969
- `akm improve report` (#944) answers "which engine did each model-calling process
3043
+ `akm improve report` (#944) answers "which connection or harness did each model-calling process
2970
3044
  use this run, how much did it cost, and which enabled processes made zero
2971
3045
  calls (and why)" without hand-written SQLite against `state.db`. It is a
2972
3046
  real subcommand (`report` is not an asset type, so it is not a scope of the
@@ -2980,7 +3054,8 @@ Every real (non-dry-run) `akm improve` invocation persists a `usageReport`
2980
3054
  field on the result (`result_json` in `improve_runs`, and in the
2981
3055
  `--json-to-stdout` / dry-run JSON): `{ byProcessEngineModel, noCalls }`.
2982
3056
  `byProcessEngineModel` is a cross-tab of the LLM call records this run's own
2983
- usage sink collects (#576) — one row per distinct `(process, engine, model)` triple, each with
3057
+ usage sink collects (#576) — one row per distinct `(process, engine, model)` triple,
3058
+ where `engine` is the connection or harness name, each with
2984
3059
  `calls`, `failures`, `promptTokens`, `completionTokens`, `totalTokens`,
2985
3060
  `reasoningTokens`, and `totalDurationMs`. `noCalls` lists every model-calling
2986
3061
  process (`reflect`, `distill`, `consolidate`, `memoryInference`,
@@ -3010,13 +3085,15 @@ support.
3010
3085
  #### improve judge
3011
3086
 
3012
3087
  `akm improve judge` (a real subcommand; `--strategy` is its only flag) runs reflect's quality judge on one revision and prints its
3013
- verdict, for testing a judge engine on revisions whose right answer you know. It
3088
+ verdict, for testing a judge on revisions whose right answer you know. It
3014
3089
  reads `{"source": "...", "candidate": "...", "feedback": "...", "ref": "..."}` JSON
3015
3090
  from stdin (`feedback` and `ref` are optional; `ref` names the revised asset,
3016
- which a judge on an agent engine may read), judges with the engine the strategy's
3017
- `processes.reflect.qualityGate.engine` names (`--strategy` picks the strategy),
3018
- and prints `{ engine, pass, score, reason, criteria }` with the gate's prompt and
3019
- pass rule. A `score` of `-1` means the judge gave no verdict. It writes nothing.
3091
+ which a judge on a harness may read), judges with the connection or harness
3092
+ `improve.qualityGate` names (the default when it names none; `--strategy` picks
3093
+ the strategy whose reflect gate must be enabled), and prints `{ engine, pass,
3094
+ score, reason, criteria }` with the gate's prompt and pass rule, where `engine`
3095
+ is the name of the connection or harness that judged. A `score` of `-1` means
3096
+ the judge gave no verdict. It writes nothing.
3020
3097
 
3021
3098
  ### proposal
3022
3099
 
@@ -3070,9 +3147,10 @@ akm proposal extract --type claude --location /custom/path --session-id <id>
3070
3147
  | `--auto` | Iterate every available harness with the default `--since`. Mutually exclusive with `--type`. |
3071
3148
  | `--dry-run` | Show candidates without queuing proposals. |
3072
3149
  | `--force` | Re-process sessions even if they were already extracted and have no new events. Default: skip already-seen sessions. |
3073
- | `--timeout-ms <ms>` | Per-session LLM timeout in ms (default `600000`). |
3074
- | `--engine <name>` | Named engine for this invocation: an LLM engine, or a `claude`, `opencode` or `opencode-sdk` agent engine. Mutually exclusive with `--strategy`. |
3075
- | `--strategy <name>` | Improve strategy supplying extract behavior and engine. Mutually exclusive with `--engine`. |
3150
+ | `--timeout-ms <ms>` | Per-session LLM timeout in ms. Default: the selected connection's or harness's own timeout. |
3151
+ | `--connection <name>` / `--harness <name\|platform>` | Connection or harness for this invocation, by name, a harness also by platform (mutually exclusive). |
3152
+ | `--model <alias\|name>` | Model for this invocation: an alias or an exact name. |
3153
+ | `--strategy <name>` | Improve strategy supplying extract behavior; it never chooses where the model runs. |
3076
3154
 
3077
3155
  `--type` and `--auto` are mutually exclusive; one of them is required.
3078
3156
  `--auto` iterates `getAvailableHarnesses()` — every harness with a detectable
@@ -3085,30 +3163,45 @@ The `codex` harness reads Codex's rollout files under `$CODEX_HOME/sessions`
3085
3163
  (`~/.codex/sessions` by default; `--location` points at another rollout
3086
3164
  directory). It lists a person's sessions, `codex exec` runs included, and
3087
3165
  leaves out the rollouts Codex writes for subagents and its other internal agents:
3088
- those are not sessions of their own.
3166
+ those are not sessions of their own. akm's own Codex model-work runs are among
3167
+ the sessions it lists; Codex gives them no marker.
3168
+
3169
+ The `opencode` harness reads two SQLite files, read-only and without starting
3170
+ OpenCode: OpenCode's own `opencode.db` (under `$XDG_DATA_HOME/opencode`, which is
3171
+ `~/.local/share/opencode` unless `XDG_DATA_HOME` says otherwise, on every
3172
+ platform) and akm's own runtime's `opencode.db` (under
3173
+ `<akm data dir>/opencode-runtime/data/opencode/`), where it keeps its agent runs
3174
+ (`--location` points at a directory holding another
3175
+ `opencode.db`). Runs of the `opencode` harness are in OpenCode's own file. It
3176
+ reads both OpenCode 2 and OpenCode 1 files. Of an OpenCode 2 file it lists only
3177
+ top-level sessions, leaving out subagent sessions and akm's own model work,
3178
+ which ran as the `akm-model-work` agent; OpenCode 1 keeps no such marker, so its
3179
+ model-work sessions are listed like any other. A file it cannot read is named in
3180
+ a warning, never taken for an empty history.
3089
3181
 
3090
3182
  There is no `akm proposal extract --watch`/`--debounce-ms` either (0.9.0:
3091
3183
  dropped — a foreground polling daemon in a one-shot CLI); the shipped
3092
3184
  `core/extract.yml` cron template (`akm proposal extract --auto` on a
3093
3185
  schedule) is the answer.
3094
3186
 
3095
- Requires an engine that can run unattended model work (an LLM engine, or a
3096
- `claude`, `opencode` or `opencode-sdk` agent): pass `--engine`, select a
3097
- `--strategy` whose `processes.extract.engine` is set, or configure
3098
- `defaults.llmEngine`.
3187
+ Extraction is model work: it needs a connection or a harness (see
3188
+ [Configuration](configuration.md#where-each-process-runs)). With neither it fails
3189
+ and points at `akm setup`. It runs on the default connection, else the default
3190
+ harness; `--connection`, `--harness` and `--model` choose another, and
3191
+ `improve.processes.extract` sets it for the improve stage too.
3099
3192
 
3100
3193
  **Output.** `ok` means the command ran to completion — it is `true` even when
3101
- every session was skipped (an unreachable LLM engine included); it does not
3194
+ every session was skipped (an unreachable connection included); it does not
3102
3195
  mean anything was harvested. Consumers that need "did this run actually
3103
3196
  harvest" branch on `skipReasons`, `warnings`, or `sessionsProcessed` /
3104
3197
  `sessionsSkipped` instead. The envelope also reports:
3105
3198
 
3106
3199
  | Field | Description |
3107
3200
  | --- | --- |
3108
- | `engine` | Resolved engine name for this run. Absent only when extract is disabled by the selected improve strategy (the run returns before an engine is resolved). |
3109
- | `engineKind` | `"llm"`, `"sdk"`, or `"agent"` — the kind of runner `engine` resolved to. Same absence condition as `engine`. |
3201
+ | `engine` | Name of the connection or harness the run resolved to. Absent only when extract is disabled by the selected improve strategy (the run returns before a target is resolved). |
3202
+ | `engineKind` | `"connection"` or `"harness"` — what `engine` names. Same absence condition as `engine`. |
3110
3203
  | `skipReasons` | Per-`skipReason` count across `sessions[]` (e.g. `{ "llm_unavailable": 25 }`). Present only when `sessionsSkipped > 0`. |
3111
- | `warnings` | Includes one aggregate line per infrastructure skip reason that fired (`llm_unavailable`, `read_failed`, `exception`, `locked_concurrent`) — e.g. `25 of 25 sessions skipped: llm_unavailable (engine "default")` — so an engine outage is visible without inspecting `sessions[]`. Session-content skips (`already_extracted`, `too_short`, `triaged_out`) are counted in `skipReasons` but never produce a warning line. |
3204
+ | `warnings` | Includes one aggregate line per infrastructure skip reason that fired (`llm_unavailable`, `read_failed`, `exception`, `locked_concurrent`) — e.g. `25 of 25 sessions skipped: llm_unavailable (engine "default")` — so an outage is visible without inspecting `sessions[]`. Session-content skips (`already_extracted`, `too_short`, `triaged_out`) are counted in `skipReasons` but never produce a warning line. |
3112
3205
  | `sessions[].warnings` | One line per candidate the model wrote that the output contract refuses, as `<type>:<name> dropped: <reason>` — a lesson without a `when_to_use` of 15 characters, a description under 20, a name that is not a kebab-case slug — and one per candidate held back by the improve ledger. A session whose every candidate was dropped has `candidateCount: 0` and no `rationaleIfEmpty`, so this is where the loss shows. |
3113
3206
 
3114
3207
  #### proposal new
@@ -3131,27 +3224,24 @@ akm proposal new skill code-review --bundle team --task "PR-style review skill"
3131
3224
  | `--bundle` | Configured writable bundle to queue the proposal for. The prompt takes its convention facts from that bundle, the proposal records it as its target (so `akm proposal accept` writes there), and it is queued in that bundle's queue (`akm proposal list --queue <bundle>`). An unknown, disabled or read-only bundle is refused, as for `akm remember --bundle`. Default: the working bundle |
3132
3225
  | `--task` | Inline task text |
3133
3226
  | `--file` | Read task text from a UTF-8 file |
3134
- | `--engine` | Override the default execution engine. Any kind works: an LLM engine, an agent CLI or `opencode-sdk` |
3135
- | `--timeout-ms` | Override the selected engine timeout for this call |
3227
+ | `--connection` / `--harness` | Override the default connection or harness, by name, a harness also by platform (mutually exclusive) |
3228
+ | `--model` | Override the model: an alias or an exact name |
3229
+ | `--timeout-ms` | Override the selected connection's or harness's timeout for this call |
3136
3230
 
3137
3231
  Exactly one of `--task` or `--file` is required. Emits `propose_invoked`.
3138
3232
 
3139
- Every engine kind returns the proposal the same way: as one JSON object on
3140
- stdout with the asset's `ref`, its full `content` and a self-rated
3141
- `confidence`. akm sends the object's JSON Schema with the request, as
3142
- `response_format` to an LLM engine and as an instruction at the end of the
3143
- prompt to an agent engine (codex also gets it as `--output-schema`). akm
3144
- captures the reply; an agent CLI runs headless, with no live terminal session.
3145
- A harness's own JSON envelope, such as claude's
3146
- `--output-format json` result, is unwrapped first.
3233
+ `proposal new` is agent work: it runs on the default harness, else akm's own
3234
+ runtime over the default connection, and `--connection` or `--harness` choose
3235
+ another. The agent returns the proposal as one JSON object on stdout with the
3236
+ asset's `ref`, its full `content` and a self-rated `confidence`. akm sends the
3237
+ object's JSON Schema as an instruction at the end of the prompt, and captures the
3238
+ reply, which is the agent's plain-text output; a harness runs headless, with no
3239
+ live terminal session.
3147
3240
  A reply that is not a valid proposal gets one corrective retry that says what
3148
3241
  was wrong. If that reply is not valid either, the command exits 1 with
3149
- `reason: "parse_error"` and an error that names the engine, for example
3150
- `Engine "local" reply was not valid proposal JSON after 2 attempts: …`.
3242
+ `reason: "parse_error"` and an error that names the connection or harness, for
3243
+ example `Engine "local" reply was not valid proposal JSON after 2 attempts: …`.
3151
3244
 
3152
- **Prompt-task `timeoutMs`:** a version-2 prompt task may set `timeoutMs` to
3153
- override its selected engine timeout. Set it to `null` to disable the timer, or
3154
- to a positive integer (milliseconds) to apply a task-specific limit.
3155
3245
 
3156
3246
  #### proposal list
3157
3247
 
@@ -3503,7 +3593,7 @@ akm search --type task # List tasks (cross-bundle)
3503
3593
  akm show tasks/<id> # Inspect one task
3504
3594
  akm task add <id> --schedule "@daily" \ # Register a new task and install it
3505
3595
  --command "akm improve --strategy default"
3506
- akm task add review --schedule "@daily" --prompt "Review recent changes" --engine reviewer
3596
+ akm task add review --schedule "@daily" --prompt "Review recent changes" --harness reviewer
3507
3597
  akm task add nightly --schedule "@daily" --command "akm improve" --disabled # register but leave off
3508
3598
  akm task add nightly --schedule "@daily" --command "akm improve" --force # overwrite an existing task id
3509
3599
  akm task enable team//tasks/nightly # Add local activation and sync its bundle
@@ -3626,7 +3716,7 @@ different bundle is a hard error.
3626
3716
  document (`version: 4`). In the file, exactly one of `uses` or `run` is
3627
3717
  allowed. `uses` accepts command, workflow, and script refs plus `akm/command`;
3628
3718
  agents and task refs are not executable. `run` accepts a shell string with the
3629
- closed shell and contained working-directory contract. Task source v4 has no
3719
+ closed shell and working-directory contract. Task source v4 has no
3630
3720
  `akm:` options bag or `on:` trigger block — scheduling, resolver overrides,
3631
3721
  `timeout`, `maxSteps`, `maxRetries`, and redaction names are all top-level
3632
3722
  keys on the document itself. Normal execution rejects v2 and v3 and points to
@@ -3638,9 +3728,9 @@ fail-closed migration behavior.
3638
3728
  file and its `logs.db` rows — is scrubbed before it is written. Two passes run:
3639
3729
  credential *shapes* (`Bearer …`, `sk-…`, webhook URLs) are matched by pattern,
3640
3730
  and exact secret values are matched by value. akm knows a value is secret when
3641
- the config declares it (`engines.<name>.apiKey`, `embedding.apiKey`, and the
3642
- `AKM_ENGINE_<NAME>_API_KEY` / `AKM_LLM_API_KEY` / `AKM_EMBED_API_KEY` recipes),
3643
- and it infers others from the variable name (`*_TOKEN`, `*_SECRET`, `*_API_KEY`,
3731
+ the config declares it (the key every connection, `embedding` and
3732
+ `search.curateRerank` resolves to: a `$VAR`'s value, or the `credentials.json`
3733
+ entry), and it infers others from the variable name (`*_TOKEN`, `*_SECRET`, `*_API_KEY`,
3644
3734
  `*_PASSWORD`, …) provided the value is at least 8 characters — a short one is
3645
3735
  far more likely to be a flag than a credential, and redaction replaces
3646
3736
  substrings, so guessing wrong mangles the log.
@@ -3659,8 +3749,7 @@ akm looks each name up in the environment the run is given; a name that is unset
3659
3749
  contributes nothing. **Names only.** A literal secret in a task file would leak
3660
3750
  far more widely than the redaction closes: task files are indexed into the search
3661
3751
  database, can be sent to an embedding provider, are printed verbatim by `akm
3662
- show`, and ship inside bundles over git and npm. This is the same rule exec
3663
- units' `pass_env:` follows.
3752
+ show`, and ship inside bundles over git and npm.
3664
3753
 
3665
3754
  A workflow-target task executes the same native orchestration as `akm workflow
3666
3755
  run`; it does not stop after creating a run. Completion maps to task
@@ -3678,7 +3767,7 @@ unattended run, so without one a single wedged unit hangs the task forever. An
3678
3767
  explicit `timeout` always wins, and `timeout: null` opts out entirely. On
3679
3768
  expiry the runner aborts the run's signal, which the engine treats as a
3680
3769
  graceful break at the next step boundary — the journal is kept and the run
3681
- stays resumable with `akm workflow resume <run-id>` (the run id is in the task
3770
+ stays active, and `akm workflow run <run-id>` continues it (the run id is in the task
3682
3771
  run's `detail.error` and log). The attempt itself is recorded as `failed`, so
3683
3772
  the OS scheduler sees a non-zero exit.
3684
3773