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
@@ -30,15 +30,14 @@ import path from "node:path";
30
30
  import { assetPathForName, stashDirFor } from "../../core/asset/asset-placement.js";
31
31
  import { parseFrontmatter } from "../../core/asset/frontmatter.js";
32
32
  import { parseRefInput } from "../../core/asset/resolve-ref.js";
33
- import { ConfigError } from "../../core/errors.js";
34
33
  import { appendEvent } from "../../core/events.js";
35
34
  import { escapeJsonStringControls, stripCodeFences, stripThinkBlocks } from "../../core/parse.js";
36
35
  import { info, warn } from "../../core/warn.js";
37
- import { DEFAULT_LLM_TIMEOUT_MS } from "../../integrations/agent/config.js";
36
+ import { noticeSet } from "../../execution/notices.js";
38
37
  import { buildExecution, resolveExecution } from "../../integrations/agent/execution.js";
39
- import { assertRunnerCredentials, runExecution, } from "../../integrations/agent/runner-dispatch.js";
38
+ import { callStructured } from "../../llm/structured-call.js";
40
39
  import { NEIGHBOUR_EXCERPT_CHARS, NEIGHBOUR_NOTE_COUNT, nearestKnowledgeNotes, shingleContainment, wordShingles, } from "../improve/consolidate/coverage.js";
41
- import { errMessage, noticeSet } from "../improve/stage.js";
40
+ import { errMessage } from "../improve/stage.js";
42
41
  import { akmProposalAccept, akmProposalReject } from "./proposal.js";
43
42
  import { isRetireProposal, PAIR_PASS_GATE, STALE_TARGET_GATE_REASON } from "./proposal-types.js";
44
43
  import { commitCollectedAccepts, listProposals, listProposalsReadOnly, preflightProposalPromotion, proposalContent, proposalContentHash, readFreshProposalTarget, recordGateDecision, } from "./repository.js";
@@ -218,38 +217,20 @@ export function parseJudgmentVerdict(raw) {
218
217
  return null;
219
218
  return { decision, reason: typeof reason === "string" ? reason : "" };
220
219
  }
