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
@@ -1,35 +1,6 @@
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
- const ENV_PASSTHROUGH_REDACTION_POLICY = {
5
- HOME: "path",
6
- PATH: "path",
7
- USER: "identifier",
8
- LANG: "identifier",
9
- LC_ALL: "identifier",
10
- TERM: "identifier",
11
- TMPDIR: "path",
12
- SYSTEMROOT: "path",
13
- COMSPEC: "path",
14
- PATHEXT: "path",
15
- WINDIR: "path",
16
- TEMP: "path",
17
- TMP: "path",
18
- AKM_EVENT_SOURCE: "identifier",
19
- OPENCODE_CONFIG: "path",
20
- CLAUDE_CONFIG: "path",
21
- CODEX_CONFIG: "path",
22
- XDG_CONFIG_HOME: "path",
23
- XDG_DATA_HOME: "path",
24
- XDG_CACHE_HOME: "path",
25
- XDG_STATE_HOME: "path",
26
- AWS_PROFILE: "identifier",
27
- AWS_REGION: "identifier",
28
- LLM_MODEL: "identifier",
29
- LLM_BASE_URL: "url",
30
- };
31
- /** Environment names whose ordinary values identify runtime configuration rather than credentials. */
32
- export const ENV_PASSTHROUGH_REDACTION_ALLOWLIST = new Set(Object.keys(ENV_PASSTHROUGH_REDACTION_POLICY));
33
4
  const SIGNED_QUERY_KEYS = new Set([
34
5
  "accesskey",
35
6
  "accesskeyid",
@@ -190,6 +161,56 @@ function inspectCredentialBearingUrl(value, values) {
190
161
  return found;
191
162
  }
192
163
  }
164
+ /**
165
+ * Shortest value an INFERRED (name-heuristic) match may contribute as a
166
+ * redaction needle. Declared secrets bypass this entirely.
167
+ *
168
+ * Redaction replaces substrings, so a short needle is not merely useless — it
169
+ * corrupts unrelated output. Below 8 the noise tier is fully intact (`1`, `0`,
170
+ * `/`, `80`, `true`, `xhigh`, `31999`); at 8 a chance collision with ordinary
171
+ * log vocabulary is negligible, and every credential format in real use is far
172
+ * longer. It also matches the conventional minimum password length, so a
173
+ * secret shorter than this is already outside normal policy.
174
+ */
175
+ export const MIN_INFERRED_SECRET_LENGTH = 8;
176
+ /**
177
+ * Environment names whose VALUE is treated as a credential on shape alone.
178
+ *
179
+ * The keyword must be a whole `_`-delimited word. Anchoring on only one side
180
+ * would drag in ordinary configuration from whichever side is left open:
181
+ * a leading anchor alone matches `KEYBOARD_LAYOUT` and `AUTHOR`, a trailing one
182
+ * matches `MONKEY` and `BYPASS`. Whole-word matching gets `GH_TOKEN`,
183
+ * `NPM_AUTH_TOKEN`, `MY_API_KEY`, `DB_PASS` and `AWS_SECRET_ACCESS_KEY` right.
184
+ */
185
+ const INFERRED_SECRET_NAME = /(?:^|_)(?:API_?KEY|KEY|TOKEN|SECRET|PASSWORD|PASSWD|PASS|CREDENTIALS?|AUTH)(?:_|$)/i;
186
+ /**
187
+ * Credential variables whose name is a single glued word, which no
188
+ * word-boundary rule can see. Enumerated rather than matched: loosening the
189
+ * pattern enough to catch `PGPASSWORD` also catches `MONKEY`.
190
+ *
191
+ * `PWD` cannot be a keyword above for the same reason it appears here as part
192
+ * of `MYSQL_PWD` — on its own it is the working directory.
193
+ */
194
+ const KNOWN_SECRET_NAMES = new Set(["PGPASSWORD", "MYSQL_PWD"]);
195
+ /** True when the NAME alone marks this variable as holding a credential. */
196
+ export function isInferredSecretName(name) {
197
+ return KNOWN_SECRET_NAMES.has(name.toUpperCase()) || INFERRED_SECRET_NAME.test(name);
198
+ }
199
+ /**
200
+ * The values in `env` whose variable NAME marks them as credentials ({@link isInferredSecretName}), at or above
201
+ * {@link MIN_INFERRED_SECRET_LENGTH}. Every process akm starts inherits akm's environment, so a reply or a log that
202
+ * echoes one of these must be scrubbed of it; this is the one place that rule lives (task logs and dispatch replies).
203
+ */
204
+ export function collectInferredSecretValues(env) {
205
+ const values = [];
206
+ for (const [name, value] of Object.entries(env)) {
207
+ if (value === undefined || value.length < MIN_INFERRED_SECRET_LENGTH)
208
+ continue;
209
+ if (isInferredSecretName(name))
210
+ values.push(value);
211
+ }
212
+ return values;
213
+ }
193
214
  /** Collect exact secrets plus decoded values embedded in credential-bearing URLs. */
194
215
  export function collectSensitiveValues(rawValues) {
195
216
  const values = new Set();
@@ -203,29 +224,6 @@ export function collectSensitiveValues(rawValues) {
203
224
  }
204
225
  return [...values];
205
226
  }
206
- /**
207
- * Decide whether an allowlisted passthrough value may cross an output boundary.
208
- * The name allowlist never overrides value inspection: URL userinfo and signed
209
- * query credentials remain secret even under ordinarily non-secret names.
210
- */
211
- export function isEnvPassthroughValueSafeToExpose(name, value) {
212
- if (value === undefined)
213
- return true;
214
- const policy = ENV_PASSTHROUGH_REDACTION_POLICY[name];
215
- if (!policy)
216
- return false;
217
- const classifiedPolicy = policy;
218
- switch (classifiedPolicy) {
219
- case "identifier":
220
- case "path":
221
- case "url":
222
- return !inspectCredentialBearingUrl(value);
223
- default: {
224
- const exhaustive = classifiedPolicy;
225
- return exhaustive;
226
- }
227
- }
228
- }
229
227
  function utf8SequenceLength(firstByte) {
230
228
  if (firstByte <= 0x7f)
231
229
  return 1;
@@ -499,10 +497,23 @@ export function redactErrorBody(input) {
499
497
  }
500
498
  return out;
501
499
  }
500
+ /**
501
+ * The spellings a JSON encoder gives a value inside a string literal: the
502
+ * `JSON.stringify` form, and the ASCII-only form with non-ASCII as `\uXXXX`
503
+ * (what Python's `json.dumps` writes). Empty for a value that needs no escaping.
504
+ */
505
+ function jsonEscapedSpellings(value) {
506
+ const json = JSON.stringify(value).slice(1, -1);
507
+ // ASCII-only encoders (Python's ensure_ascii) also escape DEL; some (Java's) write uppercase hex.
508
+ const ascii = json.replace(/[\u007f-\uffff]/g, (char) => `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`);
509
+ const upper = ascii.replace(/\\u([0-9a-f]{4})/g, (_match, hex) => `\\u${hex.toUpperCase()}`);
510
+ return [...new Set([json, ascii, upper])].filter((spelling) => spelling !== value);
511
+ }
502
512
  export function redactSensitiveText(text, sensitiveValues) {
503
- const values = [...new Set(sensitiveValues)]
504
- .filter((value) => value.length > 0)
505
- .sort((a, b) => b.length - a.length || a.localeCompare(b));
513
+ const exact = [...sensitiveValues].filter((value) => value.length > 0);
514
+ // A child that prints JSON writes a secret's escaped spelling (`\"`, `\\`, `\n`, `\uXXXX`),
515
+ // which the exact value never matches. Each escaped spelling is just another needle.
516
+ const values = [...new Set([...exact, ...exact.flatMap(jsonEscapedSpellings)])].sort((a, b) => b.length - a.length || a.localeCompare(b));
506
517
  if (values.length === 0)
507
518
  return text;
508
519
  const coverageDelta = new Int32Array(text.length + 1);
@@ -569,3 +580,31 @@ export function redactSensitiveValue(value, sensitiveValues) {
569
580
  };
570
581
  return redact(value);
571
582
  }
583
+ /** What stands in for a masked value where configuration is shown. */
584
+ export const REDACTED = "[redacted]";
585
+ /** Query parameters that carry a credential in a URL. */
586
+ const SECRET_QUERY_PARAM = /^(api[-_]?key|key|token|access[-_]?token|auth|password|secret|sig|signature)$/i;
587
+ /** `scheme://user:pass@host/?token=x` with the credentials masked. Anything that is not a URL is returned as is. */
588
+ export function redactUrlCredentials(value) {
589
+ if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(value))
590
+ return value;
591
+ try {
592
+ const url = new URL(value);
593
+ let changed = false;
594
+ if (url.username || url.password) {
595
+ url.username = "";
596
+ url.password = "";
597
+ changed = true;
598
+ }
599
+ for (const key of [...url.searchParams.keys()]) {
600
+ if (SECRET_QUERY_PARAM.test(key)) {
601
+ url.searchParams.set(key, REDACTED);
602
+ changed = true;
603
+ }
604
+ }
605
+ return changed ? url.toString() : value;
606
+ }
607
+ catch {
608
+ return value;
609
+ }
610
+ }
@@ -0,0 +1,82 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * The one substitution token akm hands to a process or a provider: `${ref}`,
6
+ * where `ref` is an akm ref (`[bundle//]conceptId`). A `secrets/…` ref stands
7
+ * for the secret's value; any other asset ref stands for the asset's absolute
8
+ * path. A `${…}` body that is not an akm ref (`${HOME}`, `${PATH//:/ }`,
9
+ * `${v//-/_}`, `${x/a/b}`: not led by a native type and not qualified by an
10
+ * installed bundle) is plain text and is left alone.
11
+ *
12
+ * Kept free of the commands layer so config credentials and env values share
13
+ * this one function.
14
+ */
15
+ import { parseBundleRef } from "./asset/asset-ref.js";
16
+ import { typeNameFromConceptId } from "./asset/resolve-ref.js";
17
+ export const REF_TOKEN_RE = /\$\{([^}\s]+)\}/g;
18
+ /**
19
+ * Does a `${…}` body parse as an akm ref (no export fragment) that either
20
+ * leads with a native asset type (bundle-qualified or not) or is bundle-qualified
21
+ * with a bundle `isBundleInstalled` accepts? Anything else stays text, so shell
22
+ * syntax (`${v//-/_}`, `${x/a/b}`) is never read as a ref. A qualified opaque body
23
+ * follows the core ref grammar and the owner walk, whatever adapter owns it, but
24
+ * only for an installed bundle; with no predicate no bundle is installed.
25
+ */
26
+ function isRefBody(body, isBundleInstalled) {
27
+ try {
28
+ const ref = parseBundleRef(body);
29
+ if (ref.fragment !== undefined)
30
+ return false;
31
+ if (typeNameFromConceptId(ref.conceptId) !== undefined)
32
+ return true;
33
+ return ref.bundle !== undefined && isBundleInstalled?.(ref.bundle) === true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
39
+ /** Is the whole string exactly one `${ref}` token? */
40
+ export function isRefToken(value) {
41
+ const body = /^\$\{([^}\s]+)\}$/.exec(value)?.[1];
42
+ return body !== undefined && isRefBody(body);
43
+ }
44
+ /** Is the whole string exactly one `${ref}` token whose ref names a `secrets/` asset? */
45
+ export function isSecretRefToken(value) {
46
+ const body = /^\$\{([^}\s]+)\}$/.exec(value)?.[1];
47
+ return (body !== undefined && isRefBody(body) && typeNameFromConceptId(parseBundleRef(body).conceptId)?.type === "secret");
48
+ }
49
+ /**
50
+ * Replace every `${ref}` token in each value. Keys are never touched, and
51
+ * tokens embedded in larger strings are all substituted. `isBundleInstalled`
52
+ * lets a bundle-qualified body that is not led by a native type be a ref when
53
+ * its bundle is installed. An unresolved ref is
54
+ * collected in `missing` and its token left in place. Resolved secret values
55
+ * must never be logged or printed by callers.
56
+ */
57
+ export function substituteRefTokens(values, resolve, isBundleInstalled) {
58
+ const missing = [];
59
+ const secretValues = new Set();
60
+ const cache = new Map();
61
+ const out = {};
62
+ for (const [key, value] of Object.entries(values)) {
63
+ out[key] = value.replace(REF_TOKEN_RE, (token, body) => {
64
+ if (!isRefBody(body, isBundleInstalled))
65
+ return token;
66
+ if (!cache.has(body))
67
+ cache.set(body, resolve(body));
68
+ const resolved = cache.get(body);
69
+ if (resolved === undefined) {
70
+ if (!missing.includes(body))
71
+ missing.push(body);
72
+ return token;
73
+ }
74
+ if (resolved.kind === "path")
75
+ return resolved.path;
76
+ if (resolved.value)
77
+ secretValues.add(resolved.value);
78
+ return resolved.value;
79
+ });
80
+ }
81
+ return { values: out, missing, secretValues: [...secretValues] };
82
+ }
@@ -0,0 +1,14 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ import fs from "node:fs";
5
+ /**
6
+ * Read a secret's value: the file content as UTF-8 with surrounding whitespace
7
+ * trimmed. The one read every consumer uses (`secret run`, env `${ref}`
8
+ * tokens, config credentials, website fetchers), so a hand-written file's
9
+ * trailing newline never lands in an HTTP header. Callers MUST NOT write the
10
+ * returned value to stdout or any log.
11
+ */
12
+ export function readValue(secretPath) {
13
+ return fs.readFileSync(secretPath, "utf8").trim();
14
+ }
@@ -1037,17 +1037,16 @@ export const STATE_MIGRATIONS = [
1037
1037
  ON workflow_run_unit_attempts(run_id, status, claim_expires_at);
1038
1038
  `,
1039
1039
  },
1040
- // ── Migration 023 — child workflow run parentage (P3a) ────────────────────
1040
+ // ── Migration 023 — child workflow run parentage ──────────────────────────
1041
1041
  //
1042
1042
  // Adds the columns and partial unique index `publishChildWorkflowRun`
1043
1043
  // (src/storage/repositories/workflow-runs-repository.ts) needs to record a
1044
1044
  // durable child workflow run under the parent unit that spawned it, and to
1045
- // make that publication idempotent per invocation
1046
- // (docs/plans/specs/p3a-plan-v5-child-freeze.md §5.1).
1045
+ // make that publication idempotent per invocation.
1047
1046
  //
1048
1047
  // Disambiguation: this migration's `workflow_runs.parent_unit_id` is the
1049
1048
  // PARENT RUN's unit that spawned this CHILD RUN — a cross-run composition
1050
- // edge, new in P3a. It is NOT the same concept as the pre-existing
1049
+ // edge. It is NOT the same concept as the pre-existing
1051
1050
  // `workflow_run_units.parent_unit_id` (migration 004, consolidated above
1052
1051
  // into migration 020's `workflow_run_units` table, migrations.ts:934),
1053
1052
  // which records MAP FAN-OUT TEMPLATE PARENTAGE — one expanded unit's row
@@ -1076,12 +1075,11 @@ export const STATE_MIGRATIONS = [
1076
1075
  WHERE parent_run_id IS NOT NULL;
1077
1076
  `,
1078
1077
  },
