akm-cli 0.9.17-alpha.2 → 0.9.17-alpha.4

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 (343) hide show
  1. package/CHANGELOG.md +756 -0
  2. package/dist/akm +94 -196
  3. package/dist/cli/shared.js +6 -2
  4. package/dist/cli.js +22 -9
  5. package/dist/commands/agent/agent-dispatch.js +1 -1
  6. package/dist/commands/command/command-execution.js +24 -62
  7. package/dist/commands/feedback-cli.js +0 -1
  8. package/dist/commands/health/accept-rate.js +2 -2
  9. package/dist/commands/health/checks.js +30 -75
  10. package/dist/commands/health/config-skew.js +38 -0
  11. package/dist/commands/health/egress.js +54 -0
  12. package/dist/commands/health/html-report.js +0 -38
  13. package/dist/commands/health/improve-metrics.js +123 -562
  14. package/dist/commands/health/plugin-staleness.js +53 -3
  15. package/dist/commands/health/renderers.js +12 -4
  16. package/dist/commands/health/report-view-model.js +11 -106
  17. package/dist/commands/health/types-improve.js +4 -19
  18. package/dist/commands/health/windows.js +64 -73
  19. package/dist/commands/health.js +122 -143
  20. package/dist/commands/improve/consolidate/chunking.js +25 -100
  21. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  22. package/dist/commands/improve/consolidate.js +538 -1075
  23. package/dist/commands/improve/content-hash.js +16 -24
  24. package/dist/commands/improve/distill/content-repair.js +18 -100
  25. package/dist/commands/improve/distill-guards.js +20 -81
  26. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  27. package/dist/commands/improve/distill.js +608 -1075
  28. package/dist/commands/improve/eligibility.js +126 -400
  29. package/dist/commands/improve/execution.js +3 -5
  30. package/dist/commands/improve/extract.js +487 -1046
  31. package/dist/commands/improve/feedback-valence.js +0 -25
  32. package/dist/commands/improve/improve-cli.js +29 -166
  33. package/dist/commands/improve/improve-result-file.js +10 -66
  34. package/dist/commands/improve/improve-strategies.js +12 -7
  35. package/dist/commands/improve/improve-usage-report.js +18 -64
  36. package/dist/commands/improve/improve.js +443 -1063
  37. package/dist/commands/improve/ledger.js +114 -0
  38. package/dist/commands/improve/locks.js +2 -8
  39. package/dist/commands/improve/loop-stages.js +459 -1172
  40. package/dist/commands/improve/memory/derived-ref.js +12 -77
  41. package/dist/commands/improve/memory/memory-belief.js +14 -118
  42. package/dist/commands/improve/memory/memory-improve.js +4 -3
  43. package/dist/commands/improve/outcome-loop.js +28 -156
  44. package/dist/commands/improve/planner.js +5 -10
  45. package/dist/commands/improve/preparation.js +851 -2339
  46. package/dist/commands/improve/proactive-maintenance.js +34 -101
  47. package/dist/commands/improve/reflect-noise.js +104 -280
  48. package/dist/commands/improve/reflect.js +621 -1367
  49. package/dist/commands/improve/salience.js +46 -232
  50. package/dist/commands/improve/session-asset.js +19 -100
  51. package/dist/commands/improve/stage.js +323 -0
  52. package/dist/commands/proposal/drain.js +251 -644
  53. package/dist/commands/proposal/proposal-cli.js +3 -18
  54. package/dist/commands/proposal/proposal-types.js +20 -41
  55. package/dist/commands/proposal/proposal.js +1 -2
  56. package/dist/commands/proposal/propose.js +134 -160
  57. package/dist/commands/proposal/repository.js +502 -1487
  58. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  59. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  60. package/dist/commands/proposal/validators/proposals.js +13 -89
  61. package/dist/commands/read/curate.js +63 -413
  62. package/dist/commands/read/search-cli.js +16 -33
  63. package/dist/commands/read/search.js +17 -23
  64. package/dist/commands/read/show.js +2 -13
  65. package/dist/commands/sources/bundle-cli.js +25 -2
  66. package/dist/commands/sources/bundle-config-ops.js +7 -0
  67. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  68. package/dist/commands/sources/info.js +2 -11
  69. package/dist/commands/sources/installed-stashes.js +197 -746
  70. package/dist/commands/sources/schema-repair.js +98 -129
  71. package/dist/commands/sources/source-add.js +62 -12
  72. package/dist/commands/sources/stash-cli.js +1 -1
  73. package/dist/commands/tasks/explain.js +10 -13
  74. package/dist/commands/tasks/tasks-cli.js +9 -8
  75. package/dist/commands/tasks/tasks.js +326 -930
  76. package/dist/commands/tasks/validate.js +42 -21
  77. package/dist/commands/workflow/plan.js +22 -29
  78. package/dist/commands/workflow-cli.js +4 -4
  79. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  80. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  81. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  82. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  83. package/dist/core/adapter/execution-source.js +17 -29
  84. package/dist/core/asset/resolve-ref.js +1 -1
  85. package/dist/core/bundle-id.js +42 -5
  86. package/dist/core/bundle-rename.js +291 -0
  87. package/dist/core/config/config-io.js +1 -2
  88. package/dist/core/config/config-schema.js +1 -33
  89. package/dist/core/config/config-walker.js +1 -1
  90. package/dist/core/config/config.js +163 -68
  91. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  92. package/dist/core/config/schema/embedding.js +20 -5
  93. package/dist/core/config/schema/engines.js +5 -0
  94. package/dist/core/config/schema/execution.js +1 -1
  95. package/dist/core/config/schema/experimental.js +1 -1
  96. package/dist/core/config/schema/improve-processes.js +21 -95
  97. package/dist/core/config/schema/improve.js +4 -42
  98. package/dist/core/config/schema/scheduler.js +12 -12
  99. package/dist/core/config/schema/search.js +6 -22
  100. package/dist/core/env-secret-ref.js +0 -1
  101. package/dist/core/errors.js +8 -9
  102. package/dist/core/file-lock.js +76 -173
  103. package/dist/core/logs-db.js +2 -2
  104. package/dist/core/paths.js +0 -27
  105. package/dist/core/redaction.js +109 -2
  106. package/dist/core/run-lock.js +2 -5
  107. package/dist/core/spawn-env.js +1 -1
  108. package/dist/core/state/migrations.js +108 -61
  109. package/dist/core/state-db-scope.js +2 -4
  110. package/dist/core/state-db.js +126 -692
  111. package/dist/core/type-presentation.js +1 -9
  112. package/dist/core/write-source.js +293 -1012
  113. package/dist/execution/input-contract.js +1 -1
  114. package/dist/execution/resolved-request.js +135 -689
  115. package/dist/execution/source.js +63 -257
  116. package/dist/execution/target-ref.js +1 -1
  117. package/dist/indexer/bundle-identity-guard.js +2 -2
  118. package/dist/indexer/db/graph-db.js +106 -46
  119. package/dist/indexer/ensure-index.js +44 -85
  120. package/dist/indexer/graph/graph-extraction.js +340 -562
  121. package/dist/indexer/graph/graph-related.js +130 -0
  122. package/dist/indexer/index-rebuild-lock.js +3 -11
  123. package/dist/indexer/index-writer-lock.js +8 -17
  124. package/dist/indexer/index-written-assets.js +139 -151
  125. package/dist/indexer/indexer.js +524 -846
  126. package/dist/indexer/materialize-embeddings.js +60 -397
  127. package/dist/indexer/passes/memory-inference.js +81 -90
  128. package/dist/indexer/passes/metadata.js +132 -200
  129. package/dist/indexer/read-preflight.js +0 -7
  130. package/dist/indexer/scan/doc-to-entry.js +1 -3
  131. package/dist/indexer/scan/drain-dir.js +1 -1
  132. package/dist/indexer/search/db-search.js +181 -590
  133. package/dist/indexer/search/fts-query.js +30 -41
  134. package/dist/indexer/search/ranking.js +28 -154
  135. package/dist/indexer/search/search-attribution.js +12 -32
  136. package/dist/indexer/search/search-fields.js +11 -15
  137. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  138. package/dist/indexer/search/search-source.js +1 -4
  139. package/dist/indexer/usage/usage-events.js +2 -7
  140. package/dist/integrations/agent/engine-fallback.js +23 -40
  141. package/dist/integrations/agent/engine-resolution.js +93 -183
  142. package/dist/integrations/agent/execution.js +507 -0
  143. package/dist/integrations/agent/model-map.js +28 -156
  144. package/dist/integrations/agent/request-lowering.js +66 -141
  145. package/dist/integrations/agent/runner-dispatch.js +143 -321
  146. package/dist/integrations/agent/runner.js +54 -14
  147. package/dist/integrations/lockfile.js +53 -101
  148. package/dist/llm/embedders/deterministic.js +2 -3
  149. package/dist/llm/embedders/profile.js +71 -0
  150. package/dist/llm/embedders/remote.js +10 -15
  151. package/dist/llm/graph-extract.js +3 -12
  152. package/dist/llm/index-passes.js +3 -5
  153. package/dist/llm/memory-infer.js +1 -2
  154. package/dist/llm/metadata-enhance.js +1 -2
  155. package/dist/llm/structured-call.js +5 -24
  156. package/dist/output/generic-render.js +23 -11
  157. package/dist/output/html-render.js +13 -10
  158. package/dist/output/render-registry.js +3 -32
  159. package/dist/output/shapes/helpers.js +2 -34
  160. package/dist/output/shapes/passthrough.js +1 -9
  161. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  162. package/dist/output/text/command-format.js +60 -23
  163. package/dist/output/text/helpers.js +1 -1
  164. package/dist/output/text/migrate.js +5 -14
  165. package/dist/output/text/proposal-format.js +1 -2
  166. package/dist/output/text/workflow-format.js +0 -32
  167. package/dist/output/text.js +2 -0
  168. package/dist/registry/factory.js +4 -19
  169. package/dist/registry/network.js +66 -220
  170. package/dist/registry/providers/index.js +0 -2
  171. package/dist/registry/providers/skills-sh.js +3 -14
  172. package/dist/registry/providers/static-index.js +24 -26
  173. package/dist/registry/resolve.js +55 -131
  174. package/dist/scripts/akm-migrate-node.js +43937 -93313
  175. package/dist/scripts/akm-migrate.js +43697 -93071
  176. package/dist/setup/registry-stash-loader.js +4 -13
  177. package/dist/setup/semantic-assets.js +3 -44
  178. package/dist/setup/setup.js +1 -1
  179. package/dist/setup/steps/tasks.js +25 -15
  180. package/dist/sources/provider-factory.js +17 -18
  181. package/dist/sources/providers/filesystem.js +2 -3
  182. package/dist/sources/providers/git-install.js +7 -1
  183. package/dist/sources/providers/git-provider.js +0 -3
  184. package/dist/sources/providers/git-stash.js +0 -17
  185. package/dist/sources/providers/npm.js +2 -4
  186. package/dist/sources/providers/provider-utils.js +5 -10
  187. package/dist/sources/providers/website.js +0 -2
  188. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  189. package/dist/sources/website-url.js +2 -2
  190. package/dist/storage/database.js +9 -35
  191. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  192. package/dist/storage/repositories/index-connection.js +34 -70
  193. package/dist/storage/repositories/index-entries-repository.js +69 -111
  194. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  195. package/dist/storage/repositories/index-entry-schema.js +83 -269
  196. package/dist/storage/repositories/index-fts-repository.js +86 -256
  197. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  198. package/dist/storage/repositories/index-meta-repository.js +6 -4
  199. package/dist/storage/repositories/index-schema.js +192 -220
  200. package/dist/storage/repositories/index-utility-repository.js +8 -29
  201. package/dist/storage/repositories/index-vec-repository.js +133 -414
  202. package/dist/storage/repositories/outcome-repository.js +2 -1
  203. package/dist/storage/repositories/proposals-repository.js +35 -0
  204. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  205. package/dist/storage/repositories/task-history-repository.js +26 -4
  206. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  207. package/dist/storage/sqlite-migrations.js +136 -0
  208. package/dist/storage/sqlite-pragmas.js +11 -9
  209. package/dist/storage/sqlite-transaction.js +170 -0
  210. package/dist/storage/state-db-integrity.js +34 -27
  211. package/dist/tasks/activation-config.js +134 -62
  212. package/dist/tasks/backends/cron.js +129 -277
  213. package/dist/tasks/backends/exec-utils.js +2 -5
  214. package/dist/tasks/backends/launchd.js +125 -745
  215. package/dist/tasks/backends/schtasks.js +101 -620
  216. package/dist/tasks/prepare/prepare-support.js +5 -15
  217. package/dist/tasks/prepare/prepare.js +0 -2
  218. package/dist/tasks/resolve-akm-bin.js +20 -79
  219. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  220. package/dist/tasks/scheduler-binding.js +18 -238
  221. package/dist/tasks/scheduler-invocation.js +52 -52
  222. package/dist/tasks/scheduler-lock.js +53 -0
  223. package/dist/tasks/scheduler-sync.js +363 -679
  224. package/dist/tasks/source/parse-task-source.js +160 -10
  225. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  226. package/dist/tasks/source/task-to-v4.js +2 -2
  227. package/dist/workflows/authoring/authoring.js +3 -12
  228. package/dist/workflows/compile.js +211 -0
  229. package/dist/workflows/concurrency-policy.js +13 -74
  230. package/dist/workflows/exec/child-invocation.js +3 -17
  231. package/dist/workflows/exec/child-workflow.js +32 -141
  232. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  233. package/dist/workflows/exec/environment.js +98 -0
  234. package/dist/workflows/exec/exec-unit.js +33 -140
  235. package/dist/workflows/exec/frozen-judge.js +7 -59
  236. package/dist/workflows/exec/native-executor.js +82 -341
  237. package/dist/workflows/exec/param-secrets.js +29 -47
  238. package/dist/workflows/exec/run-workflow.js +154 -387
  239. package/dist/workflows/exec/scheduler.js +9 -36
  240. package/dist/workflows/exec/step-work.js +127 -430
  241. package/dist/workflows/exec/unit-dispatch.js +11 -63
  242. package/dist/workflows/exec/unit-writer.js +8 -52
  243. package/dist/workflows/exec/worktree.js +39 -273
  244. package/dist/workflows/freeze/child-output-references.js +4 -15
  245. package/dist/workflows/freeze/environment.js +99 -92
  246. package/dist/workflows/freeze/freeze.js +172 -0
  247. package/dist/workflows/freeze/step-values.js +19 -21
  248. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  249. package/dist/workflows/freeze/targets/command.js +10 -33
  250. package/dist/workflows/freeze/targets/script.js +5 -12
  251. package/dist/workflows/freeze/targets/shell.js +3 -6
  252. package/dist/workflows/freeze/targets/task.js +25 -80
  253. package/dist/workflows/freeze/task-bindings.js +20 -67
  254. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  255. package/dist/workflows/ir/params.js +6 -51
  256. package/dist/workflows/ir/plan-hash.js +2 -34
  257. package/dist/workflows/parser.js +140 -43
  258. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  259. package/dist/workflows/renderer.js +36 -69
  260. package/dist/workflows/resource-limits.js +12 -120
  261. package/dist/workflows/runtime/agent-identity.js +8 -40
  262. package/dist/workflows/runtime/run-outputs.js +3 -6
  263. package/dist/workflows/runtime/run-plan.js +316 -0
  264. package/dist/workflows/runtime/runs.js +48 -200
  265. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  266. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  267. package/dist/workflows/validate-summary.js +2 -7
  268. package/docs/integration/bundling-akm.md +49 -42
  269. package/docs/migration/README.md +1 -0
  270. package/docs/migration/release-notes/0.9.17.md +41 -0
  271. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  272. package/docs/reference/cli.md +182 -125
  273. package/docs/reference/configuration.md +49 -56
  274. package/docs/reference/data-and-telemetry.md +19 -20
  275. package/docs/reference/tasks.md +86 -38
  276. package/docs/reference/workflow-schema.md +14 -18
  277. package/docs/reference/workflows.md +6 -9
  278. package/package.json +1 -1
  279. package/schemas/akm-config.json +87 -406
  280. package/dist/commands/health/advisories.js +0 -150
  281. package/dist/commands/health/metrics.js +0 -329
  282. package/dist/commands/health/surfaces.js +0 -102
  283. package/dist/commands/improve/anti-collapse.js +0 -83
  284. package/dist/commands/improve/collapse-detector.js +0 -432
  285. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  286. package/dist/commands/improve/consolidate/merge.js +0 -146
  287. package/dist/commands/improve/distill/promote-memory.js +0 -329
  288. package/dist/commands/improve/distill/quality-gate.js +0 -500
  289. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  290. package/dist/commands/improve/proposal-envelope.js +0 -31
  291. package/dist/commands/improve/run-context.js +0 -123
  292. package/dist/commands/improve/shared.js +0 -21
  293. package/dist/commands/improve/source-identity.js +0 -28
  294. package/dist/commands/improve/triage.js +0 -96
  295. package/dist/commands/proposal/drain-policies.js +0 -151
  296. package/dist/commands/sources/update-transaction.js +0 -220
  297. package/dist/core/action-contributors.js +0 -28
  298. package/dist/core/config/config-version-shim.js +0 -101
  299. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  300. package/dist/core/fs-txn.js +0 -405
  301. package/dist/core/lexical-score.js +0 -25
  302. package/dist/core/maintenance-barrier.js +0 -167
  303. package/dist/execution/executable-identity.js +0 -105
  304. package/dist/execution/guarded-source.js +0 -427
  305. package/dist/indexer/graph/graph-boost.js +0 -427
  306. package/dist/indexer/graph/graph-dedup.js +0 -95
  307. package/dist/indexer/search/name-match.js +0 -35
  308. package/dist/indexer/search/ranking-contributors.js +0 -515
  309. package/dist/indexer/walk/project-context.js +0 -192
  310. package/dist/integrations/agent/execution-cascade.js +0 -566
  311. package/dist/integrations/agent/execution-definitions.js +0 -202
  312. package/dist/integrations/agent/execution-lowering.js +0 -841
  313. package/dist/integrations/agent/execution-preparation.js +0 -98
  314. package/dist/integrations/agent/inline-execution.js +0 -74
  315. package/dist/registry/create-provider-registry.js +0 -29
  316. package/dist/registry/pinned-request-helper.js +0 -247
  317. package/dist/registry/pinned-transport.js +0 -717
  318. package/dist/sources/providers/index.js +0 -14
  319. package/dist/storage/engines/sqlite-migrations.js +0 -271
  320. package/dist/storage/repositories/canaries-repository.js +0 -107
  321. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  322. package/dist/storage/repositories/registry-cache.js +0 -113
  323. package/dist/tasks/scheduler-sync-preview.js +0 -52
  324. package/dist/workflows/freeze/resolve-steps.js +0 -86
  325. package/dist/workflows/freeze/source-freeze.js +0 -64
  326. package/dist/workflows/ir/compile.js +0 -321
  327. package/dist/workflows/ir/environment-v4.js +0 -330
  328. package/dist/workflows/ir/freeze-v4.js +0 -153
  329. package/dist/workflows/ir/schema-v4.js +0 -745
  330. package/dist/workflows/ir/schema.js +0 -354
  331. package/dist/workflows/program/schema.js +0 -78
  332. package/dist/workflows/runtime/checkin.js +0 -57
  333. package/dist/workflows/runtime/plan-classifier.js +0 -196
  334. package/dist/workflows/runtime/unit-checkin.js +0 -45
  335. package/dist/workflows/runtime/unit-phases.js +0 -20
  336. package/dist/workflows/schema.js +0 -4
  337. package/dist/workflows/source-ir/compile.js +0 -200
  338. package/dist/workflows/source-ir/program.js +0 -50
  339. package/dist/workflows/source-ir/result.js +0 -26
  340. package/dist/workflows/source-ir/schema.js +0 -786
  341. package/dist/workflows/source-ir/triggers.js +0 -79
  342. package/dist/workflows/source-ir/uses.js +0 -40
  343. package/dist/workflows/validator.js +0 -60
