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
@@ -2,9 +2,9 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  /**
5
- * `akm reflect [ref]` — ask an engine whether an asset's `description`,
5
+ * `akm reflect [ref]` — ask a model whether an asset's `description`,
6
6
  * `when_to_use` and title need a fix, and queue the asset with that fix as a
7
- * proposal (`source: "reflect"`). The engine never writes the body: akm keeps
7
+ * proposal (`source: "reflect"`). The model never writes the body: akm keeps
8
8
  * it byte for byte. Reflect never writes an asset: the proposal queue is the
9
9
  * only path, `akm proposal accept` the bridge.
10
10
  *
@@ -21,23 +21,21 @@ import { parseRefInput } from "../../core/asset/resolve-ref.js";
21
21
  import { DESCRIPTION_MAX_CHARS, requiresDescription } from "../../core/authoring-rules.js";
22
22
  import { isWithin, resolveStashDir, safeRealpath } from "../../core/common.js";
23
23
  import { loadConfig } from "../../core/config/config.js";
24
+ import { SHIPPED_ALIAS } from "../../core/config/model-aliases.js";
24
25
  import { generatedContentRejection } from "../../core/content-safety.js";
25
26
  import { ConfigError, UsageError } from "../../core/errors.js";
26
27
  import { appendEvent, readEvents } from "../../core/events.js";
27
28
  import { lintLessonContent } from "../../core/lesson-lint.js";
28
29
  import { parseEmbeddedJsonResponse } from "../../core/parse.js";
29
- import { redactSensitiveText } from "../../core/redaction.js";
30
30
  import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
31
- import { warn, warnOnce } from "../../core/warn.js";
31
+ import { warnOnce } from "../../core/warn.js";
32
+ import { noticeSet } from "../../execution/notices.js";
32
33
  import { lookup } from "../../indexer/indexer.js";
33
- import { DEFAULT_LLM_TIMEOUT_MS } from "../../integrations/agent/config.js";
34
- import { fallbackAnnouncement, NO_ENGINE_MESSAGE_SUFFIX, NO_ENGINE_REMEDY, withEngineFallback, } from "../../integrations/agent/engine-fallback.js";
35
- import { buildExecution, resolveExecution } from "../../integrations/agent/execution.js";
36
34
  import { buildReflectOutputRepairPrompt, buildReflectPrompt, REFLECT_CONTENT_CAP, } from "../../integrations/agent/prompts.js";
37
- import { runnerIsLlm } from "../../integrations/agent/runner.js";
38
- import { assertRunnerCredentials, collectDispatchSensitiveValues, } from "../../integrations/agent/runner-dispatch.js";
39
- import { isJsonSchemaKnownUnsupported, LlmCallError } from "../../llm/client.js";
40
- import { baseFailureFields, enoentHintMessage, isEnoentFailure } from "../agent/agent-support.js";
35
+ import { getHarness } from "../../integrations/harnesses/index.js";
36
+ import { isJsonSchemaKnownUnsupported } from "../../llm/client.js";
37
+ import { isRefused, structuredLoop } from "../../llm/structured.js";
38
+ import { enoentHintMessage, isEnoentFailure } from "../agent/agent-support.js";
41
39
  import { isValidDescription } from "../proposal/validators/proposal-quality-validators.js";
42
40
  import { CHARS_PER_TOKEN, DEFAULT_CONTEXT_LENGTH_TOKENS } from "./consolidate/chunking.js";
43
41
  import { contentHash } from "./content-hash.js";
@@ -45,7 +43,7 @@ import { findAssetFilePath } from "./eligibility.js";
45
43
  import { resolveImproveExecution } from "./execution.js";
46
44
  import { recordLedgerAttempt } from "./ledger.js";
47
45
  import { bodyHasH1, classifyReflectChange, findReflectDefect, splitFrontmatter, } from "./reflect-noise.js";
48
- import { callStageOnce, errMessage, mintProposal, noticeSet, rejectedProposalContext, resolveQualityGateJudge, runReflectQualityJudge, } from "./stage.js";
46
+ import { callStageOnce, errMessage, mintProposal, rejectedProposalContext, resolveQualityGateJudge, runReflectQualityJudge, } from "./stage.js";
49
47
  const MAX_FEEDBACK_LINES = 10;
50
48
  const MAX_GLOBAL_FEEDBACK_LINES = 20;
51
49
  /** Ends a feedback line whose event judged text the asset no longer has. */
@@ -229,10 +227,10 @@ function patchFrontmatterLines(fmText, changes) {
229
227
  }
230
228
  // ── Output contract ──────────────────────────────────────────────────────────
231
229
  //
232
- // Every engine kind is asked for the same reply: the JSON object of
233
- // REFLECT_JSON_SCHEMA, or the framed-markdown frame for an LLM engine that
234
- // rejects JSON Schema. The reply is validated by the parse functions below and
235
- // repaired once, whatever engine produced it.
230
+ // A connection and a harness are asked for the same reply: the JSON object of
231
+ // REFLECT_JSON_SCHEMA, or the framed-markdown frame for a connection whose
232
+ // endpoint rejects JSON Schema. The reply is validated by the parse functions
233
+ // below and repaired once, whatever produced it.
236
234
  const REFLECT_FRONTMATTER_PATCH_JSON_SCHEMA = {
237
235
  type: "object",
238
236
  required: ["description", "when_to_use", "title"],
@@ -269,26 +267,11 @@ export const REFLECT_UNSCOPED_JSON_SCHEMA = {
269
267
  },
270
268
  };