1079
- // ── Migration 024 — workflow run outputs (P3b) ─────────────────────────────
1078
+ // ── Migration 024 — workflow run outputs ───────────────────────────────────
1080
1079
  //
1081
1080
  // Adds workflow_runs.outputs_json — the resolved map of a plan's declared
1082
1081
  // outputs:, persisted once at run completion in the SAME transaction as the
1083
- // final step's completion (docs/plans/specs/p3b-child-executor.md §4.3,
1084
- // B-N13). NULL for every run whose plan declares no outputs: (the
1082
+ // final step's completion. NULL for every run whose plan declares no outputs: (the
1085
1083
  // overwhelming majority, including every run before this migration) and for
1086
1084
  // every run that fails or blocks before completing — never `{}`.
1087
1085
  // `WorkflowRunsRepository.setRunOutputs` is the only writer;
@@ -1092,28 +1090,25 @@ export const STATE_MIGRATIONS = [
1092
1090
  ALTER TABLE workflow_runs ADD COLUMN outputs_json TEXT;
1093
1091
  `,
1094
1092
  },
1095
- // ── Migration 025 — task_history D8 result-vocabulary backfill ─────────────
1096
- //
1097
- // The D8 re-code (docs/architecture/decisions/0005-task-result-vocabulary-
1098
- // and-legacy-read-mapping.md) renamed the written `target_kind` vocabulary
1099
- // and marked every new row with `targetVocab: 2` in `metadata_json`, but
1100
- // left every row written before it in the OLD vocabulary forever, pushing
1101
- // the "which generation is this row" decision onto three separate read
1102
- // sites (src/tasks/run/task-history.ts, src/commands/health/
1103
- // improve-metrics.ts, src/commands/health/windows.ts). That is exactly the
1104
- // shape `docs/plans/specs/p4-deletions-closeout.md` row B-51 ratified
1105
- // keeping "forever" — SUPERSEDED here: `task_history` is DB-owned data, the
1106
- // remap is deterministic and total, so it belongs in a one-time migration,
1107
- // not three permanently-recurring read-side shims.
1093
+ // ── Migration 025 — task_history result-vocabulary backfill ────────────────
1094
+ //
1095
+ // The written `target_kind` vocabulary was renamed and every new row is
1096
+ // marked `targetVocab: 2` in `metadata_json`, but every row written before
1097
+ // that stayed in the OLD vocabulary, which would push the "which generation
1098
+ // is this row" decision onto three separate read sites
1099
+ // (src/tasks/run/task-history.ts, src/commands/health/
1100
+ // improve-metrics.ts, src/commands/health/windows.ts). `task_history` is
1101
+ // DB-owned data and the remap is deterministic and total, so it is a
1102
+ // one-time migration, not three permanently-recurring read-side shims.
1108
1103
  //
1109
1104
  // The remap, applied only to rows with no `targetVocab` marker yet (a
1110
1105
  // NULL/absent `$.targetVocab` in the JSON column — already-marked or
1111
1106
  // malformed metadata_json is left untouched; malformed rows are a
1112
1107
  // pre-existing, unrelated skip-and-warn concern at read time):
1113
1108
  // - target_kind 'prompt' -> 'command' (the prepared command/agent-LLM
1114
- // arm; D8 renamed its written label, this backfills the old one)
1109
+ // arm; its written label was renamed, this backfills the old one)
1115
1110
  // - target_kind 'command' -> 'shell' (the legacy native shell/script
1116
- // arm's shared old label; D8 split it into 'shell'/'script', and only
1111
+ // arm's shared old label; it was split into 'shell'/'script', and only
1117
1112
  // 'shell' is reconstructable — the old vocabulary never distinguished
1118
1113
  // script from shell, matching the read mapping this migration retires)
1119
1114
  // Only 'prompt' and legacy 'command' rows actually change meaning between
@@ -1,79 +1,13 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * `runStructured<T>()` — transport-free structured-output core (P0.5 seam).
6
- *
7
- * akm has two structured-output paths that share no code: the LLM HTTP path
8
- * (`llm/structured-call.ts` + `responseSchema`) and the agent JSON path
9
- * (`agent/spawn.ts` `parseOutput: "json"` — embedded-JSON scan, no schema,
10
- * no retry). This module is the ONE validation-driven retry loop both are
11
- * meant to converge on: the workflow engine's schema units compose it with a
12
- * dispatch adapter per runner (llm = `chatCompletion` + `responseSchema`;
13
- * agent/sdk = `runAgent`/`runOpencodeSdk` + prompt-injected schema;
14
- * native-schema CLIs pass the schema through and still validate).
15
- *
16
- * Layering: this file lives in `core/` — NOT `llm/` — because the agent path
17
- * must be able to reach it and `agent/ ⇏ llm/` is an enforced invariant
18
- * (`tests/integration/architecture/agent-no-llm-sdk-guard.test.ts`). The transport is
19
- * always injected; this module never performs IO of its own.
20
- *
21
- * Retry semantics: only parse/validation misses are retried (with corrective
22
- * feedback appended to the re-dispatch). Transport errors PROPAGATE — the
23
- * transports own their own retry discipline (`chatCompletion` has a bounded
24
- * jittered retry; `runAgent` has timeout/abort semantics).
25
- */
26
- import { parseEmbeddedJsonResponse } from "./parse.js";
27
4
  /**
28
5
  * Append the one structured-output instruction to a prompt. Agent lowering
29
- * appends it to every schema-bearing request, alongside a harness's native
30
- * channel where one exists (codex `--output-schema`); the workflow engine
6
+ * appends it to every schema-bearing request, alongside a transport's native
7
+ * channel where one exists (a chat's `response_format`); the workflow engine
31
8
  * appends it for a direct-LLM unit. Resumed workflow runs depend on these
32
9
  * exact bytes, so do not reword it.
33
10
  */
34
11
  export function withSchemaInstruction(prompt, schema) {
35
12
  return `${prompt}\n\nRespond with ONLY a JSON value matching this JSON Schema (no prose, no code fences):\n${JSON.stringify(schema)}`;
36
13
  }
37
- export function defaultFeedback(failure) {
38
- if (failure.reason === "parse_error") {
39
- return "Your previous response contained no parseable JSON. Respond with ONLY a JSON value that matches the requested schema — no prose, no code fences.";
40
- }
41
- return `Your previous JSON response failed validation:\n- ${failure.errors.join("\n- ")}\nRespond again with ONLY a corrected JSON value.`;
42
- }
43
- /**
44
- * Run the dispatch→parse→validate loop, re-dispatching with corrective
45
- * feedback on parse/validation misses, up to `maxAttempts` total attempts.
46
- * Never throws for structure problems (returns a typed failure); transport
47
- * throws propagate untouched.
48
- */
49
- export async function runStructured(options) {
50
- const parse = options.parse ?? ((raw) => parseEmbeddedJsonResponse(raw));
51
- const buildFeedback = options.buildFeedback ?? defaultFeedback;
52
- const maxAttempts = Math.max(1, options.maxAttempts ?? 2);
53
- let feedback;
54
- let lastFailure;
55
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
56
- const raw = await options.dispatch(feedback);
57
- const candidate = parse(raw);
58
- if (candidate === undefined) {
59
- lastFailure = {
60
- ok: false,
61
- reason: "parse_error",
62
- errors: ["no JSON structure found in response"],
63
- attempts: attempt,
64
- raw,
65
- };
66
- feedback = buildFeedback({ reason: "parse_error", errors: lastFailure.errors, raw });
67
- continue;
68
- }
69
- const verdict = options.validate(candidate);
70
- if (verdict.ok) {
71
- return { ok: true, value: verdict.value, attempts: attempt };
72
- }
73
- lastFailure = { ok: false, reason: "validation_error", errors: verdict.errors, attempts: attempt, raw };
74
- feedback = buildFeedback({ reason: "validation_error", errors: verdict.errors, raw });
75
- }
76
- // maxAttempts >= 1 guarantees at least one loop iteration set lastFailure
77
- // (a success would have returned), so the non-null assertion is safe.
78
- return lastFailure;
79
- }
@@ -11,8 +11,10 @@
11
11
  * • Process-GROUP spawn (`detached: true` when capturing ON POSIX) so a
12
12
  * negative-pid kill reaps the whole descendant tree — no orphaned children.
13
13
  * See {@link spawnsOwnProcessGroup} for why Windows is excluded.
14
- * • A SIGTERM→SIGKILL kill ladder on timeout/abort — a child that ignores
15
- * SIGTERM is force-killed after a grace period instead of wedging forever.
14
+ * • A SIGINT→SIGTERM→SIGKILL kill ladder on timeout/abort — SIGINT first, as
15
+ * a Ctrl-C would, so a program that treats an interrupt as a stop can wind
16
+ * the run down; a child that ignores it is terminated, and one that ignores
17
+ * that is force-killed, each after a grace period, instead of wedging forever.
16
18
  * • Time-bounded output capture ({@link readStream}) that cannot block past
17
19
  * the wall budget even when the child leaves a pipe endpoint open, plus an
18
20
  * OPT-IN RETENTION cap (`maxOutputBytes`); see {@link readStream} for what
@@ -94,27 +96,58 @@ export function killGroup(proc, signal) {
94
96
  /* ignore */
95
97
  }
96
98
  }
99
+ /** Whether anything still runs in `proc`'s process group (the leader included), or the leader has not exited. */
100
+ function groupRunning(proc) {
101
+ if (typeof proc.pid === "number") {
102
+ try {
103
+ process.kill(-proc.pid, 0);
104
+ return true;
105
+ }
106
+ catch {
107
+ // No member is left, or the child leads no group of its own: only the leader's own exit tells.
108
+ }
109
+ }
110
+ return proc.exitCode === null;
111
+ }
97
112
  /**
98
- * SIGTERM→SIGKILL kill ladder shared by the timeout and abort paths (§4.6
99
- * dedup, H3). No-op when the child has already exited; otherwise runs
100
- * `onKill` (the caller's reason flag — `timedOut` / `aborted` — set BEFORE
101
- * the first signal, exactly as the inlined copies did), SIGTERMs the
102
- * process group, and schedules a follow-up SIGKILL after `graceMs` in case
103
- * the process ignores SIGTERM. The SIGKILL timer is unref'ed so it never
104
- * pins the event loop.
113
+ * SIGINT→SIGTERM→SIGKILL kill ladder shared by the timeout and abort paths.
114
+ * No-op when the child has already exited; otherwise runs `onKill`
115
+ * (the caller's reason flag — `timedOut` / `aborted` — set BEFORE the first
116
+ * signal, exactly as the inlined copies did) and interrupts the process group.
117
+ * SIGTERM follows when `graceMs` runs out or as soon as the leader exits,
118
+ * whichever is first, because members of the group can outlive it: a job a
119
+ * shell started in the background ignores SIGINT. SIGKILL follows another
120
+ * `graceMs` later if anything in the group still runs. The timers are unref'ed
121
+ * so they never pin the event loop.
122
+ *
123
+ * SIGINT goes first because it is what a person's Ctrl-C sends, and a program
124
+ * that records how a run ended acts on it: the OpenCode 2 CLI marks its session
125
+ * interrupted and releases its claim, where on SIGTERM or SIGKILL the session
126
+ * stays suspended and OpenCode's own service may resume it later.
105
127
  */
106
128
  export function scheduleKillLadder(proc, opts) {
107
129
  if (!proc || proc.exitCode !== null)
108
130
  return;
109
131
  opts.onKill();
110
- killGroup(proc, "SIGTERM");
111
- const sigkillTimer = opts.setTimeoutFn(() => {
112
- if (!proc || proc.exitCode !== null)
132
+ const afterGrace = (run) => {
133
+ const timer = opts.setTimeoutFn(run, opts.graceMs ?? 5000);
134
+ if (typeof timer !== "number")
135
+ timer.unref?.();
136
+ };
137
+ killGroup(proc, "SIGINT");
138
+ let terminated = false;
139
+ const terminate = () => {
140
+ if (terminated || !groupRunning(proc))
113
141
  return;
114
- killGroup(proc, "SIGKILL");
115
- }, opts.graceMs ?? 5000);
116
- if (typeof sigkillTimer !== "number")
117
- sigkillTimer.unref?.();
142
+ terminated = true;
143
+ killGroup(proc, "SIGTERM");
144
+ afterGrace(() => {
145
+ if (groupRunning(proc))
146
+ killGroup(proc, "SIGKILL");
147
+ });
148
+ };
149
+ afterGrace(terminate);
150
+ proc.exited.then(terminate, terminate);
118
151
  }
119
152
  const liveGroupChildren = new Set();
120
153
  let signalGuardHandlers;
@@ -211,7 +244,7 @@ function utf8BoundaryAtOrBefore(value, limit) {
211
244
  }
212
245
  /**
213
246
  * Drain a readable stream to text, optionally racing each read against a
214
- * timeout so a process that is killed via SIGTERM/SIGKILL but whose pipe
247
+ * timeout so a process that is killed via SIGINT/SIGTERM/SIGKILL but whose pipe
215
248
  * endpoints stay open (e.g. background threads still holding the fd) cannot
216
249
  * block the caller indefinitely. On timeout we return whatever was decoded
217
250
  * before the pipe stopped draining.
@@ -368,7 +401,7 @@ function toError(err) {
368
401
  }
369
402
  /**
370
403
  * Spawn `cmd` and manage its lifecycle: process-group spawn, hard timeout and
371
- * cooperative abort (both via the SIGTERM→SIGKILL {@link scheduleKillLadder}),
404
+ * cooperative abort (both via the SIGINT→SIGTERM→SIGKILL {@link scheduleKillLadder}),
372
405
  * bounded output capture, and an optional stdin payload. Never throws for a
373
406
  * spawn/exit failure — those surface as {@link ManagedSubprocessResult.spawnError}.
374
407
  */
@@ -413,7 +446,7 @@ export async function runManagedSubprocess(cmd, opts) {
413
446
  };
414
447
  }
415
448
  opts.onSpawn?.(proc);
416
- // Hard timeout: SIGTERM now, SIGKILL after the grace period if ignored.
449
+ // Hard timeout: SIGINT now, SIGTERM and SIGKILL after each grace period if ignored.
417
450
  // Skipped entirely when timeoutMs is null.
418
451
  let timedOut = false;
419
452
  let timer;
@@ -495,9 +528,17 @@ export async function runManagedSubprocess(cmd, opts) {
495
528
  const stdinStream = proc.stdin;
496
529
  const stdinDone = (async () => {
497
530
  try {
498
- const writer = stdinStream.getWriter();
499
- await writer.write(new TextEncoder().encode(stdinPayload));
500
- await writer.close();
531
+ // Bun.spawn's pipe is a FileSink (write/end), not a WritableStream.
532
+ const sink = stdinStream;
533
+ if (typeof sink.write === "function" && typeof sink.end === "function" && !("getWriter" in stdinStream)) {
534
+ sink.write(stdinPayload);
535
+ await sink.end();
536
+ }
537
+ else {
538
+ const writer = stdinStream.getWriter();
539
+ await writer.write(new TextEncoder().encode(stdinPayload));
540
+ await writer.close();
541
+ }
501
542
  }
502
543
  catch {
503
544
  // Best-effort: ignore stdin write failures, the child will get EOF.
@@ -2,33 +2,29 @@
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
- * Chunk 1.5 (WI-1.5.1, D1.5-4) — the §2.3 "compile-time safety mitigation"
6
- * table for AKM's own presentation metadata. EXTENDED by chunk-2 WI-C
7
- * (`docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md` §2) to carry the per-`type`
8
- * renderer NAME + action builder, so this table becomes the `TYPE_PRESENTATION`
9
- * data table §2 mandates ("Renderer/action = data table keyed on the open
10
- * `type`, pointing at a named-function core module").
5
+ * The `TYPE_PRESENTATION` table of AKM's own presentation metadata: the per-`type`
6
+ * renderer NAME + action builder, a data table keyed on the open
7
+ * `type`, pointing at a named-function core module.
11
8
  *
12
- * The open type token (chunk 1.5) trades the deleted closed asset-type
9
+ * The open type token trades the deleted closed asset-type
13
10
  * union's exhaustiveness checking for a runtime lookup. `TYPE_PRESENTATION`
14
11
  * restores that exhaustiveness for AKM's OWN known types (the compiler
15
12
  * demands an entry whenever {@link KnownType} gains a member), while
16
13
  * {@link presentationFor} stays open over `string` so foreign/adapter types
17
14
  * still resolve to a sane generic fallback instead of `undefined`/a throw.
18
15
  *
19
- * ── renderer/action provenance (WI-C, §2) ──
16
+ * ── renderer/action provenance ──
20
17
  *
21
18
  * The `renderer` NAMES and `action` builders below are the SINGLE SOURCE OF
22
- * TRUTH for search-hit rendering — chunk-3 folded the old mutable renderer/
23
- * action registry singleton into this static table (reached via
24
- * {@link presentationFor}). They cover all built-in types — INCLUDING
19
+ * TRUTH for search-hit rendering (reached via {@link presentationFor}).
20
+ * They cover all built-in types — INCLUDING
25
21
  * the 15th type `instruction` (a read-like-knowledge markdown doc added for the
26
22
  * format-family adapters) and the 6 "static-only" mappings
27
- * (script/skill/command/agent/knowledge/memory) — §6 "6 renderer mappings".
23
+ * (script/skill/command/agent/knowledge/memory).
28
24
  * The workflow action is the one function-valued builder; its
29
25
  * `buildWorkflowAction` body (`output/renderers.ts` — a cycle-sensitive module)
30
26
  * is reproduced inline here rather than imported, to keep this leaf import-free
31
- * (only `recognition-util`, D1-5's pure sink); `tests/core/adapter/
27
+ * (only `recognition-util`, a pure sink); `tests/core/adapter/
32
28
  * akm-presentation.test.ts` pins the renderer/action values against drift.
33
29
  */
34
30
  import { isKnownType } from "./recognition-util.js";
@@ -119,7 +115,7 @@ export const TYPE_PRESENTATION = {
119
115
  action: (ref) => `akm show ${ref} -> read the stash fact and apply it as durable context`,
120
116
  },
121
117
  // `instruction` (CLAUDE.md / AGENTS.md) is a read-like-knowledge markdown
122
- // doc (spec §6/§7 instruction row, maintainer resolution 2026-07): it REUSES
118
+ // doc: it REUSES
123
119
  // the `knowledge-md` renderer and mirrors knowledge's read action, so an
124
120
  // instruction hit renders exactly like knowledge instead of the generic
125
121
  // fallback (the parity guard in akm-presentation.test.ts pins this).