@@ -2,21 +2,12 @@
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
- * The `exec` unit runner — the ONE place a frozen workflow spawns a shell
6
- * command as a unit: argv-only (never a shell string), non-blocking,
7
- * detached with a SIGTERM→SIGKILL ladder against the whole process group,
8
- * cwd-contained by a resolved-path recheck, resource-bounded (timeout,
9
- * output bytes, context size), and allowlisted-environment (see
10
- * {@link childEnv}). `env` values reaching this module are already resolved
11
- * from `env:` bindings by NAME — the caller scrubs the outcome with
12
- * `redactUnitOutcome` before anything is journaled. A LEAF module by
13
- * layering (Node built-ins, `core/spawn-env`, `core/subprocess`, `core/warn`,
14
- * the import-free `workflows/resource-limits` only).
15
- *
16
- * See docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md
17
- * for the full per-invariant design history.
18
- *
19
- * @module workflows/exec/exec-unit
5
+ * The `exec` unit runner — the one place a frozen workflow spawns a command:
6
+ * argv-only, detached with a SIGTERM→SIGKILL ladder against the process group,
7
+ * cwd-contained by a resolved-path recheck, bounded (timeout, output bytes,
8
+ * context size), with an allowlisted environment ({@link childEnv}). The
9
+ * caller redacts the outcome before anything is journaled.
10
+ * See docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md.
20
11
  */