271
269
  /**
272
- * Frame for JSON Schema unless the LLM connection disabled it or already proved
270
+ * Frame for JSON Schema unless the connection already proved
273
271
  * this process that it rejects it (the transport retries plain text on a 4xx).
274
272
  */
275
273
  function wantsJsonSchemaOutput(connection) {
276
- return connection.supportsJsonSchema !== false && !isJsonSchemaKnownUnsupported(connection);
277
- }
278
- /** Injected between the prior draft and the refinement request (self-refine). */
279
- const REFLECT_CRITIQUE_PROMPT = "Your previous proposal is shown above. Review it critically and provide an improved version that is more specific, actionable, and avoids any issues with the previous attempt. Return only the improved response using the output contract from the original prompt.";
280
- function parsedRecord(result) {
281
- return result.parsed && typeof result.parsed === "object" && !Array.isArray(result.parsed)
282
- ? result.parsed
283
- : undefined;
284
- }
285
- function reflectTelemetry(result) {
286
- const parsed = parsedRecord(result);
287
- if (!parsed || (parsed.outputMode !== "json_schema" && parsed.outputMode !== "framed_markdown"))
288
- return undefined;
289
- if (typeof parsed.repairAttempts !== "number")
290
- return undefined;
291
- return { outputMode: parsed.outputMode, repairAttempts: parsed.repairAttempts };
274
+ return !isJsonSchemaKnownUnsupported(connection);
292
275
  }
293
276
  function parseReflectConfidence(value) {
294
277
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 1) {
@@ -366,130 +349,121 @@ function parseFramedReflectOutput(raw, targetRef) {
366
349
  patch: parseReflectFrontmatterPatch(parsedPatch),
367
350
  };
368
351
  }
352
+ /** A failure only a message describes, as a process that printed it and exited would have: what a connection reports. */
353
+ function messageFailure(error, reason, stdout = "", exitCode = 1) {
354
+ return { reason, error, exitCode, stdout, stderr: error };
355
+ }
356
+ /** How a failed dispatch is reported: an agent as it ran (exit code, streams, reason), a connection by its message. */
357
+ function dispatchFailure(outcome, runner, signal) {
358
+ const result = runner.kind === "connection" ? undefined : outcome.result;
359
+ if (result) {
360
+ const reason = result.reason ?? "non_zero_exit";
361
+ return {
362
+ reason,
363
+ error: result.error ?? `agent failure (${reason})`,
364
+ exitCode: result.exitCode,
365
+ stdout: result.stdout,
366
+ stderr: result.stderr,
367
+ };
368
+ }
369
+ return messageFailure(outcome.error, signal?.aborted || outcome.reason === "aborted"
370
+ ? "aborted"
371
+ : outcome.reason === "timeout"
372
+ ? "timeout"
373
+ : "non_zero_exit");
374
+ }
369
375
  /**
370
- * One reflect iteration on any engine, as an agent-shaped result (errors
371
- * captured, never thrown except configuration). Every engine kind is sent the
372
- * same request, with the reply's schema as the output schema, and its reply is
373
- * held to the same contract: an unparseable reply gets one repair turn within
374
- * the original deadline, then fails. A failed agent or SDK dispatch is reported
375
- * as it ran, with its exit code and stderr; an LLM call has only its message.
376
+ * One reflect call on a connection or a harness (errors captured, never thrown except
377
+ * configuration). A connection and a harness are sent the same request, with the reply's
378
+ * schema as the output schema, and its reply is held to the same contract: an
379
+ * unparseable reply gets one repair turn within the original deadline, then
380
+ * fails. A failed agent dispatch is reported as it ran, with its exit code and
381
+ * stderr; an LLM call has only its message.
376
382
  */