221
- /** Lower the judgment prompt through the frozen runner and dispatch it. */
222
- async function dispatchJudgment(runner, prompt, seams) {
220
+ /** Dispatch the judgment prompt on the frozen runner: one model call, under the model-work tool policy. */
221
+ async function dispatchJudgment(runner, prompt, seams, signal) {
223
222
  let notices = [];
224
- try {
225
- // Model work is bounded on every runner kind: one with no timeout of its own gets the default.
226
- // The judgment runs under the model-work tool policy.
227
- const prepared = resolveExecution({
228
- content: prompt,
229
- runner,
230
- current: Object.hasOwn(runner, "timeoutMs") ? {} : { timeout: DEFAULT_LLM_TIMEOUT_MS },
231
- modelWork: true,
232
- });
233
- const lowered = buildExecution(prepared.request, prepared.runner);
234
- notices = lowered.notices;
235
- const chat = seams.chat;
236
- const llmRunner = lowered.runner.kind === "llm" ? lowered.runner : undefined;
237
- const result = await runExecution(lowered, {
238
- ...(seams.runAgentFn ? { runAgent: seams.runAgentFn } : {}),
239
- ...(seams.runSdkFn ? { runSdk: seams.runSdkFn } : {}),
240
- ...(chat && llmRunner
241
- ? { chat: async (connection, messages) => chat({ ...llmRunner, connection }, messages) }
242
- : {}),
243
- });
244
- if (!result.ok)
245
- return { verdict: null, notices, error: result.error ?? result.reason ?? "unknown error" };
246
- return { verdict: parseJudgmentVerdict(result.stdout), notices };
247
- }
248
- catch (error) {
249
- if (error instanceof ConfigError)
250
- throw error;
251
- return { verdict: null, notices, error: errMessage(error) };
252
- }
223
+ const outcome = await callStructured({
224
+ runner,
225
+ messages: [{ role: "user", content: prompt }],
226
+ request: { ...(seams.chat ? { chat: seams.chat } : {}), ...(signal ? { signal } : {}) },
227
+ onNotices: (value) => {
228
+ notices = value;
229
+ },
230
+ });
231
+ if (!outcome.ok)
232
+ return { verdict: null, notices, error: outcome.error };
233
+ return { verdict: parseJudgmentVerdict(outcome.raw), notices };
253
234
  }
254
235
  /**
255
236
  * The judgment tier: the runner only judges; the drain performs the accept
@@ -268,6 +249,12 @@ async function runJudgmentTier(opts, result, pending, acceptBudget, promoteFn, r
268
249
  stillDeferred.push(item);
269
250
  continue;
270
251
  }
252
+ // Past the deadline nothing is dispatched: the item stays undecided, as an error would leave it.
253
+ if (opts.signal?.aborted) {
254
+ deferNotes.set(item.id, { reason: "judgment-error" });
255
+ stillDeferred.push(item);
256
+ continue;
257
+ }
271
258
  const liveAsset = readLiveAssetContent(opts.stashDir, proposal.ref);
272
259
  const prompt = buildJudgmentPrompt(proposal, item.reason, {
273
260
  liveAsset,
@@ -277,7 +264,7 @@ async function runJudgmentTier(opts, result, pending, acceptBudget, promoteFn, r
277
264
  ? { neighbours: promotionNeighbours(opts.stashDir, proposal, acceptedPromotions) }
278
265
  : {}),
279
266
  });
280
- const dispatch = await dispatchJudgment(opts.judgment, prompt, seams);
267
+ const dispatch = await dispatchJudgment(opts.judgment, prompt, seams, opts.signal);
281
268
  notices.add(dispatch.notices);
282
269
  if (dispatch.error)
283
270
  warn(`[triage] judgment dispatch failed for ${item.id}: ${dispatch.error}`);
@@ -439,7 +426,7 @@ async function drainPending(opts, promoteFn, rejectFn, judgmentSeams) {
439
426
  // A consolidate pair-pass `retire` proposal is auto-accepted only when the
440
427
  // pair pass staged it: nothing unique on either side, confirmed by a
441
428
  // second look, no continuity risk; every other one waits for a direct
442
- // `akm proposal accept` (spec §25.6). Checked before isEmptyDiff, which
429
+ // `akm proposal accept`. Checked before isEmptyDiff, which
443
430
  // has nothing meaningful to read on a delete-primary change.
444
431
  if (isRetireProposal(proposal)) {
445
432
  const staged = proposal.gateDecision;
@@ -479,13 +466,13 @@ async function drainPending(opts, promoteFn, rejectFn, judgmentSeams) {
479
466
  }
480
467
  }
481
468
  if (opts.judgment && result.deferred.some((d) => d.reason === "needs-judgment")) {
482
- // Symbolic credentials, and the runner's model-work tool policy, are checked before any gate, reject or promote.
469
+ // Build the judgment runner's request before any gate, reject or promote: a transport that cannot run at all fails here, not after a mutation.
483
470
  const prepared = resolveExecution({
484
471
  content: "Validate the selected proposal judgment runner before mutation.",
485
472
  runner: opts.judgment,
486
473
  modelWork: true,
487
474
  });
488
- assertRunnerCredentials(buildExecution(prepared.request, prepared.runner).runner);
475
+ buildExecution(prepared.request, prepared.runner);
489
476
  }
490
477
  for (const id of empties) {
491
478
  const failure = await rejectProposal(opts, id, "empty diff", "empty-diff", rejectFn);
@@ -17,7 +17,9 @@ import { parsePositiveIntFlag } from "../../cli/parse-args.js";
17
17
  import { defineGroupCommand, defineJsonCommand, EXIT_CODES, output } from "../../cli/shared.js";
18
18
  import { resolveStashDir } from "../../core/common.js";
19
19
  import { loadConfig } from "../../core/config/config.js";
20
- import { UsageError } from "../../core/errors.js";
20
+ import { SHIPPED_ALIAS } from "../../core/config/model-aliases.js";
21
+ import { ConfigError, UsageError } from "../../core/errors.js";
22
+ import { mergeNotices } from "../../execution/notices.js";
21
23
  import { installLlmUsagePersistenceIfAbsent } from "../../llm/usage-persist.js";
22
24
  import { withLlmStage } from "../../llm/usage-telemetry.js";
23
25
  import { resolveImproveExecution } from "../improve/execution.js";
@@ -27,14 +29,6 @@ import { drainProposals } from "./drain.js";
27
29
  import { akmProposalAccept, akmProposalAcceptMany, akmProposalDiff, akmProposalList, akmProposalReject, akmProposalReopen, akmProposalRevert, akmProposalShow, bulkAdjudicateProposals, } from "./proposal.js";
28
30
  import { proposalWaitingSince } from "./proposal-types.js";
29
31
  import { proposeCommand } from "./propose-cli.js";
30
- export function mergeProposalDrainNotices(resolutionNotices, dispatchNotices) {
31
- const byKey = new Map();
32
- for (const notice of resolutionNotices ?? [])
33
- byKey.set(JSON.stringify(notice), notice);
34
- for (const notice of dispatchNotices ?? [])
35
- byKey.set(JSON.stringify(notice), notice);
36
- return byKey.size > 0 ? Object.freeze([...byKey.values()]) : undefined;
37
- }
38
32
  /**
39
33
  * Parse + validate the shared bulk-adjudication filter flags
40
34
  * (`--max-diff-lines`, `--older-than`). Extracted from the two verbatim
@@ -433,10 +427,9 @@ const proposalDrainCommand = defineJsonCommand({
433
427
  }
434
428
  }
435
429
  // `--older-than` is applied here as a pre-filter on excludeIds: ids that
436
- // are too fresh are excluded so the engine never touches them. This reads
430
+ // are too fresh are excluded so the drain never touches them. This reads
437
431
  // the pending set once here; drainProposals reads the pending set again
438
- // internally, so a future engine-level olderThan option could remove this
439
- // second read (engine API owned by another agent — not changed here).
432
+ // internally.
440
433
  let excludeIds;
441
434
  if (olderThanMs !== undefined) {
442
435
  const { listProposals } = await import("./repository.js");
@@ -456,15 +449,18 @@ const proposalDrainCommand = defineJsonCommand({
456
449
  // disabled block. An explicitly selected strategy may opt in through its
457
450
  // judgment block; the implicit default strategy keeps standalone drain's
458
451
  // historical no-judge behavior.
459
- const judgmentResolution = args.judgment === true || (args.strategy !== undefined && triageConfig?.judgment?.enabled === true)
452
+ const judgmentWanted = args.judgment === true || (args.strategy !== undefined && triageConfig?.judgment?.enabled === true);
453
+ const judgmentResolution = judgmentWanted
460
454
  ? resolveImproveExecution({
461
455
  config: cfg,
462
- profile: selectedStrategy.config,
463
- process: triageConfig,
464
- current: triageConfig?.judgment,
456
+ process: "triage",
465
457
  processName: "proposal-triage-judgment",
458
+ alias: SHIPPED_ALIAS.judge,
466
459
  })
467
460
  : null;
461
+ if (judgmentWanted && !judgmentResolution) {
462
+ throw new ConfigError("Proposal judgment was requested, but no connection or harness is configured to judge with.", "LLM_NOT_CONFIGURED", "Run `akm setup`, or set improve.connection or improve.processes.triage.connection.");
463
+ }
468
464
  const judgment = judgmentResolution?.runner ?? null;
469
465
  // #576: persist + attribute per-call LLM usage for the standalone drain
470
466
  // path. `IfAbsent` keeps an enclosing `akm improve` sink in charge when
@@ -486,14 +482,14 @@ const proposalDrainCommand = defineJsonCommand({
486
482
  disposeDrainUsageSink();
487
483
  }
488
484
  const dispatchNotices = result.notices;
489
- const notices = mergeProposalDrainNotices(judgmentResolution?.notices, dispatchNotices);
485
+ const notices = mergeNotices(judgmentResolution?.notices, dispatchNotices);
490
486
  output("proposal-drain", {
491
487
  schemaVersion: 1,
492
488
  ok: true,
493
489
  applyMode,
494
490
  dryRun,
495
491
  strategy: selectedStrategy.name,
496
- judgmentEngine: judgment?.engine ?? null,
492
+ judgmentEngine: judgment?.name ?? null,
497
493
  judgmentKind: judgment?.kind ?? null,
498
494
  ...(notices ? { notices } : {}),
499
495
  promoted: result.promoted,
@@ -18,6 +18,7 @@ import fs from "node:fs";
18
18
  import path from "node:path";
19
19
  import { defineCommand } from "citty";
20
20
  import { getStringArg, parsePositiveIntFlag } from "../../cli/parse-args.js";
21
+ import { RETIRED_ENGINE_ARG, SELECTION_ARGS, selectionFromArgs } from "../../cli/selection.js";
21
22
  import { EXIT_CODES, GLOBAL_OUTPUT_ARGS, output, runWithJsonErrors } from "../../cli/shared.js";
22
23
  import { assertFlatAssetName, combineCreatePath, normalizeCreateSubPath } from "../../core/asset/asset-create.js";
23
24
  import { UsageError } from "../../core/errors.js";
@@ -51,7 +52,8 @@ export const proposeCommand = defineCommand({
51
52
  type: "string",
52
53
  description: "Configured writable bundle to queue the proposal for and draw convention facts from (default: the working bundle)",
53
54
  },
54
- engine: { type: "string", description: "Engine to use (defaults to defaults.engine)" },
55
+ ...SELECTION_ARGS,
56
+ ...RETIRED_ENGINE_ARG,
55
57
  "timeout-ms": { type: "string", description: "Override the engine timeout in milliseconds" },
56
58
  },
57
59
  async run({ args }) {
@@ -76,7 +78,7 @@ export const proposeCommand = defineCommand({
76
78
  type: String(args.type),
77
79
  name: proposedName,
78
80
  task: taskText,
79
- engine: getStringArg(args, "engine"),
81
+ selection: selectionFromArgs(args),
80
82
  bundle: getStringArg(args, "bundle"),
81
83
  ...(timeoutMs !== undefined ? { timeoutMs } : {}),
82
84
  });
@@ -1,34 +1,21 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * `akm proposal new <type> <name> --task ...` — proposal-producing command
6
- * (#226).
7
- *
8
- * Mirrors {@link akmReflect} but for fresh authoring. The engine, of any kind,
9
- * receives a task description plus per-asset-type schema hints and returns a
10
- * brand-new asset payload as JSON on stdout. The output lands ONLY in the
11
- * proposal queue.
12
- *
13
- * Failures use the same {@link AgentFailureReason} discriminants as
14
- * `akm reflect`. `propose_invoked` is emitted at command entry.
15
- */
16
4
  import { placementTypes, stashDirFor } from "../../core/asset/asset-placement.js";
17
5
  import { parseRefInput } from "../../core/asset/resolve-ref.js";
18
6
  import { resolveStashDir } from "../../core/common.js";
7
+ import { SHIPPED_ALIAS } from "../../core/config/model-aliases.js";
19
8
  import { generatedContentRejection } from "../../core/content-safety.js";
20
9
  import { UsageError } from "../../core/errors.js";
21
10
  import { appendEvent } from "../../core/events.js";
22
- import { redactSensitiveText } from "../../core/redaction.js";
23
11
  import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
24
- import { runStructured } from "../../core/structured.js";
25
- import { warn } from "../../core/warn.js";
26
12
  import { resolveWriteTarget } from "../../core/write-source.js";
27
13
  import { deriveEntryProvenance } from "../../indexer/installations.js";
28
- import { fallbackAnnouncement } from "../../integrations/agent/engine-fallback.js";
29
- import { buildExecution, resolveExecution } from "../../integrations/agent/execution.js";
14
+ import { buildExecution, currentLayer, resolveExecution, shippedAlias } from "../../integrations/agent/execution.js";
30
15
  import { buildProposePrompt, PROPOSAL_JSON_SCHEMA, validateProposalPayload, } from "../../integrations/agent/prompts.js";
31
- import { assertRunnerCredentials, collectDispatchSensitiveValues, runExecution, unwrapHarnessReply, } from "../../integrations/agent/runner-dispatch.js";
16
+ import { runExecution } from "../../integrations/agent/runner-dispatch.js";
17
+ import { isRefused, jsonParser, structuredLoop } from "../../llm/structured.js";
18
+ import { outcomeOf } from "../../llm/structured-call.js";
32
19
  import { baseFailureFields, enoentHintMessage, isEnoentFailure } from "../agent/agent-support.js";
33
20
  import { createProposal, resolveProposalQueueTarget, } from "./repository.js";
34
21
  function failureEnvelope(result, type, name, engine, notices, fallbackReason = "non_zero_exit") {
@@ -44,7 +31,6 @@ function failureEnvelope(result, type, name, engine, notices, fallbackReason = "
44
31
  function noticeFields(notices) {
45
32
  return notices.length > 0 ? { notices } : {};
46
33
  }
47
- const DISPATCH_FAILED = Symbol("proposal-dispatch-failed");
48
34
  /**
49
35
  * Resolve, lower, and dispatch the already-rendered proposal prompt with the
50
36
  * proposal's JSON Schema as its output schema, and capture the reply. A reply
@@ -52,55 +38,41 @@ const DISPATCH_FAILED = Symbol("proposal-dispatch-failed");
52
38
  */
53
39
  async function dispatchProposalPrompt(prompt, config, options, onDispatchReady) {
54
40
  const current = {
55
- ...(options.engine !== undefined ? { engine: options.engine } : {}),
41
+ ...options.selection,
56
42
  ...(options.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
57
43
  outputSchema: PROPOSAL_JSON_SCHEMA,
58
44
  };
59
- const lower = (content) => {
60
- const prepared = resolveExecution({ content, config, current });
61
- return { prepared, lowered: buildExecution(prepared.request, prepared.runner) };
62
- };
63
- const { prepared, lowered } = lower(prompt);
64
- const engineName = prepared.request.engine.name;
65
- const announcement = fallbackAnnouncement(prepared.fallbackEngineName, engineName);
66
- if (announcement)
67
- warn(announcement);
68
- // Validate every required symbolic credential before the entry event opens
69
- // durable state. Provider/runtime failures still occur after the event,
70
- // preserving the command-attempt observability contract. The dispatch reads
71
- // the same caller environment.
72
- const envSource = options.runAgentOptions?.envSource;
73
- assertRunnerCredentials(lowered.runner, envSource);
45
+ // The target is resolved once; a corrective attempt rebuilds only the request, for the same runner.
46
+ const prepared = resolveExecution({
47
+ content: prompt,
48
+ config,
49
+ layers: [shippedAlias(SHIPPED_ALIAS.agent), currentLayer(current)],
50
+ });
51
+ const lowered = buildExecution(prepared.request, prepared.runner);
52
+ const corrected = (content) => buildExecution(resolveExecution({ content, runner: prepared.runner, layers: [currentLayer(current)] }).request, prepared.runner);
53
+ // Resolution and lowering come before the entry event opens durable state; provider and
54
+ // runtime failures occur after it, preserving the command-attempt observability contract.
55
+ const engineName = prepared.request.target.name;
74
56
  onDispatchReady();
75
57
  options.onDispatchReady?.();
76
- // runStructured dispatches at least once, so a returned or DISPATCH_FAILED exchange has a result.
58
+ // The loop dispatches at least once, so there is a result.
77
59
  const results = [];
78
- let reply;
79
- try {
80
- reply = await runStructured({
81
- dispatch: async (feedback) => {
82
- const execution = feedback ? lower(`${prompt}\n\n${feedback}`).lowered : lowered;
83
- const result = await runExecution(execution, { runOptions: options.runAgentOptions ?? {} });
84
- results.push(result);
85
- if (!result.ok)
86
- throw DISPATCH_FAILED;
87
- return unwrapHarnessReply(execution.runner, result).text;
88
- },
89
- validate: validateProposalPayload,
90
- });
91
- }
92
- catch (err) {
93
- if (err !== DISPATCH_FAILED)
94
- throw err;
95
- }
60
+ const reply = await structuredLoop({
61
+ dispatch: async (correction) => {
62
+ const execution = correction ? corrected(`${prompt}\n\n${correction.text}`) : lowered;
63
+ const result = await runExecution(execution);
64
+ results.push(result);
65
+ return outcomeOf(result);
66
+ },
67
+ parse: jsonParser(validateProposalPayload),
68
+ });
96
69
  return {
97
70
  result: results.at(-1),
98
- ...(reply ? { reply } : {}),
71
+ reply,
99
72
  durationMs: results.reduce((total, result) => total + result.durationMs, 0),
100
73
  engineName,
101
- ...(lowered.runner.kind === "llm" ? {} : { engineBin: lowered.runner.profile.bin }),
74
+ ...(lowered.runner.kind === "harness" ? { engineBin: lowered.runner.bin } : {}),
102
75
  notices: lowered.notices,
103
- sensitiveValues: collectDispatchSensitiveValues(lowered.runner, {}, envSource),
104
76
  };
105
77
  }
106
78
  /**
@@ -121,6 +93,7 @@ function proposeItemRef(bundleId, type, name) {
121
93
  * (`proposeItemRef`), so the entry event and the stored proposal agree.
122
94
  */
123
95
  function emitProposeInvoked(bundleId, options) {
96
+ const named = options.selection?.connection ?? options.selection?.harness ?? options.selection?.engine;
124
97
  appendEvent({
125
98
  eventType: "propose_invoked",
126
99
  ref: proposeItemRef(bundleId, options.type, options.name),
@@ -128,7 +101,7 @@ function emitProposeInvoked(bundleId, options) {
128
101
  type: options.type,
129
102
  name: options.name,
130
103
  task: options.task,
131
- ...(options.engine ? { engine: options.engine } : {}),
104
+ ...(named ? { engine: named } : {}),
132
105
  },
133
106
  });
134
107
  }
@@ -145,7 +118,7 @@ export async function akmPropose(options) {
145
118
  if (!stashDirFor(options.type)) {
146
119
  throw new UsageError(`propose: unknown asset type "${options.type}". Known types: ${[...placementTypes()].sort().join(", ")}.`, "INVALID_FLAG_VALUE");
147
120
  }
148
- // 1. Resolve the write target. Engine/model/inference resolution happens
121
+ // 1. Resolve the write target. Connection, harness, model and inference resolution happens
149
122
  // exactly once below through the shared execution cascade. `--bundle` names a
150
123
  // configured, writable bundle (same resolver and errors as `akm remember
151
124
  // --bundle`); its root becomes the stash the proposal is queued for and the
@@ -168,9 +141,9 @@ export async function akmPropose(options) {
168
141
  // request's output schema, with no synthetic persona, conversation turn, or
169
142
  // tool selection.
170
143
  const dispatch = await dispatchProposalPrompt(prompt, config, options, () => emitProposeInvoked(target.source, options));
171
- const { result, reply, engineName, notices, sensitiveValues } = dispatch;
172
- if (!reply) {
173
- // B3: ENOENT / not-found gives an actionable hint.
144
+ const { result, reply, engineName, notices } = dispatch;
145
+ if (!reply.ok && !isRefused(reply)) {
146
+ // The dispatch failed. B3: ENOENT / not-found gives an actionable hint.
174
147
  if (isEnoentFailure(result)) {
175
148
  return {
176
149
  ...failureEnvelope(result, options.type, options.name, engineName, notices),
@@ -179,7 +152,7 @@ export async function akmPropose(options) {
179
152
  }
180
153
  return failureEnvelope(result, options.type, options.name, engineName, notices);
181
154
  }
182
- // 5. The proposal the engine returned on stdout, validated.
155
+ // 5. The proposal the model returned on stdout, validated.
183
156
  if (!reply.ok) {
184
157
  return {
185
158
  schemaVersion: 2,
@@ -196,7 +169,7 @@ export async function akmPropose(options) {
196
169
  };
197
170
  }
198
171
  const payload = reply.value;
199
- const unsafeContent = generatedContentRejection(payload.content, redactSensitiveText(payload.content, sensitiveValues));
172
+ const unsafeContent = generatedContentRejection(payload.content);
200
173
  if (unsafeContent) {
201
174
  return {
202
175
  schemaVersion: 2,
@@ -446,7 +446,7 @@ export function resolveProposalIdIn(db, stashDir, idOrRef) {
446
446
  return exact;
447
447
  if (idOrRef.includes(":") || idOrRef.includes("/")) {
448
448
  const wantRef = filterRefIdentity(idOrRef);
449
- // Should-fix 7: by-ref resolution never picks a retire proposal — the
449
+ // By-ref resolution never picks a retire proposal — the
450
450
  // newest pending proposal for a ref could be a `consolidate-pair`
451
451
  // retirement rather than the reflect/distill edit a person typed the
452
452
  // ref to accept, and accepting it archives the asset instead. A retire
@@ -1226,7 +1226,7 @@ async function promoteProposalWithLease(stashDir, config, id, options, ctx) {
1226
1226
  * Every archive dir a tombstone under `.akm/memory-cleanup/archive/` claims
1227
1227
  * for `proposalId` — the primary asset's, and its `.derived` twin's if one
1228
1228
  * was archived alongside it. Used to detect what a resumed retire accept
1229
- * (should-fix 5) has already moved.
1229
+ * has already moved.
1230
1230
  */
1231
1231
  function findRetireArchiveDirsByProposalId(stashRoot, proposalId) {
1232
1232
  const archiveRoot = path.join(stashRoot, ".akm", "memory-cleanup", "archive");
@@ -1267,7 +1267,7 @@ function alreadyArchivedOriginalPaths(stashRoot, dirs) {
1267
1267
  return paths;
1268
1268
  }
1269
1269
  /**
1270
- * Should-fix 5: record a retire accept's intent — `backupContent` and which
1270
+ * Record a retire accept's intent — `backupContent` and which
1271
1271
  * files (asset, `.derived` twin) are about to move — on the still-pending
1272
1272
  * proposal BEFORE any file is moved. A crash after this point resumes from
1273
1273
  * exactly this record instead of re-deriving `backupContent` from whatever
@@ -1287,7 +1287,7 @@ function recordRetireAcceptIntent(stashDir, proposalId, intent, ctx) {
1287
1287
  /**
1288
1288
  * Persist a retire's "accepted" decision — the row, its ledger decision and
1289
1289
  * its event — the one finalize step a fresh accept and one resumed after a
1290
- * crash (should-fix 5) share: by the time either calls it, every file move
1290
+ * crash share: by the time either calls it, every file move
1291
1291
  * is already confirmed done. Mirrors the accept branch of
1292
1292
  * {@link persistProposalDecision}, kept separate since a retire's
1293
1293
  * accepted-shape fields (`retiredArchive`, no published `content`) do not
@@ -1347,10 +1347,10 @@ function persistRetireAcceptance(stashDir, proposal, info, ctx) {
1347
1347
  }));
1348
1348
  }
1349
1349
  /**
1350
- * B2: throws a stale-retire `UsageError` unless the successor still exists
1350
+ * Throws a stale-retire `UsageError` unless the successor still exists
1351
1351
  * and both sides' recorded body hashes and judged scopes still match — the
1352
- * durable half of the chain guard. Used for a fresh accept, and (4b, third
1353
- * review round) to re-check a resumed accept whose intent was recorded but
1352
+ * durable half of the chain guard. Used for a fresh accept, and to
1353
+ * re-check a resumed accept whose intent was recorded but
1354
1354
  * nothing has moved yet: a separate proposal accepted in between (e.g. this
1355
1355
  * one's successor itself retired by a B->C accept) can make the decision
1356
1356
  * stale even though nothing about the retired side's own file changed.
@@ -1377,15 +1377,15 @@ function assertRetirementStillFresh(proposalId, proposalRef, retirement, targetS
1377
1377
  }
1378
1378
  /**
1379
1379
  * Accept a `retire` proposal (0.9.17-alpha.9, the consolidate pair pass): no
1380
- * new content is written. Should-fix 5 (second review round) makes this a
1380
+ * new content is written. It is a
1381
1381
  * three-phase, resume-safe sequence: (1) record intent — `backupContent`
1382
1382
  * and the exact files about to move — on the still-pending proposal; (2)
1383
1383
  * move each file into the recoverable cleanup archive
1384
1384
  * (`archiveCleanupCandidate`), skipping any the tombstone scan shows a prior,
1385
1385
  * crashed attempt already moved; (3) finalize via
1386
1386
  * {@link persistRetireAcceptance}. A `supersedes` judgement writes the
1387
- * supersede edge on the retired (older) side AFTER intent is recorded (4a,
1388
- * third review round — recording it first means a crash before the edge
1387
+ * supersede edge on the retired (older) side AFTER intent is recorded —
1388
+ * recording it first means a crash before the edge
1389
1389
  * write can never cause a resume to re-read the file and capture its own
1390
1390
  * edge into `backupContent`), so the archived copy still preserves it. A
1391
1391
  * target already gone with no recorded intent (raced with something else)
@@ -1429,8 +1429,8 @@ async function retireProposalWithLease(stashDir, config, proposal, options, ctx)
1429
1429
  // `retiredThisRun` in pair-pass.ts):
1430
1430
  assertRetirementStillFresh(proposal.id, proposal.ref, retirement, target.source, currentBytes);
1431
1431
  assertAkmAssetWrite(target.source);
1432
- // Phase 1: record intent BEFORE any move, and BEFORE the supersede edge
1433
- // (4a, third review round) — `backupContent` is `currentBytes`, read
1432
+ // Phase 1: record intent BEFORE any move, and BEFORE the supersede edge:
1433
+ // `backupContent` is `currentBytes`, read
1434
1434
  // above, before any mutation of this file. Recording first means a crash
1435
1435
  // between here and the edge write below can never cause a resume to
1436
1436
  // re-read the file and capture the edge INTO backupContent as if it were
@@ -1472,7 +1472,7 @@ async function retireProposalWithLease(stashDir, config, proposal, options, ctx)
1472
1472
  archiveDirs.push(path.dirname(record.auditPath));
1473
1473
  paths.push(intent.assetPath, path.join(mutationTarget.source.path, record.archivedPath), path.join(mutationTarget.source.path, record.auditPath));
1474
1474
  }
1475
- // 4d (third review round): the twin path is re-derived, not carried on the
1475
+ // The twin path is re-derived, not carried on the
1476
1476
  // intent — it is a pure function of assetPath and the ref's type, and the
1477
1477
  // tombstone scan above (`alreadyDone`) already finds one archived earlier,
1478
1478
  // so storing it was redundant persisted state.
@@ -1528,7 +1528,7 @@ export async function revertProposal(stashDir, config, id, options = {}, ctx) {
1528
1528
  * tombstone names the exact paths to restore — no re-scan of every
1529
1529
  * tombstone in the archive.
1530
1530
  *
1531
- * Should-fix 5 (second review round): every archive dir is resolved and
1531
+ * Every archive dir is resolved and
1532
1532
  * validated before any of them are moved, AND that validation tells "not
1533
1533
  * yet moved" apart from "already moved by an earlier, crashed attempt of
1534
1534
  * our own" (original present, archived copy gone) rather than treating the
@@ -1591,7 +1591,7 @@ async function unretireProposalWithLease(stashDir, config, proposal, options, ct
1591
1591
  if (!originalExists && !archivedExists && !fromBackup) {
1592
1592
  throw new UsageError(`Cannot revert proposal ${proposal.id}: archived copy ${archivedRel} is missing.`, "INVALID_FLAG_VALUE");
1593
1593
  }
1594
- // Must-fix 2 (third review round): "original present, archived copy
1594
+ // "original present, archived copy
1595
1595
  // missing" is not necessarily our own earlier, crashed revert — once a
1596
1596
  // purge can delete an archived copy on its own, a LATER, unrelated file
1597
1597
  // can occupy this same path (a new memory reusing a retired one's name),
@@ -1714,8 +1714,8 @@ async function revertProposalWithLease(stashDir, config, id, options, ctx) {
1714
1714
  }
1715
1715
  const target = prepareWriteTargetForMutation(boundTarget);
1716
1716
  if (!fs.existsSync(assetPath) || contentHash(fs.readFileSync(assetPath)) !== recorded.contentHash) {
1717
- // Nit (third review round): by-ref resolution skips retire proposals
1718
- // (should-fix 7), so reverting by ref when a SEPARATE retire proposal
1717
+ // By-ref resolution skips retire proposals, so reverting by ref when a
1718
+ // SEPARATE retire proposal
1719
1719
  // for the same ref exists (pending or already accepted) lands here with
1720
1720
  // no clue that proposal is the real story — name it when one does.
1721
1721
  const siblingRetire = listProposalsReadOnly(stashDir, { ref: proposal.ref, includeArchive: true }, ctx).find((p) => isRetireProposal(p) && (p.status === "pending" || p.status === "accepted"));
@@ -52,8 +52,8 @@ const canonicalProposalValidators = {
52
52
  const name = ctx.parsedRef?.name;
53
53
  if (!name)
54
54
  return [];
55
- // Version-routing seam (spec docs/plans/specs/p2a-task-source-v4.md
56
- // §3.6): a proposal body is validated by parsing alone — neither arm's
55
+ // Version-routing seam: a proposal body is validated by parsing alone —
56
+ // neither arm's
57
57
  // parsed document is inspected further, so routing through the union is
58
58
  // a pure swap; any parse failure (either version) is turned into an
59
59
  // `invalid-task-structure` finding by the try/catch this call sits in.
@@ -80,10 +80,7 @@ const canonicalProposalValidators = {
80
80
  ];
81
81
  }
82
82
  const sourcePath = proposal.changes[0]?.path || proposal.ref;
83
- const result = compileWorkflowSource(content, {
84
- path: sourcePath,
85
- workspaceRoot: proposal.proposedTarget.root,
86
- });
83
+ const result = compileWorkflowSource(content, { path: sourcePath });
87
84
  if (result.ok)
88
85
  return [];
89
86
  return result.errors.map((error) => ({
@@ -28,7 +28,6 @@ import { matchBeliefFilter, searchHitContent } from "../../indexer/search/db-sea
28
28
  import { copySearchHitAttribution, getSearchHitAttribution, usageEventAttributionMetadata, } from "../../indexer/search/search-attribution.js";
29
29
  import { insertUsageEvent } from "../../indexer/usage/usage-events.js";
30
30
  import { estimateTokenCount } from "../../llm/embedders/remote.js";
31
- import { isLlmFeatureEnabled, tryLlmFeature } from "../../llm/feature-gate.js";
32
31
  import { rerankDocuments } from "../../llm/rerank-client.js";
33
32
  import { truncateDescription } from "../../output/shapes/helpers.js";
34
33
  import { TELEMETRY_BUSY_TIMEOUT_MS, withIndexDb } from "../../storage/repositories/index-db.js";
@@ -188,7 +187,7 @@ export async function curateSearchResults(query, result, limit, selectedType, ev
188
187
  * `budgetTokens`.
189
188
  *
190
189
  * Registry hits are never packed — only `CuratedStashItem`s (locked
191
- * contract, AGENTS.md: registry results stay separate/opt-in).
190
+ * contract: registry results stay separate/opt-in).
192
191
  *
193
192
  * Truncation policy: drop whole hits from the tail of the ranked list first.
194
193
  * The only exception is a single high-rank hit that alone exceeds the
@@ -337,7 +336,7 @@ function buildCurateSummary(query, items) {
337
336
  }
338
337
  /** How many fused candidates curate fetches for the reranker; 0 when reranking is off. */
339
338
  function rerankTopN(config) {
340
- if (!isLlmFeatureEnabled(config, "curate_rerank"))
339
+ if (!config.search?.curateRerank?.enabled)
341
340
  return 0;
342
341
  return config.search?.curateRerank?.topN ?? DEFAULT_CURATE_RERANK_TOP_N;
343
342
  }
@@ -355,15 +354,20 @@ async function maybeRerankCuratedStashHits(query, hits) {
355
354
  return hits;
356
355
  const config = loadConfig();
357
356
  const rerankConfig = config.search?.curateRerank;
358
- return tryLlmFeature("curate_rerank", config, async () => {
357
+ if (!rerankConfig?.enabled)
358
+ return hits;
359
+ try {
359
360
  const head = hits.slice(0, rerankTopN(config));
360
361
  const tail = hits.slice(head.length);
361
- const ranked = await rerankDocuments(rerankConfig ?? {}, query, rerankDocumentTexts(head));
362
+ const ranked = await rerankDocuments(rerankConfig, query, rerankDocumentTexts(head));
362
363
  const rerankedHead = ranked
363
364
  .map(({ index }) => head[index])
364
365
  .filter((hit) => hit !== undefined);
365
366
  return [...rerankedHead, ...tail];
366
- }, hits, { timeoutMs: rerankConfig?.timeoutMs ?? null });
367
+ }
368
+ catch {
369
+ return hits;
370
+ }
367
371
  }
368
372
  /**
369
373
  * Name, description and the start of each hit's indexed content, capped for