21
12
  import fs from "node:fs";
22
13
  import path from "node:path";
@@ -26,30 +17,16 @@ import { runManagedSubprocess, streamCaptureFailure, } from "../../core/subproce
26
17
  import { warn } from "../../core/warn.js";
27
18
  import { execContextLimits, utf8Bytes, WORKFLOW_EXEC_OUTPUT_TRUNCATED_MARKER, WORKFLOW_MAX_EXEC_OUTPUT_BYTES, WORKFLOW_UNIT_DIAGNOSTIC_CLIP, } from "../resource-limits.js";
28
19
  /**
29
- * Max characters of a failed command's stderr retained in the unit's `error`
30
- * diagnostic.
31
- *
32
- * Deliberately BELOW {@link WORKFLOW_UNIT_DIAGNOSTIC_CLIP}: the composed
33
- * diagnostic reads `<what happened>. stderr (last N chars): <tail>`, and the
34
- * journal clips that COMPOSED string head-first. Reserving 500 characters for
35
- * the prefix keeps the whole stderr tail — the part that actually says why the
36
- * command failed — inside the journaled and displayed diagnostic, instead of
37
- * losing its final few hundred characters to the outer clip.
20
+ * Max characters of a failed command's stderr tail kept in its diagnostic —
21
+ * below {@link WORKFLOW_UNIT_DIAGNOSTIC_CLIP} so the journal's head-first clip
22
+ * of the composed message never cuts the tail.
38
23
  */