377
383
  export async function runReflectIteration(opts) {
378
384
  const start = Date.now();
379
385
  let repairAttempts = 0;
380
- // Model work is bounded: with no timeout from the caller or the runner, the default.
381
- const configuredTimeout = Object.hasOwn(opts, "timeoutMs")
382
- ? (opts.timeoutMs ?? null)
383
- : Object.hasOwn(opts.runner, "timeoutMs")
384
- ? (opts.runner.timeoutMs ?? null)
385
- : DEFAULT_LLM_TIMEOUT_MS;
386
+ const configuredTimeout = Object.hasOwn(opts, "timeoutMs") ? (opts.timeoutMs ?? null) : opts.runner.timeoutMs;
386
387
  const deadline = typeof configuredTimeout === "number" ? start + configuredTimeout : undefined;
387
388
  const messages = [{ role: "user", content: opts.prompt ?? "" }];
388
- if (opts.priorDraft !== undefined && opts.iteration > 0) {
389
- messages.push({ role: "assistant", content: opts.priorDraft }, { role: "user", content: REFLECT_CRITIQUE_PROMPT });
390
- }
391
- const parse = (raw) => opts.outputMode === "json_schema"
392
- ? parseSchemaReflectOutput(raw, opts.targetRef)
393
- : parseFramedReflectOutput(raw, opts.targetRef);
394
- const failure = (err, reason, stdout = "", exitCode = 1) => {
395
- const msg = errMessage(err);
396
- return {
397
- ok: false,
398
- stdout,
399
- stderr: msg,
400
- durationMs: Date.now() - start,
401
- exitCode,
402
- reason,
403
- error: msg,
404
- parsed: { outputMode: opts.outputMode, repairAttempts },
405
- };
406
- };
407
- // A reply that broke the contract; its message is the parser's, on every engine kind.
408
- const invalidReply = (err, reply) => failure(err, "parse_error", reply, 0);
409
- // The result of the dispatch that failed, kept for an agent or SDK engine.
410
- let dispatched;
411
- // Reflect parses and repairs its own reply (the repair turn below), so one dispatch, unvalidated.
412
- const call = async (callMessages, repairTimeoutMs) => {
413
- const outcome = await callStageOnce({
414
- feature: "reflect_proposal",
415
- runner: opts.runner,
416
- prompt: callMessages.at(-1)?.content ?? "",
417
- history: callMessages.slice(0, -1),
418
- request: {
419
- ...(repairTimeoutMs !== undefined
420
- ? { timeoutMs: repairTimeoutMs }
421
- : Object.hasOwn(opts, "timeoutMs")
422
- ? { timeoutMs: opts.timeoutMs }
423
- : {}),
424
- ...(opts.signal ? { signal: opts.signal } : {}),
425
- ...(opts.responseSchema !== undefined ? { responseSchema: opts.responseSchema } : {}),
426
- ...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),
427
- // Visible chain-of-thought can exhaust the output before the envelope.
428
- enableThinking: false,
429
- ...(opts.chat ? { chat: opts.chat } : {}),
430
- ...(opts.runSdk ? { runSdk: opts.runSdk } : {}),
431
- ...(opts.runOptions ? { runOptions: opts.runOptions } : {}),
432
- },
433
- ...(opts.environment ? { current: { environment: opts.environment } } : {}),
434
- ...(opts.onNotices ? { onNotices: opts.onNotices } : {}),
435
- });
436
- if (!outcome.ok) {
437
- if (!runnerIsLlm(opts.runner))
438
- dispatched = outcome.result;
439
- throw outcome.reason === "timeout"
440
- ? new LlmCallError(outcome.error ?? "timeout", "timeout")
441
- : new Error(outcome.error ?? "dispatch failed");
389
+ const parse = (raw) => {
390
+ try {
391
+ return {
392
+ ok: true,
393
+ value: opts.outputMode === "json_schema"
394
+ ? parseSchemaReflectOutput(raw, opts.targetRef)
395
+ : parseFramedReflectOutput(raw, opts.targetRef),
396
+ };
397
+ }
398
+ catch (err) {
399
+ return { ok: false, errors: [errMessage(err)] };
442
400
  }
443
- return outcome.raw;
444
401
  };
402
+ const failed = (failure) => ({
403
+ ok: false,
404
+ durationMs: Date.now() - start,
405
+ telemetry: { outputMode: opts.outputMode, repairAttempts },
406
+ ...failure,
407
+ });
408
+ // Reflect parses and repairs its own reply (the repair turn below), so one dispatch, unvalidated.
409
+ const call = (callMessages, repairTimeoutMs) => callStageOnce({
410
+ runner: opts.runner,
411
+ prompt: callMessages.at(-1)?.content ?? "",
412
+ history: callMessages.slice(0, -1),
413
+ request: {
414
+ ...(repairTimeoutMs !== undefined
415
+ ? { timeoutMs: repairTimeoutMs }
416
+ : Object.hasOwn(opts, "timeoutMs")
417
+ ? { timeoutMs: opts.timeoutMs }
418
+ : {}),
419
+ ...(opts.signal ? { signal: opts.signal } : {}),
420
+ ...(opts.responseSchema !== undefined ? { responseSchema: opts.responseSchema } : {}),
421
+ ...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),
422
+ // Visible chain-of-thought can exhaust the output before the envelope.
423
+ enableThinking: false,
424
+ ...(opts.chat ? { chat: opts.chat } : {}),
425
+ },
426
+ ...(opts.environment ? { current: { environment: opts.environment } } : {}),
427
+ ...(opts.onNotices ? { onNotices: opts.onNotices } : {}),
428
+ });
445
429
  try {
446
430
  if (opts.signal?.aborted)
447
- throw new Error("Reflect request aborted");
448
- const stdout = await call(messages);
449
- let payload;
450
- let acceptedOutput = stdout;
451
- try {
452
- payload = parse(stdout);
453
- }
454
- catch (err) {
455
- if (opts.allowRepair === false)
456
- return invalidReply(err, stdout);
457
- if (opts.signal?.aborted)
458
- return failure(new Error("Reflect request aborted"), "aborted", stdout);
459
- const remaining = deadline === undefined ? undefined : deadline - Date.now();
460
- if (remaining !== undefined && remaining <= 0) {
461
- return failure(new LlmCallError("Reflect request timed out before output repair", "timeout"), "timeout", stdout);
462
- }
463
- repairAttempts = 1;
464
- const repairPrompt = buildReflectOutputRepairPrompt(opts.outputMode, opts.targetRef !== undefined);
465
- acceptedOutput = await call([...messages, { role: "assistant", content: stdout }, { role: "user", content: repairPrompt }], remaining);
466
- try {
467
- payload = parse(acceptedOutput);
468
- }
469
- catch (repairErr) {
470
- return invalidReply(repairErr, acceptedOutput);
471
- }
431
+ return failed(messageFailure("Reflect request aborted", "aborted"));
432
+ const loop = await structuredLoop({
433
+ dispatch: async (correction) => {
434
+ if (!correction)
435
+ return call(messages);
436
+ // The repair turn spends what is left of the original deadline, and does not start once the caller has aborted.
437
+ if (opts.signal?.aborted)
438
+ return { ok: false, reason: "aborted", error: "Reflect request aborted" };
439
+ const remaining = deadline === undefined ? undefined : deadline - Date.now();
440
+ if (remaining !== undefined && remaining <= 0) {
441
+ return { ok: false, reason: "timeout", error: "Reflect request timed out before output repair" };
442
+ }
443
+ repairAttempts = 1;
444
+ const repair = `${buildReflectOutputRepairPrompt(opts.outputMode, opts.targetRef !== undefined)}\n\nWhat was wrong with it: ${correction.text}`;
445
+ return call([...messages, { role: "assistant", content: correction.reply }, { role: "user", content: repair }], remaining);
446
+ },
447
+ parse,
448
+ correct: (refusal) => refusal.errors.join("; "),
449
+ });
450
+ if (!loop.ok) {
451
+ // A reply that broke the contract: its message is the parser's, on a connection and a harness alike.
452
+ if (isRefused(loop))
453
+ return failed(messageFailure(loop.errors.join("; "), "parse_error", loop.raw, 0));
454
+ return failed(dispatchFailure(loop, opts.runner, opts.signal));
472
455
  }
473
456
  return {
474
457
  ok: true,
475
- stdout: JSON.stringify(payload),
476
- stderr: "",
458
+ payload: loop.value,
477
459
  durationMs: Date.now() - start,
478
- exitCode: 0,
479
- parsed: { outputMode: opts.outputMode, repairAttempts, priorDraft: acceptedOutput },
460
+ telemetry: { outputMode: opts.outputMode, repairAttempts },
480
461
  };
481
462
  }
482
463
  catch (err) {
483
464
  if (err instanceof ConfigError)
484
465
  throw err;
485
- if (dispatched)
486
- return { ...dispatched, parsed: { outputMode: opts.outputMode, repairAttempts } };
487
- const reason = opts.signal?.aborted
488
- ? "aborted"
489
- : err instanceof LlmCallError && err.code === "timeout"
490
- ? "timeout"
491
- : "non_zero_exit";
492
- return failure(err, reason);
466
+ return failed(messageFailure(errMessage(err), opts.signal?.aborted ? "aborted" : "non_zero_exit"));
493
467
  }
494
468
  }
495
469
  /** The lazy `reflect_invoked` + failure-side `reflect_completed` emitters. */
@@ -503,7 +477,6 @@ function reflectEmitters(options) {
503
477
  ...(options.ref ? { ref: options.itemRef ?? options.ref } : {}),
504
478
  metadata: {
505
479
  ...(options.task ? { task: options.task } : {}),
506
- ...(options.engine ? { engine: options.engine } : {}),
507
480
  ...(options.eligibilitySource ? { eligibilitySource: options.eligibilitySource } : {}),
508
481
  },
509
482
  }, options.eventsCtx);
@@ -519,22 +492,27 @@ function reflectEmitters(options) {
519
492
  };
520
493
  return { emitInvoked, emitFailed };
521
494
  }
522
- /** A post-dispatch failure envelope (with the run's notices). */
523
- function reflectFailure(run, result, reason, error, withOutput) {
495
+ /** The failure envelope for `failure` (with the run's notices). */
496
+ function reflectFailure(run, failure) {
524
497
  return {
525
498
  schemaVersion: 2,
526
499
  ok: false,
527
- reason,
528
- error,
500
+ reason: failure.reason,
501
+ error: failure.error,
529
502
  ...(run.options.ref ? { ref: run.options.ref } : {}),
530
503
  engine: run.engineName,
531
- exitCode: result.exitCode,
532
- ...(withOutput ? { stdout: result.stdout, ...(result.stderr ? { stderr: result.stderr } : {}) } : {}),
504
+ exitCode: failure.exitCode,
505
+ ...(failure.stdout ? { stdout: failure.stdout } : {}),
506
+ ...(failure.stderr ? { stderr: failure.stderr } : {}),
533
507
  ...run.notices.fields(),
534
508
  };
535
509
  }
536
- function exitCodeMeta(result) {
537
- return result.exitCode !== null ? { exitCode: result.exitCode } : {};
510
+ /** A failure after a dispatch that succeeded: the exit code is its, there is no output to report. */
511
+ function refusal(reason, error) {
512
+ return { reason, error, exitCode: 0 };
513
+ }
514
+ function exitCodeMeta(failure) {
515
+ return failure.exitCode !== null ? { exitCode: failure.exitCode } : {};
538
516
  }
539
517
  function unsupportedTypeFailure(ref, type, detail, emitFailed) {
540
518
  emitFailed("unsupported_type", "unsupported_type", ref, { type });
@@ -613,74 +591,53 @@ async function resolveReflectSource(options, stash, emitFailed) {
613
591
  return { assetContent, parsedRef };
614
592
  }
615
593
  /**
616
- * The single engine for this invocation: `--engine`, the improve strategy's
617
- * reflect process, or `defaults.engine` (announced when it falls back to the
618
- * SDK binary). Whatever its kind, reflect runs it under the model-work tool
619
- * policy.
594
+ * The single connection or harness for this invocation: the one the improve
595
+ * plan froze for reflect, else reflect's place in improve's cascade. Whatever
596
+ * its kind, reflect runs it under the model-work tool policy.
620
597
  */
621
598
  function resolveReflectRunner(options) {
622
599
  const config = options.config ?? loadConfig();
623
- const activeStrategy = options.improveProfile ?? config.improve?.strategies?.[config.defaults?.improveStrategy ?? "default"];
624
- const lower = (selection) => {
625
- const prepared = resolveExecution(selection);
626
- return buildExecution(prepared.request, prepared.runner);
627
- };
628
- let lowered;
629
- if (options.engine) {
630
- lowered = lower({ content: "reflect engine selection", config, current: { engine: options.engine } });
631
- }
632
- else if (options.improveProfile) {
633
- const resolved = resolveImproveExecution({
600
+ const activeStrategy = options.improveProfile ?? config.improve?.strategies?.[config.improve?.strategy ?? "default"];
601
+ // The plan resolved reflect's runner once, with its notices; each asset does not resolve it again.
602
+ const resolved = Object.hasOwn(options, "llmRunner")
603
+ ? options.llmRunner
604
+ ? { runner: options.llmRunner, notices: [] }
605
+ : null
606
+ : resolveImproveExecution({
634
607
  config,
635
- profile: activeStrategy,
636
- process: activeStrategy?.processes?.reflect,
637
608
  processName: "reflect",
609
+ alias: SHIPPED_ALIAS.improve,
610
+ ...(options.run ? { run: options.run } : {}),
638
611
  });
639
- if (!resolved) {
640
- throw new ConfigError("Reflect requires an engine for the active improve strategy.", "LLM_NOT_CONFIGURED", "Set defaults.llmEngine or improve.strategies.<name>.processes.reflect.engine.");
641
- }
642
- lowered = resolved;
612
+ if (!resolved) {
613
+ throw new ConfigError("Reflect requires a connection or harness for the active improve strategy.", "LLM_NOT_CONFIGURED", "Run `akm setup`, or set improve.connection or improve.processes.reflect.connection.");
643
614
  }
644
- else {
645
- const { config: engineConfig, fallbackEngineName } = withEngineFallback(config);
646
- const defaultEngine = engineConfig.defaults?.engine;
647
- const announcement = fallbackAnnouncement(fallbackEngineName, defaultEngine);
648
- if (announcement)
649
- warn(announcement);
650
- if (!defaultEngine) {
651
- throw new ConfigError(`reflect ${NO_ENGINE_MESSAGE_SUFFIX} ${NO_ENGINE_REMEDY}`, "INVALID_CONFIG_FILE");
652
- }
653
- lowered = lower({ content: "reflect engine selection", config });
654
- }
655
- const runnerSpec = lowered.runner;
656
- const engineName = runnerSpec.engine ?? options.engine;
657
- if (!engineName)
658
- throw new ConfigError("Reflect requires a named engine.", "INVALID_CONFIG_FILE");
659
- return { config, activeStrategy, runnerSpec, engineName, notices: lowered.notices };
615
+ return {
616
+ config,
617
+ activeStrategy,
618
+ runnerSpec: resolved.runner,
619
+ engineName: resolved.runner.name,
620
+ notices: resolved.notices,
621
+ };
660
622
  }
661
- /**
662
- * Lower a runner under the model-work tool policy and check its credentials,
663
- * so a bad transport, or one that cannot confine the policy, fails before any work.
664
- */
665
- function preflightReflectDispatch(runnerSpec, onNotices) {
666
- const prepared = resolveExecution({
667
- content: "Validate reflect operation transport before dispatch.",
668
- runner: runnerSpec,
669
- modelWork: true,
670
- });
671
- const lowered = buildExecution(prepared.request, prepared.runner);
672
- onNotices(lowered.notices);
673
- assertRunnerCredentials(lowered.runner);
623
+ /** Whether a harness takes the prompt as an argument, which the OS limits; one that reads it from stdin does not. */
624
+ function promptInArgv(runner) {
625
+ const harness = getHarness(runner.platform);
626
+ return harness?.build({ bin: runner.bin, args: runner.args }, { prompt: "x" }).stdin === undefined;
674
627
  }
675
628
  /**
676
- * The flat 12k content cap exists for CLI argv; the HTTP runner can spend half
677
- * its context window (after the rest of the prompt) on the asset, reserving
678
- * the other half for the reply. Never below the flat floor.
629
+ * The flat 12k content cap exists for CLI argv, so only a harness that takes the
630
+ * prompt there keeps it (`undefined`); one that reads stdin (claude, OpenCode)
631
+ * has none (`null`). The HTTP runner can spend half its context window (after
632
+ * the rest of the prompt) on the asset, reserving the other half for the reply.
633
+ * Never below the flat floor.
679
634
  */
680
635
  function computeReflectContentBudgetChars(promptInput, runnerSpec) {
681
- if (!runnerIsLlm(runnerSpec) || !promptInput.assetContent?.trim())
636
+ if (runnerSpec.kind === "harness")
637
+ return promptInArgv(runnerSpec) ? undefined : null;
638
+ if (!promptInput.assetContent?.trim())
682
639
  return undefined;
683
- const window = (runnerSpec.connection.contextLength ?? DEFAULT_CONTEXT_LENGTH_TOKENS) * CHARS_PER_TOKEN;
640
+ const window = (runnerSpec.contextLength ?? DEFAULT_CONTEXT_LENGTH_TOKENS) * CHARS_PER_TOKEN;
684
641
  const overhead = buildReflectPrompt({ ...promptInput, contentBudgetChars: 0 }).prompt.length;
685
642
  return Math.max(REFLECT_CONTENT_CAP, Math.floor((window - overhead) / 2));
686
643
  }
@@ -695,10 +652,10 @@ function gatherReflectPromptSources(options, stash, parsedRef, assetContent) {
695
652
  }
696
653
  /** The exact prompt reflect sends, shared by dispatch and `--show-prompt`. */
697
654
  function buildReflectPromptText(args) {
698
- const { options, parsedRef, assetContent, sources, runnerSpec, priorDraft } = args;
655
+ const { options, parsedRef, assetContent, sources, runnerSpec } = args;
699
656
  const { feedback, schemaHints, rejectedProposals, standardsContext } = sources;
700
- // An LLM engine that rejects JSON Schema gets the framed contract; every other engine gets the JSON object.
701
- const outputMode = runnerIsLlm(runnerSpec) && !wantsJsonSchemaOutput(runnerSpec.connection) ? "framed_markdown" : "json_schema";
657
+ // A connection that rejects JSON Schema gets the framed contract; a harness gets the JSON object.
658
+ const outputMode = runnerSpec.kind === "connection" && !wantsJsonSchemaOutput(runnerSpec) ? "framed_markdown" : "json_schema";
702
659
  const input = {
703
660
  ...(options.ref ? { ref: options.ref } : {}),
704
661
  ...(parsedRef?.type ? { type: parsedRef.type } : {}),
@@ -710,7 +667,6 @@ function buildReflectPromptText(args) {
710
667
  ...(standardsContext.trim() ? { standardsContext } : {}),
711
668
  ...(options.avoidPatterns && options.avoidPatterns.length > 0 ? { avoidPatterns: options.avoidPatterns } : {}),
712
669
  ...(rejectedProposals.length > 0 ? { rejectedProposals } : {}),
713
- ...(priorDraft !== undefined ? { priorDraft } : {}),
714
670
  outputMode,
715
671
  };
716
672
  const contentBudgetChars = computeReflectContentBudgetChars(input, runnerSpec);
@@ -721,71 +677,28 @@ function buildReflectPromptText(args) {
721
677
  return { prompt, outputMode };
722
678
  }
723
679
  /**
724
- * Dispatch with the optional self-refine loop: up to `maxRefineIters` passes,
725
- * each critiquing the prior draft, stopping early on an unchanged draft. Every
726
- * engine kind runs the same iteration, and the repair budget is shared across
727
- * passes. Under the model-work tool policy an agent can edit only its own
728
- * scratch directory, which is gone once it returns, so it returns the proposal
729
- * as its reply, as an LLM does.
680
+ * Dispatch the reflect request once. Under the model-work tool policy an agent can edit only its own scratch
681
+ * directory, which is gone once it returns, so it returns the proposal as its reply, as an LLM does.
730
682
  */
731
- async function runReflectRefineIterations(args) {
683
+ async function dispatchReflect(args) {
732
684
  const { run, parsedRef, assetContent, sources, agentEnv } = args;
733
685
  const { options, runnerSpec } = run;
734
- const maxRefineIters = Math.max(1, options.maxRefineIters ?? 1);
735
- let result = {};
736
- let priorDraft;
737
- let repairAttempts = 0;
738
- // Only an agent or SDK engine runs a child process, with an environment and spawn or SDK seams.
739
- const childProcess = runnerIsLlm(runnerSpec)
740
- ? {}
741
- : {
742
- ...(Object.keys(agentEnv).length > 0 ? { environment: agentEnv } : {}),
743
- ...(options.runSdk ? { runSdk: options.runSdk } : {}),
744
- ...(options.runAgentOptions ? { runOptions: options.runAgentOptions } : {}),
745
- };
746
- for (let iter = 0; iter < maxRefineIters; iter++) {
747
- const { prompt, outputMode } = buildReflectPromptText({
748
- options,
749
- parsedRef,
750
- assetContent,
751
- sources,
752
- runnerSpec,
753
- priorDraft,
754
- });
755
- const iterResult = await runReflectIteration({
756
- prompt,
757
- runner: runnerSpec,
758
- ...(Object.hasOwn(options, "timeoutMs") ? { timeoutMs: options.timeoutMs } : {}),
759
- ...(options.signal ? { signal: options.signal } : {}),
760
- priorDraft,
761
- iteration: iter,
762
- ...(outputMode === "json_schema"
763
- ? { responseSchema: options.ref ? REFLECT_JSON_SCHEMA : REFLECT_UNSCOPED_JSON_SCHEMA }
764
- : {}),
765
- outputMode,
766
- ...(options.ref ? { targetRef: options.ref } : {}),
767
- allowRepair: repairAttempts === 0,
768
- ...(options.chat ? { chat: options.chat } : {}),
769
- ...childProcess,
770
- onNotices: run.notices.add,
771
- });
772
- const telemetry = reflectTelemetry(iterResult);
773
- if (telemetry)
774
- repairAttempts += telemetry.repairAttempts;
775
- result = telemetry
776
- ? { ...iterResult, parsed: { ...iterResult.parsed, ...telemetry, repairAttempts } }
777
- : iterResult;
778
- if (!result.ok)
779
- break;
780
- if (iter < maxRefineIters - 1) {
781
- const priorFromReply = parsedRecord(result)?.priorDraft;
782
- const nextDraft = typeof priorFromReply === "string" ? priorFromReply : (result.stdout ?? "");
783
- if (priorDraft !== undefined && nextDraft === priorDraft)
784
- break;
785
- priorDraft = nextDraft;
786
- }
787
- }
788
- return result;
686
+ const { prompt, outputMode } = buildReflectPromptText({ options, parsedRef, assetContent, sources, runnerSpec });
687
+ return runReflectIteration({
688
+ prompt,
689
+ runner: runnerSpec,
690
+ ...(Object.hasOwn(options, "timeoutMs") ? { timeoutMs: options.timeoutMs } : {}),
691
+ ...(options.signal ? { signal: options.signal } : {}),
692
+ ...(outputMode === "json_schema"
693
+ ? { responseSchema: options.ref ? REFLECT_JSON_SCHEMA : REFLECT_UNSCOPED_JSON_SCHEMA }
694
+ : {}),
695
+ outputMode,
696
+ ...(options.ref ? { targetRef: options.ref } : {}),
697
+ ...(options.chat ? { chat: options.chat } : {}),
698
+ // Only a harness (or the internal runtime) runs a child process, which has an environment.
699
+ ...(runnerSpec.kind !== "connection" && Object.keys(agentEnv).length > 0 ? { environment: agentEnv } : {}),
700
+ onNotices: run.notices.add,
701
+ });
789
702
  }
790
703
  /**
791
704
  * The judge's review band for a reflect revision: a non-pass whose mean is at or above this goes to a
@@ -813,9 +726,9 @@ const NOISE_SUBREASONS = {
813
726
  * gate is on.
814
727
  */
815
728
  async function finalizeReflectProposal(args) {
816
- const { run, payload, assetContent, result, judge, feedback } = args;
729
+ const { run, payload, assetContent, dispatch, judge, feedback } = args;
817
730
  const { options } = run;
818
- const telemetry = reflectTelemetry(result) ?? {};
731
+ const { telemetry } = dispatch;
819
732
  const patched = applyReflectPatch(payload.patch, assetContent, payload.ref);
820
733
  // A patch that changes nothing leaves the asset as it is: an empty diff.
821
734
  const content = patched?.content ?? assetContent;
@@ -825,7 +738,7 @@ async function finalizeReflectProposal(args) {
825
738
  const what = changeKind === "noop"
826
739
  ? "identical to the current asset (empty diff)"
827
740
  : "a cosmetic-only reformat of the current asset (whitespace/fence/YAML-folding changes)";
828
- return reflectFailure(run, result, "no_change", `Reflect skipped: proposed content for ${payload.ref} is ${what}; no proposal created.`, false);
741
+ return reflectFailure(run, refusal("no_change", `Reflect skipped: proposed content for ${payload.ref} is ${what}; no proposal created.`));
829
742
  }
830
743
  /** A judge refused the revision: record it for the ledger's rejection window and stop. */
831
744
  const refuse = (detail, metadata, message) => {
@@ -843,7 +756,7 @@ async function finalizeReflectProposal(args) {
843
756
  ref: payload.ref,
844
757
  metadata: { source: "reflect", qualityRejected: true, ...metadata, ...telemetry },
845
758
  }, options.eventsCtx);
846
- return reflectFailure(run, result, "quality_rejected", message, false);
759
+ return reflectFailure(run, refusal("quality_rejected", message));
847
760
  };
848
761
  // A defect no judge needs to weigh is refused before any judge call, whether or not the gate is on.
849
762
  const defect = findReflectDefect(assetContent, content, options.defectFilter);
@@ -918,7 +831,7 @@ async function finalizeReflectProposal(args) {
918
831
  proposal,
919
832
  ref: proposal.ref,
920
833
  engine: run.engineName,
921
- durationMs: result.durationMs,
834
+ durationMs: dispatch.durationMs,
922
835
  ...run.notices.fields(),
923
836
  };
924
837
  }
@@ -945,7 +858,6 @@ export async function renderReflectPromptPreview(options) {
945
858
  assetContent: source.assetContent,
946
859
  sources,
947
860
  runnerSpec,
948
- priorDraft: undefined,
949
861
  });
950
862
  return { ref, prompt, engine: engineName, engineKind: runnerSpec.kind };
951
863
  }
@@ -963,78 +875,37 @@ export async function akmReflect(options = {}) {
963
875
  // Judge selection is frozen before dispatch so a missing judge credential fails first.
964
876
  const judgeWanted = activeStrategy?.processes?.reflect?.qualityGate?.enabled ?? true;
965
877
  let judgeRunner;
966
- if (judgeWanted) {
967
- const gateJudge = resolveQualityGateJudge(config, activeStrategy, "reflect", notices.add);
968
- if (gateJudge) {
969
- judgeRunner = gateJudge;
970
- }
971
- else if (runnerIsLlm(runnerSpec)) {
972
- judgeRunner = runnerSpec;
973
- }
974
- else {
975
- const resolved = resolveImproveExecution({ config, processName: "reflect_proposal_quality-judge" });
976
- if (resolved)
977
- notices.add(resolved.notices);
978
- judgeRunner = resolved?.runner;
979
- }
980
- }
878
+ if (judgeWanted)
879
+ judgeRunner = resolveQualityGateJudge(config, activeStrategy, "reflect", notices.add, options.run);
981
880
  const skippedNoJudge = judgeWanted && !judgeRunner;
982
881
  if (skippedNoJudge) {
983
- warnOnce("reflect-quality-gate-no-judge", "Reflect proposal quality gate has no engine configured to judge proposals (set defaults.llmEngine). Skipping the gate for this run; the proposal is queued for human review instead.");
882
+ warnOnce("reflect-quality-gate-no-judge", "Reflect proposal quality gate has no connection or harness to judge proposals (run `akm setup`). Skipping the gate for this run; the proposal is queued for human review instead.");
984
883
  }
985
- preflightReflectDispatch(runnerSpec, notices.add);
986
- if (judgeRunner && judgeRunner !== runnerSpec)
987
- preflightReflectDispatch(judgeRunner, notices.add);
988
884
  const sources = gatherReflectPromptSources(options, stash, parsedRef, assetContent);
989
885
  const agentEnv = options.eventSource === "improve" ? { AKM_EVENT_SOURCE: "improve" } : {};
990
- const sensitiveValues = collectDispatchSensitiveValues(runnerSpec, {
991
- ...(Object.keys(agentEnv).length > 0 ? { env: agentEnv } : {}),
992
- ...(options.runAgentOptions ?? {}),
993
- });
994
- let result;
995
- let payload;
886
+ let iteration;
996
887
  try {
997
- result = await runReflectRefineIterations({ run, parsedRef, assetContent, sources, agentEnv });
998
- emitInvoked();
999
- if (!result.ok) {
1000
- if (isEnoentFailure(result)) {
1001
- emitFailed("spawn_failed", "enoent", options.ref, {
1002
- ...(result.exitCode !== undefined ? { exitCode: result.exitCode } : {}),
1003
- });
1004
- return {
1005
- ...baseFailureFields(result),
1006
- schemaVersion: 2,
1007
- ...(options.ref ? { ref: options.ref } : {}),
1008
- engine: engineName,
1009
- error: enoentHintMessage(runnerIsLlm(runnerSpec) ? engineName : runnerSpec.profile.bin),
1010
- ...notices.fields(),
1011
- };
1012
- }
1013
- const envelope = {
1014
- ...baseFailureFields(result),
1015
- schemaVersion: 2,
1016
- ...(options.ref ? { ref: options.ref } : {}),
1017
- engine: engineName,
1018
- };
1019
- emitFailed(envelope.reason, envelope.reason === "parse_error" ? "parse_error" : "agent_crash", options.ref, {
1020
- ...(envelope.exitCode !== null ? { exitCode: envelope.exitCode } : {}),
1021
- ...(reflectTelemetry(result) ?? {}),
1022
- });
1023
- return { ...envelope, ...notices.fields() };
1024
- }
1025
- // The iteration parsed the reply and put its payload on stdout.
1026
- payload = JSON.parse(result.stdout);
888
+ iteration = await dispatchReflect({ run, parsedRef, assetContent, sources, agentEnv });
1027
889
  }
1028
890
  catch (error) {
1029
891
  if (!(error instanceof ConfigError))
1030
892
  emitInvoked();
1031
893
  throw error;
1032
894
  }
895
+ emitInvoked();
896
+ if (!iteration.ok) {
897
+ const enoent = isEnoentFailure(iteration);
898
+ emitFailed(enoent ? "spawn_failed" : iteration.reason, enoent ? "enoent" : iteration.reason === "parse_error" ? "parse_error" : "agent_crash", options.ref, { ...exitCodeMeta(iteration), ...iteration.telemetry });
899
+ return reflectFailure(run, enoent
900
+ ? { ...iteration, error: enoentHintMessage(runnerSpec.kind === "connection" ? engineName : runnerSpec.bin) }
901
+ : iteration);
902
+ }
903
+ const { payload } = iteration;
1033
904
  const generated = Object.values(payload.patch).join("\n");
1034
- const unsafeContent = generatedContentRejection(generated, redactSensitiveText(generated, sensitiveValues));
905
+ const unsafeContent = generatedContentRejection(generated);
1035
906
  if (unsafeContent) {
1036
- emitFailed("parse_error", "parse_error", options.ref, exitCodeMeta(result));
1037
- return reflectFailure(run, result, "parse_error", unsafeContent, false);
907
+ emitFailed("parse_error", "parse_error", options.ref, { exitCode: 0 });
908
+ return reflectFailure(run, refusal("parse_error", unsafeContent));
1038
909
  }
1039
910
  // An unscoped reply names its asset only now: read it as a targeted run read its own before dispatch.
1040
911
  const target = options.ref
@@ -1046,7 +917,7 @@ export async function akmReflect(options = {}) {
1046
917
  run,
1047
918
  payload,
1048
919
  assetContent: target.assetContent ?? "",
1049
- result,
920
+ dispatch: iteration,
1050
921
  judge: { enabled: judgeWanted && !skippedNoJudge, skippedNoJudge, runner: judgeRunner },
1051
922
  feedback: sources.feedback,
1052
923
  });