39
24
  const EXEC_STDERR_DIAGNOSTIC_CLIP = WORKFLOW_UNIT_DIAGNOSTIC_CLIP - 500;
40
25
  /**
41
- * The DEFAULT environment allowlist for an exec unit's child — the single
42
- * definition of the EXEC list; `exec.passEnv` extends it per unit. Extends
43
- * {@link COMMON_SPAWN_ENV_PASSTHROUGH} (the same baseline agent-harness
44
- * children use) plus POSIX/Windows names load-bearing for ordinary commands
45
- * (PATH, HOME, USER/LOGNAME, SHELL, locale, TERM, TZ, TMPDIR, the
46
- * {@link WIN32_SPAWN_ENV_FLOOR}, Windows toolchain roots) and
47
- * `AKM_EVENT_SOURCE` (provenance, DRIFT-6). Deliberately ABSENT and reachable
48
- * only through `exec.passEnv` / `env:`: credentials, cloud/CI vars, and the
49
- * proxy family.
50
- *
51
- * See docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md
52
- * for the per-entry rationale and why the default is an allowlist at all.
26
+ * The default environment allowlist for an exec unit's child (`exec.passEnv`
27
+ * extends it): the agent-harness baseline plus names ordinary commands need
28
+ * and `AKM_EVENT_SOURCE`. Credentials, cloud/CI vars, and proxies reach a
29
+ * child only through `pass_env` or `env:`.
53
30
  */
54
31
  export const EXEC_DEFAULT_ENV_PASSTHROUGH = [
55
32
  // PATH, HOME, USER, LANG, LC_ALL, TERM, TMPDIR, AKM_EVENT_SOURCE
@@ -70,21 +47,11 @@ export const EXEC_DEFAULT_ENV_PASSTHROUGH = [
70
47
  "ProgramFiles",
71
48
  ];
72
49
  /**
73
- * Run one exec unit and map its process outcome onto the dispatch vocabulary:
74
- * non-zero exit → `non_zero_exit`, wall-clock expiry → `timeout`, cancellation
75
- * → `aborted`, a child that never started → `spawn_failed` (all pre-existing
76
- * `AgentFailureReason` members, so `retry.on` keeps working). The
77
- * out-of-taxonomy `exec_cwd_escape`, `exec_output_limit`,
78
- * `exec_context_too_large` and `exec_capture_incomplete` are deliberate: each
79
- * is tampering, a runaway, an authoring bug, or work that ALREADY RAN — never
80
- * a transient — so no `retry.on` value can ever re-dispatch one. An
81
- * INCOMPLETE stdout capture is always a failure, never a partial artifact;
82
- * output OVERFLOW past {@link WORKFLOW_MAX_EXEC_OUTPUT_BYTES} does not fail a
83
- * command that otherwise passed unless the unit declared an `output:` schema
84
- * (a truncated JSON prefix cannot parse).
85
- *
86
- * See docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md
87
- * for the full capture/overflow reasoning.
50
+ * Run one exec unit and map its outcome onto the dispatch vocabulary
51
+ * (`non_zero_exit`, `timeout`, `aborted`, `spawn_failed` — retryable). The
52
+ * `exec_*` reasons (cwd escape, output limit, context too large, incomplete
53
+ * capture) are deliberately outside `retry.on`. Output overflow fails only a
54
+ * unit that declared an `output:` schema.
88
55
  */
89
56
  export async function runExecUnit(input) {
90
57
  const cwd = await resolveExecCwd(input);
@@ -98,11 +65,7 @@ export async function runExecUnit(input) {
98
65
  cwd: cwd.path,
99
66
  env: childEnv(input.exec, input.env, input.context, input.eventSource),
100
67
  timeoutMs: input.timeoutMs,
101
- // stdout IS this unit's artifact, so RETENTION is BOUNDED: an unbounded
102
- // capture is memory the akm process spends on a command's behalf with no
103
- // ceiling at all until it exits or the (default 10-minute) budget expires.
104
- // The cap discards past the bound rather than killing — the command's own
105
- // outcome is not akm's memory problem to solve.
68
+ // stdout is the artifact; retention is bounded (discarding past the cap, never killing).
106
69
  maxOutputBytes: WORKFLOW_MAX_EXEC_OUTPUT_BYTES,
107
70
  ...(input.signal ? { signal: input.signal } : {}),
108
71
  ...(input.spawnFn ? { spawnFn: input.spawnFn } : {}),
@@ -172,21 +135,10 @@ export async function runExecUnit(input) {
172
135
  if (result.stdoutRead.overflowed && input.hasOutputSchema) {
173
136
  return outputLimitFailure(input, display, result);
174
137
  }
175
- // The promoted artifact is STDOUT. Trailing newlines are stripped, exactly
176
- // like shell command substitution `$(…)`, so a one-line command's artifact is
177
- // the value an author expects rather than the value plus a `\n`. stderr is a
178
- // diagnostic channel only and never contributes to the artifact. When stdout
179
- // overflowed, `stdout` already carries the truncation marker (which is
180
- // deliberately the LAST thing in the artifact, so it survives the strip).
138
+ // The artifact is stdout with trailing newlines stripped, like `$(…)`; stderr is diagnostic only.
181
139
  return { ok: true, text: stripTrailingNewlines(stdout) };
182
140
  }
183
- /**
184
- * A drain report with nothing wrong in it, passed as the OTHER pipe so
185
- * {@link streamCaptureFailure} classifies exactly one of them.
186
- *
187
- * The classifier stays shared with the agent path — what a failed drain means
188
- * must not drift — while each caller decides which pipes are fatal for IT.
189
- */
141
+ /** A clean drain report, passed as the other pipe so {@link streamCaptureFailure} classifies one. */
190
142
  const DRAINED_CLEAN = {
191
143
  text: "",
192
144
  timedOut: false,
@@ -194,14 +146,7 @@ const DRAINED_CLEAN = {
194
146
  bytesRead: 0,
195
147
  retainedBytes: 0,
196
148
  };
197
- /**
198
- * Report a stderr drain that did not finish on an otherwise successful unit.
199
- *
200
- * Warn-only by construction: the artifact is stdout, which was captured whole,
201
- * so there is nothing wrong with the unit's RESULT — only with how much of its
202
- * log tail akm holds. A dispatch result has no channel for a non-fatal note, so
203
- * the operator surface is the warn stream.
204
- */
149
+ /** Warn about an unfinished stderr drain on an otherwise successful unit (its stdout artifact is whole). */
205
150
  function reportStderrCaptureFailure(input, display, result) {
206
151
  const stderrFailure = streamCaptureFailure(DRAINED_CLEAN, result.stderrRead);
207
152
  if (!stderrFailure)
@@ -216,14 +161,7 @@ function truncationNote(read) {
216
161
  return (`the command wrote ${read.bytesRead} bytes to stdout and only the first ${read.retainedBytes} were retained ` +
217
162
  `(the ${WORKFLOW_MAX_EXEC_OUTPUT_BYTES}-byte per-pipe capture limit)`);
218
163
  }
219
- /**
220
- * The captured stdout, with an unmistakable truncation block appended when the
221
- * retention cap discarded part of it.
222
- *
223
- * Truncated data must never be mistakable for complete data. The block names
224
- * both byte counts, so a reader can see exactly how much is missing rather
225
- * than inferring it from a suspiciously round length.
226
- */
164
+ /** The captured stdout, with a truncation block naming both byte counts when the cap discarded some. */
227
165
  function markTruncatedStdout(result) {
228
166
  const read = result.stdoutRead;
229
167
  if (!read.overflowed)
@@ -235,17 +173,7 @@ function markTruncatedStdout(result) {
235
173
  `so its exit code is real, but THIS TEXT IS INCOMPLETE and must not be treated as the command's whole output. ` +
236
174
  `Have the command write bulk output to a file and print the path, or quiet it down.`);
237
175
  }
238
- /**
239
- * The output-cap failure for a unit that declared an `output:` schema —
240
- * deliberately UNMISTAKABLE.
241
- *
242
- * `text` is emptied rather than carrying the partial capture: for a failed unit
243
- * `text` is only a diagnostic (the durable evidence graph keeps a failure's
244
- * `failureReason` alone), and handing back several megabytes of a runaway
245
- * command's output as "the text" would just move the memory problem one layer
246
- * up. The byte counts go in the message instead, so the operator can see how far
247
- * past the cap the command ran.
248
- */
176
+ /** The output-cap failure for a unit with an `output:` schema: no partial text, byte counts in the message. */
249
177
  function outputLimitFailure(input, display, result) {
250
178
  return {
251
179
  ok: false,
@@ -259,31 +187,9 @@ function outputLimitFailure(input, display, result) {
259
187
  };
260
188
  }
261
189
  /**
262
- * Refuse to spawn when the engine-authored `AKM_*` context would not fit in the
263
- * child's environment ON THIS PLATFORM.
264
- *
265
- * A workflow artifact has no bound comparable to an OS environment entry, so a
266
- * perfectly legitimate declared input can serialize into an `AKM_INPUTS` far
267
- * past what `execve` accepts. Left unchecked that surfaces as a bare `E2BIG`
268
- * from the spawn syscall — reported as `spawn_failed` with a message about
269
- * "argument list too long" that names neither the variable nor the artifact
270
- * that produced it. Checking here converts it into a located, actionable
271
- * failure BEFORE process creation is attempted.
272
- *
273
- * ## The ceiling is the CURRENT platform's, never the smallest one
274
- *
275
- * That translation is this check's ONLY job, which fixes its bound exactly: the
276
- * limits come from {@link execContextLimits} for the platform the run is on. A
277
- * guard that applied Windows' 32 767-character ceiling on Linux would fail
278
- * spawns the kernel would happily have accepted — inventing a failure instead of
279
- * explaining an inevitable one, which is a tripwire and not a guard. Workflows
280
- * that must also run on Windows should stay under the smaller bound; that is
281
- * documented guidance (`docs/reference/workflow-schema.md`), not something a
282
- * Linux host enforces.
283
- *
284
- * Only the engine-authored context is measured. The unit's `env:` bindings are
285
- * authored values a human wrote and sized; this is the surface where the SIZE
286
- * is data-dependent and therefore surprising.
190
+ * Name the `AKM_*` variable that would not fit in the child's environment on
191
+ * this platform ({@link execContextLimits}), instead of a bare E2BIG from the
192
+ * spawn. Only the engine-authored context is measured.
287
193
  */
288
194
  function checkExecContextSize(input) {
289
195
  const limits = execContextLimits(input.platform ?? process.platform);
@@ -315,12 +221,8 @@ function contextTooLarge(input, what, names, limits) {
315
221
  }
316
222
  /**
317
223
  * Resolve `exec.cwd` inside `baseDir` and prove containment against the
318
- * RESOLVED base (symlinks included). The syntactic checks the parser and the
319
- * decoder already ran are necessary but not sufficient: `reports` can be a
320
- * symlink to `/etc`, and only a realpath comparison catches that.
321
- *
322
- * Async on purpose: this runs once per unit — up to 10 000 times for one map
323
- * step — on the dispatch path that must never block (see the module note).
224
+ * resolved base (a symlinked `reports` could point at `/etc`). Async: it runs
225
+ * per unit on the dispatch path.
324
226
  */
325
227
  async function resolveExecCwd(input) {
326
228
  const base = path.resolve(input.baseDir);
@@ -351,22 +253,13 @@ async function isExistingDirectory(candidate) {
351
253
  }
352
254
  }
353
255
  /**
354
- * The child's environment, in three layers with fixed precedence: (1) the
355
- * BASE — {@link EXEC_DEFAULT_ENV_PASSTHROUGH} plus the unit's `exec.passEnv`
356
- * names; (2) the unit's resolved `env:` bindings; (3) the engine-authored
357
- * `AKM_*` context, LAST so a workflow-supplied binding can never shadow the
358
- * ids/item the engine is telling the command the truth about.
359
- *
360
- * See docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md
361
- * for why the default is an allowlist rather than full inheritance.
256
+ * The child's environment, in precedence order: the allowlist plus
257
+ * `exec.passEnv`; the resolved `env:` bindings; then the engine's `AKM_*`
258
+ * context, last so a binding cannot shadow it.
362
259
  */
363
260
  function childEnv(exec, bindings, context, eventSource) {
364
261
  const env = collectAllowlistedEnv(execAllowlist(exec));
365
- // F-1 (spec §5.2 point 2): applied to the allowlisted BASE only when the
366
- // ambient passthrough above left the name absent — an ambient
367
- // AKM_EVENT_SOURCE already collected into `env` still wins, and this runs
368
- // strictly BEFORE the bindings/context overlays below, so an authored
369
- // `env:` binding (or the engine-authored context) still wins too.
262
+ // Only when absent from the base, and before the overlays, so ambient and authored values win.
370
263
  if (eventSource !== undefined && env.AKM_EVENT_SOURCE === undefined) {
371
264
  env.AKM_EVENT_SOURCE = eventSource;
372
265
  }
@@ -2,41 +2,11 @@
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
- * The gate judge built from the workflow's frozen current execution target.
6
- *
7
- * Two contracts this module owns, both of which the rest of the engine already
8
- * enforces for ordinary units and neither of which the judge may opt out of:
9
- *
10
- * 1. **Redaction.** A judge response IS journaled — `journalGateEvaluationFinish`
11
- * (exec/step-work.ts) writes the parsed verdict into the gate row's
12
- * `result_json`, and a judge failure's message becomes the blocked step's
13
- * notes. So the judge outcome goes through the SAME scrub every unit outcome
14
- * goes through: {@link collectWorkflowDispatchSensitiveValues} +
15
- * {@link withDispatchRedaction} (exec/dispatch-redaction.ts). Nothing about
16
- * a judge call reaches durable state before that scrub. Agent and direct-LLM
17
- * judges share one prepared/lowered dispatch request; the manual completion
18
- * path uses the same config-free dispatcher without opening an executor
19
- * import cycle.
20
- *
21
- * 2. **Identity.** The dispatch request carries the REAL run/step and the gate's
22
- * real node/unit ids — the same ids `journalGateEvaluationStart/Finish` write
23
- * (`<stepId>.gate` / `<stepId>.gate:l<loop>`) — so per-dispatch telemetry and
24
- * harness-side correlation describe the same thing the gate row describes.
25
- * The identity is threaded in from the caller that writes the row
26
- * ({@link SummaryJudge}'s `identity` argument); it is never synthesized here.
27
- *
28
- * A judge dispatch carries NO `env` bindings: the normalized gate target has
29
- * no environment key, so there is nothing authored to thread — and a step's
30
- * unit environment is scoped to the WORK,
31
- * not to the verifier. Redaction is unaffected: the sensitive-value set below
32
- * still covers the judge engine's credential and unsafe passthrough values.
33
- * Lowering notices are live execution metadata: units expose a typed result,
34
- * while judges retain their public string contract and emit only the common
35
- * lowerer's prompt/body-free notice projection through `warn()`. Current
36
- * result/evidence journal writers intentionally exclude these diagnostics;
37
- * this boundary makes no claim about future persistence ownership.
38
- *
39
- * @module workflows/exec/frozen-judge
5
+ * The gate judge built from the step's frozen judge target. Its outcome is
6
+ * journaled (the gate row, or a blocked step's notes), so it goes through the
7
+ * same dispatch redaction as every unit; its dispatch carries the real
8
+ * run/step and gate unit ids the gate row records. A judge carries no `env:`
9
+ * bindings (a step's environment belongs to the work, not the verifier).
40
10
  */
41
11
  import { warn } from "../../core/warn.js";
42
12
  import { collectWorkflowDispatchSensitiveValues, withDispatchRedaction } from "./dispatch-redaction.js";
@@ -45,13 +15,7 @@ import { dispatchWorkflowExecution, prepareWorkflowExecution, } from "./unit-dis
45
15
  export function gateNodeId(stepId) {
46
16
  return `${stepId}.gate`;
47
17
  }
48
- /**
49
- * Identity for one judge dispatch: the journaling caller's exact row identity
50
- * when it supplied one, else the owning run/step with the gate's node id as the
51
- * unit id. Either way the request names the REAL run — never a synthetic
52
- * `"gate"` placeholder, which made every judge dispatch indistinguishable from
53
- * every other one.
54
- */
18
+ /** Identity for one judge dispatch: the caller's row identity, else the run/step with the gate node id. */
55
19
  function dispatchIdentity(owner, identity) {
56
20
  return identity ?? { ...owner, unitId: gateNodeId(owner.stepId) };
57
21
  }
@@ -67,23 +31,7 @@ function warnLoweringNotices(...groups) {
67
31
  }
68
32
  }
69
33
  }
70
- /**
71
- * Build a gate judge from the normalized frozen target without consulting live
72
- * config.
73
- *
74
- * `eventSource` (P1b spec §5.2 point 2, gap closed — code review): the task
75
- * runner's resolved provenance event source, threaded through exactly like
76
- * `executeStepSubgraph`'s units so a workflow-task run's judge dispatch is not
77
- * the one dispatch left silently unstamped. Spread onto the built
78
- * {@link UnitDispatchRequest} the same way every other optional field here is
79
- * — `undefined` for the manual `akm workflow step complete` judge
80
- * (`runtime/runs.ts`, which passes no 5th argument) and for `akm workflow run`
81
- * (no task context), so both stay byte-identical. When present, it flows
82
- * through the same `forwardedDispatchEventSource` precedence gate every other
83
- * "command"-kind dispatch uses (`unit-dispatch.ts`): the module doc above
84
- * already establishes a judge request never carries an authored `env:`
85
- * binding, so the gate always forwards it here.
86
- */
34
+ /** Build a gate judge from the frozen target without consulting live config; `eventSource` stamps it like a unit. */
87
35
  export function frozenSummaryJudge(target, signal, dispatcher, owner, eventSource) {
88
36
  if (!target)
89
37
  return null;