akm-cli 0.9.1 → 0.9.2-alpha.2

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 (350) hide show
  1. package/CHANGELOG.md +103 -28
  2. package/README.md +3 -1
  3. package/SECURITY.md +1 -1
  4. package/STABILITY.md +1 -1
  5. package/dist/akm +2 -2
  6. package/dist/akm-migrate +2 -2
  7. package/dist/assets/hints/cli-hints-full.md +14 -9
  8. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -1
  9. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  10. package/dist/assets/models.json +35 -0
  11. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +3 -4
  12. package/dist/assets/stash-skeleton/facts/conventions/organization.md +1 -3
  13. package/dist/assets/tasks/core/extract.yml +6 -5
  14. package/dist/assets/tasks/core/improve.yml +6 -5
  15. package/dist/assets/tasks/core/index-refresh.yml +6 -5
  16. package/dist/assets/tasks/core/sync.yml +6 -5
  17. package/dist/assets/tasks/core/version-check.yml +6 -5
  18. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
  19. package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
  20. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
  21. package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
  22. package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
  23. package/dist/cli/confirm.js +2 -2
  24. package/dist/cli/parse-args.js +3 -24
  25. package/dist/cli/retired-commands.js +1 -1
  26. package/dist/cli/shared.js +2 -2
  27. package/dist/cli.js +11 -9
  28. package/dist/commands/agent/agent-dispatch.js +55 -89
  29. package/dist/commands/agent/contribute-cli.js +12 -45
  30. package/dist/commands/command/builtin-action.js +32 -0
  31. package/dist/commands/command/command-cli.js +99 -0
  32. package/dist/commands/command/command-execution.js +308 -0
  33. package/dist/commands/command/execution-source-loader.js +176 -0
  34. package/dist/commands/command/portable-template.js +60 -0
  35. package/dist/commands/config-cli.js +10 -4
  36. package/dist/commands/env/env.js +4 -2
  37. package/dist/commands/feedback-cli.js +1 -1
  38. package/dist/commands/health/checks.js +241 -29
  39. package/dist/commands/health/html-report.js +0 -14
  40. package/dist/commands/health/report-view-model.js +0 -1
  41. package/dist/commands/health/surfaces.js +6 -7
  42. package/dist/commands/health/types.js +0 -2
  43. package/dist/commands/health.js +63 -18
  44. package/dist/commands/improve/collapse-detector.js +5 -6
  45. package/dist/commands/improve/consolidate.js +251 -214
  46. package/dist/commands/improve/distill/promote-memory.js +71 -34
  47. package/dist/commands/improve/distill/quality-gate.js +17 -5
  48. package/dist/commands/improve/distill.js +232 -155
  49. package/dist/commands/improve/eligibility.js +112 -79
  50. package/dist/commands/improve/execution.js +57 -0
  51. package/dist/commands/improve/extract-cli.js +5 -5
  52. package/dist/commands/improve/extract-prompt.js +64 -22
  53. package/dist/commands/improve/extract.js +608 -360
  54. package/dist/commands/improve/improve-strategies.js +43 -14
  55. package/dist/commands/improve/improve.js +249 -29
  56. package/dist/commands/improve/loop-stages.js +11 -17
  57. package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
  58. package/dist/commands/improve/outcome-loop.js +22 -38
  59. package/dist/commands/improve/planner.js +134 -0
  60. package/dist/commands/improve/preparation.js +730 -409
  61. package/dist/commands/improve/reflect.js +386 -223
  62. package/dist/commands/improve/run-context.js +3 -4
  63. package/dist/commands/improve/salience.js +6 -58
  64. package/dist/commands/improve/session-asset.js +12 -12
  65. package/dist/commands/lint/index.js +101 -29
  66. package/dist/commands/migrate-cli.js +11 -69
  67. package/dist/commands/migration-tool.js +6 -9
  68. package/dist/commands/models-cli.js +27 -0
  69. package/dist/commands/proposal/drain.js +258 -186
  70. package/dist/commands/proposal/proposal-cli.js +32 -10
  71. package/dist/commands/proposal/proposal.js +2 -5
  72. package/dist/commands/proposal/propose.js +192 -172
  73. package/dist/commands/proposal/repository.js +54 -91
  74. package/dist/commands/proposal/validators/proposal-validators.js +9 -7
  75. package/dist/commands/read/curate.js +53 -22
  76. package/dist/commands/read/registry-search.js +25 -9
  77. package/dist/commands/read/remember-cli.js +14 -2
  78. package/dist/commands/read/search.js +10 -4
  79. package/dist/commands/read/show.js +139 -153
  80. package/dist/commands/registry-cli.js +16 -7
  81. package/dist/commands/remember.js +33 -18
  82. package/dist/commands/sources/add-cli.js +19 -178
  83. package/dist/commands/sources/bundle-cli.js +15 -3
  84. package/dist/commands/sources/dangerous-env-audit.js +135 -0
  85. package/dist/commands/sources/info.js +2 -1
  86. package/dist/commands/sources/installed-stashes.js +901 -177
  87. package/dist/commands/sources/schema-repair.js +174 -95
  88. package/dist/commands/sources/self-update.js +30 -74
  89. package/dist/commands/sources/source-add.js +3 -5
  90. package/dist/commands/sources/sources-cli.js +2 -15
  91. package/dist/commands/sources/update-transaction.js +220 -0
  92. package/dist/commands/tasks/tasks-cli.js +3 -3
  93. package/dist/commands/tasks/tasks.js +736 -317
  94. package/dist/commands/workflow-cli.js +2 -2
  95. package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
  96. package/dist/core/adapter/adapters/akm-adapter.js +85 -35
  97. package/dist/core/adapter/adapters/akm-lint.js +54 -39
  98. package/dist/core/adapter/adapters/akm-metadata.js +45 -45
  99. package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
  100. package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
  101. package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
  102. package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
  103. package/dist/core/adapter/adapters/index.js +0 -9
  104. package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
  105. package/dist/core/adapter/adapters/okf-adapter.js +4 -0
  106. package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
  107. package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
  108. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
  109. package/dist/core/adapter/execution-source.js +308 -0
  110. package/dist/core/adapter/recognize-match.js +36 -13
  111. package/dist/core/adapter/registry.js +0 -9
  112. package/dist/core/asset/stash-meta.js +94 -4
  113. package/dist/core/common.js +6 -11
  114. package/dist/core/config/config-io.js +3 -3
  115. package/dist/core/config/config-schema.js +18 -40
  116. package/dist/core/config/config-sources.js +11 -21
  117. package/dist/core/config/config-walker.js +31 -13
  118. package/dist/core/config/config.js +23 -26
  119. package/dist/core/config/schema/engines.js +8 -7
  120. package/dist/core/config/schema/improve-processes.js +29 -5
  121. package/dist/core/config/schema/index-config.js +0 -27
  122. package/dist/core/config/schema/primitives.js +1 -23
  123. package/dist/core/config/schema/sources-bundles.js +13 -16
  124. package/dist/core/errors.js +2 -0
  125. package/dist/core/events.js +68 -32
  126. package/dist/core/extra-params.js +1 -0
  127. package/dist/core/improve-result.js +315 -0
  128. package/dist/core/lesson-lint.js +0 -6
  129. package/dist/core/maintenance-barrier.js +4 -4
  130. package/dist/core/network-policy.js +152 -0
  131. package/dist/core/paths.js +1 -1
  132. package/dist/core/recognition-util.js +4 -4
  133. package/dist/core/registry-url.js +456 -0
  134. package/dist/core/state/migrations.js +161 -47
  135. package/dist/core/state-db.js +453 -80
  136. package/dist/core/system-error.js +32 -0
  137. package/dist/core/time.js +2 -12
  138. package/dist/core/write-source.js +0 -18
  139. package/dist/execution/directory-identity.js +52 -0
  140. package/dist/execution/executable-identity.js +107 -0
  141. package/dist/execution/guarded-source.js +398 -0
  142. package/dist/execution/json.js +95 -0
  143. package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
  144. package/dist/execution/record.js +55 -0
  145. package/dist/execution/resolved-request.js +730 -0
  146. package/dist/execution/source.js +320 -0
  147. package/dist/indexer/bundle-identity-guard.js +5 -4
  148. package/dist/indexer/db/graph-db.js +33 -0
  149. package/dist/indexer/graph/graph-boost.js +3 -4
  150. package/dist/indexer/graph/graph-extraction.js +562 -373
  151. package/dist/indexer/index-written-assets.js +78 -39
  152. package/dist/indexer/indexer.js +471 -432
  153. package/dist/indexer/installations.js +6 -0
  154. package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
  155. package/dist/indexer/materialize-embeddings.js +155 -0
  156. package/dist/indexer/passes/memory-inference.js +227 -174
  157. package/dist/indexer/passes/metadata.js +263 -118
  158. package/dist/indexer/scan/doc-to-entry.js +7 -10
  159. package/dist/indexer/scan/drain-dir.js +51 -23
  160. package/dist/indexer/search/db-search.js +156 -50
  161. package/dist/indexer/search/fts-query.js +40 -40
  162. package/dist/indexer/search/ranking.js +36 -1
  163. package/dist/indexer/search/search-attribution.js +3 -1
  164. package/dist/indexer/search/search-fields.js +23 -14
  165. package/dist/indexer/search/search-hit-enrichers.js +1 -1
  166. package/dist/indexer/search/search-source.js +7 -16
  167. package/dist/indexer/search/semantic-status.js +10 -1
  168. package/dist/indexer/usage/show-usage.js +105 -0
  169. package/dist/indexer/usage/usage-events.js +7 -2
  170. package/dist/indexer/walk/matchers.js +40 -10
  171. package/dist/indexer/walk/path-resolver.js +5 -2
  172. package/dist/indexer/walk/walker.js +20 -2
  173. package/dist/integrations/agent/builder-shared.js +3 -6
  174. package/dist/integrations/agent/conversation-fallback.js +16 -0
  175. package/dist/integrations/agent/engine-resolution.js +87 -87
  176. package/dist/integrations/agent/execution-cascade.js +566 -0
  177. package/dist/integrations/agent/execution-definitions.js +211 -0
  178. package/dist/integrations/agent/execution-lowering.js +811 -0
  179. package/dist/integrations/agent/execution-preparation.js +67 -0
  180. package/dist/integrations/agent/index.js +0 -2
  181. package/dist/integrations/agent/inline-execution.js +74 -0
  182. package/dist/integrations/agent/model-map.js +515 -0
  183. package/dist/integrations/agent/persona-fallback.js +30 -0
  184. package/dist/integrations/agent/request-lowering.js +186 -0
  185. package/dist/integrations/agent/runner-dispatch.js +230 -37
  186. package/dist/integrations/agent/runner.js +12 -83
  187. package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
  188. package/dist/integrations/harnesses/aider/index.js +0 -1
  189. package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
  190. package/dist/integrations/harnesses/amazonq/index.js +0 -1
  191. package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
  192. package/dist/integrations/harnesses/claude/index.js +1 -5
  193. package/dist/integrations/harnesses/claude/session-log.js +3 -33
  194. package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
  195. package/dist/integrations/harnesses/codex/index.js +0 -1
  196. package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
  197. package/dist/integrations/harnesses/copilot/index.js +0 -1
  198. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
  199. package/dist/integrations/harnesses/gemini/index.js +0 -1
  200. package/dist/integrations/harnesses/index.js +4 -44
  201. package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
  202. package/dist/integrations/harnesses/opencode/index.js +0 -2
  203. package/dist/integrations/harnesses/opencode/session-log.js +14 -204
  204. package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
  205. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
  206. package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
  207. package/dist/integrations/harnesses/openhands/index.js +0 -1
  208. package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
  209. package/dist/integrations/harnesses/pi/index.js +0 -1
  210. package/dist/integrations/harnesses/shared.js +0 -1
  211. package/dist/integrations/harnesses/types.js +1 -3
  212. package/dist/integrations/lockfile.js +82 -79
  213. package/dist/integrations/session-logs/index.js +6 -17
  214. package/dist/integrations/session-logs/provider-base.js +1 -29
  215. package/dist/llm/client.js +10 -5
  216. package/dist/llm/embedder.js +6 -7
  217. package/dist/llm/embedders/local.js +37 -88
  218. package/dist/llm/embedders/types.js +1 -1
  219. package/dist/llm/graph-extract.js +75 -50
  220. package/dist/llm/index-passes.js +43 -5
  221. package/dist/llm/memory-infer.js +8 -6
  222. package/dist/llm/metadata-enhance.js +5 -3
  223. package/dist/llm/structured-call.js +122 -25
  224. package/dist/output/format-exempt.js +1 -1
  225. package/dist/output/render-registry.js +0 -16
  226. package/dist/output/renderers.js +12 -7
  227. package/dist/output/shapes/curate.js +1 -0
  228. package/dist/output/shapes/helpers.js +10 -2
  229. package/dist/output/shapes/passthrough.js +2 -0
  230. package/dist/output/text/command-format.js +31 -33
  231. package/dist/output/text/health-format.js +1 -29
  232. package/dist/output/text/migrate.js +6 -56
  233. package/dist/output/text/proposal-format.js +16 -1
  234. package/dist/output/text/workflow-format.js +16 -0
  235. package/dist/registry/network.js +279 -0
  236. package/dist/registry/pinned-request-helper.js +247 -0
  237. package/dist/registry/pinned-transport.js +717 -0
  238. package/dist/registry/providers/skills-sh.js +18 -6
  239. package/dist/registry/providers/static-index.js +20 -7
  240. package/dist/registry/resolve.js +53 -28
  241. package/dist/scripts/akm-migrate-node.js +19334 -52269
  242. package/dist/scripts/akm-migrate.js +19270 -51612
  243. package/dist/setup/registry-stash-loader.js +64 -20
  244. package/dist/setup/semantic-assets.js +9 -34
  245. package/dist/setup/setup.js +12 -30
  246. package/dist/setup/source-identity.js +17 -0
  247. package/dist/setup/steps/sources.js +36 -15
  248. package/dist/setup/steps/tasks.js +39 -11
  249. package/dist/sources/providers/git-provider.js +3 -3
  250. package/dist/sources/providers/npm.js +2 -2
  251. package/dist/sources/providers/provider-utils.js +4 -3
  252. package/dist/sources/providers/website.js +11 -7
  253. package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
  254. package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
  255. package/dist/sources/website-url.js +73 -0
  256. package/dist/storage/engines/sqlite-migrations.js +81 -26
  257. package/dist/storage/managed-db.js +27 -24
  258. package/dist/storage/repositories/events-repository.js +3 -0
  259. package/dist/storage/repositories/index-connection.js +42 -10
  260. package/dist/storage/repositories/index-entries-repository.js +203 -229
  261. package/dist/storage/repositories/index-entry-mapper.js +8 -12
  262. package/dist/storage/repositories/index-entry-schema.js +255 -0
  263. package/dist/storage/repositories/index-fts-repository.js +64 -71
  264. package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
  265. package/dist/storage/repositories/index-meta-repository.js +0 -11
  266. package/dist/storage/repositories/index-schema.js +74 -350
  267. package/dist/storage/repositories/index-utility-repository.js +12 -17
  268. package/dist/storage/repositories/index-vec-repository.js +56 -7
  269. package/dist/storage/repositories/proposals-repository.js +4 -127
  270. package/dist/storage/repositories/registry-cache.js +2 -1
  271. package/dist/storage/repositories/task-history-repository.js +20 -40
  272. package/dist/storage/repositories/workflow-runs-repository.js +228 -129
  273. package/dist/storage/sqlite-read-snapshot.js +148 -0
  274. package/dist/tasks/backends/cron.js +170 -42
  275. package/dist/tasks/backends/index.js +1 -1
  276. package/dist/tasks/backends/launchd.js +787 -202
  277. package/dist/tasks/backends/schtasks.js +282 -83
  278. package/dist/tasks/embedded.js +7 -7
  279. package/dist/tasks/frozen-script.js +50 -0
  280. package/dist/tasks/resolve-akm-bin.js +5 -1
  281. package/dist/tasks/runner.js +239 -251
  282. package/dist/tasks/runtime-v3.js +281 -0
  283. package/dist/tasks/scheduler-binding.js +272 -0
  284. package/dist/tasks/scheduler-invocation.js +57 -43
  285. package/dist/tasks/scheduler-sync.js +654 -0
  286. package/dist/tasks/source-v3.js +752 -0
  287. package/dist/tasks/standalone-script-entry.js +5 -0
  288. package/dist/tasks/task-id.js +29 -0
  289. package/dist/workflows/authoring/authoring.js +15 -32
  290. package/dist/workflows/exec/dispatch-redaction.js +14 -8
  291. package/dist/workflows/exec/exec-unit.js +7 -28
  292. package/dist/workflows/exec/frozen-judge.js +57 -89
  293. package/dist/workflows/exec/lowering-notices.js +23 -0
  294. package/dist/workflows/exec/native-executor.js +301 -458
  295. package/dist/workflows/exec/param-secrets.js +4 -3
  296. package/dist/workflows/exec/run-workflow.js +26 -32
  297. package/dist/workflows/exec/step-work.js +105 -109
  298. package/dist/workflows/exec/unit-dispatch.js +103 -27
  299. package/dist/workflows/exec/unit-writer.js +3 -3
  300. package/dist/workflows/exec/worktree.js +2 -2
  301. package/dist/workflows/ir/compile.js +86 -72
  302. package/dist/workflows/ir/environment-v4.js +328 -0
  303. package/dist/workflows/ir/freeze-v4.js +122 -0
  304. package/dist/workflows/ir/plan-hash.js +13 -7
  305. package/dist/workflows/ir/schema-v4.js +525 -0
  306. package/dist/workflows/ir/schema.js +25 -284
  307. package/dist/workflows/ir/source-freeze-v4.js +506 -0
  308. package/dist/workflows/parser.js +27 -24
  309. package/dist/workflows/program/schema.js +1 -2
  310. package/dist/workflows/renderer.js +42 -29
  311. package/dist/workflows/resource-limits.js +4 -5
  312. package/dist/workflows/runtime/agent-identity.js +11 -13
  313. package/dist/workflows/runtime/plan-classifier.js +8 -8
  314. package/dist/workflows/runtime/runs.js +27 -43
  315. package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
  316. package/dist/workflows/source-files.js +373 -0
  317. package/dist/workflows/source-ir/compile.js +196 -0
  318. package/dist/workflows/source-ir/github-yaml.js +577 -0
  319. package/dist/workflows/source-ir/ordering.js +38 -0
  320. package/dist/workflows/source-ir/program.js +50 -0
  321. package/dist/workflows/source-ir/result.js +26 -0
  322. package/dist/workflows/source-ir/schema.js +772 -0
  323. package/dist/workflows/source-ir/semantics.js +242 -0
  324. package/dist/workflows/source-ir/uses.js +14 -0
  325. package/docs/README.md +2 -0
  326. package/docs/migration/README.md +3 -1
  327. package/docs/migration/release-notes/0.9.2.md +55 -0
  328. package/docs/migration/release-notes/README.md +5 -0
  329. package/docs/migration/v0.8-to-v0.9.md +76 -1077
  330. package/docs/migration/v0.9.0-troubleshooting.md +104 -516
  331. package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
  332. package/docs/reference/README.md +1 -0
  333. package/docs/reference/cli.md +230 -98
  334. package/docs/reference/configuration.md +159 -36
  335. package/docs/reference/data-and-telemetry.md +19 -1
  336. package/docs/reference/supported-formats.md +23 -3
  337. package/docs/reference/tasks.md +182 -0
  338. package/docs/reference/workflow-schema.md +91 -40
  339. package/docs/reference/workflows.md +33 -6
  340. package/package.json +10 -6
  341. package/schemas/akm-config.json +372 -224
  342. package/schemas/akm-task.json +324 -80
  343. package/schemas/akm-workflow.json +6 -9
  344. package/dist/core/migration-operation.js +0 -75
  345. package/dist/integrations/agent/model-aliases.js +0 -74
  346. package/dist/tasks/parser.js +0 -380
  347. package/dist/tasks/schema.js +0 -123
  348. package/dist/tasks/validator.js +0 -80
  349. package/dist/workflows/ir/freeze.js +0 -320
  350. package/dist/workflows/runtime/document-cache.js +0 -13
@@ -2,17 +2,17 @@
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
- * Show + indexing renderer for the unified workflow asset (workflow-format-
6
- * unification). One format now: reads the frontmatter+body document via
7
- * `parseWorkflow` and projects the validated `WorkflowDocument` down to the
8
- * public `ShowResponse` shape and into search hints for the indexer,
5
+ * Show + indexing renderer for peer workflow sources. `.md` and `.yml` both
6
+ * compile through `compileWorkflowSource` into source IR v1, which is projected
7
+ * down to the public `ShowResponse` shape and into search hints for the indexer,
9
8
  * including a compact per-step orchestration summary (engine/model or an exec
10
9
  * unit's argv, `map.over` reference, route table) when the step declares one.
11
10
  */
12
11
  import { displayRef } from "../core/asset/resolve-ref.js";
13
12
  import { UsageError } from "../core/errors.js";
14
- import { parseWorkflow } from "./parser.js";
15
13
  import { projectExecCore } from "./program/schema.js";
14
+ import { compileWorkflowSource } from "./source-ir/compile.js";
15
+ import { sourceStepInstructions, workflowShellCommand } from "./source-ir/program.js";
16
16
  function shellQuote(value) {
17
17
  return `'${value.replace(/'/g, `'\\''`)}'`;
18
18
  }
@@ -26,11 +26,11 @@ function deriveName(ctx) {
26
26
  const ext = ctx.relPath.lastIndexOf(".");
27
27
  return ext > 0 ? ctx.relPath.slice(0, ext) : ctx.relPath;
28
28
  }
29
- function loadDocument(ctx) {
30
- const result = parseWorkflow(ctx.content(), { path: ctx.relPath });
29
+ function loadSourceIr(ctx) {
30
+ const result = compileWorkflowSource(ctx.content(), { path: ctx.relPath, workspaceRoot: ctx.stashRoot });
31
31
  if (result.ok)
32
- return result.document;
33
- const summary = result.errors.map((e) => `${ctx.relPath}:${e.line} — ${e.message}`).join("\n");
32
+ return result.ir;
33
+ const summary = result.errors.map((e) => `${e.path}:${e.line} — ${e.message}`).join("\n");
34
34
  throw new UsageError(`Workflow has errors:\n${summary}`);
35
35
  }
36
36
  /**
@@ -40,8 +40,9 @@ function loadDocument(ctx) {
40
40
  * a non-empty instructions string).
41
41
  */
42
42
  function stepInstructions(step) {
43
- if (step.instructions)
44
- return step.instructions.text;
43
+ const instructions = sourceStepInstructions(step);
44
+ if (instructions)
45
+ return instructions;
45
46
  if (step.route) {
46
47
  const branches = step.route.branches.map((b) => `"${b.match}" -> ${b.stepId}`);
47
48
  if (step.route.defaultStepId !== undefined)
@@ -51,10 +52,10 @@ function stepInstructions(step) {
51
52
  return "";
52
53
  }
53
54
  /** Project the `params` block into the flat `WorkflowParameter` list. */
54
- function projectParameters(document) {
55
- if (!document.params)
55
+ function projectParameters(sourceIr) {
56
+ if (!sourceIr.params)
56
57
  return undefined;
57
- const parameters = Object.entries(document.params).map(([name, schema]) => {
58
+ const parameters = Object.entries(sourceIr.params).map(([name, schema]) => {
58
59
  const description = schema.description;
59
60
  return { name, ...(typeof description === "string" && description !== "" ? { description } : {}) };
60
61
  });
@@ -91,8 +92,15 @@ function projectParameters(document) {
91
92
  * `instructions` this same projection already carries whole.
92
93
  */
93
94
  function summarizeStepOrchestration(step, defaults) {
94
- const unit = step.unit ?? step.map?.unit;
95
- const exec = unit?.exec;
95
+ const unit = step.unit;
96
+ const exec = step.exec
97
+ ? step.exec
98
+ : step.run !== undefined
99
+ ? {
100
+ command: workflowShellCommand(step.shell ?? "sh", step.run),
101
+ ...(step.workingDirectory ? { cwd: step.workingDirectory } : {}),
102
+ }
103
+ : undefined;
96
104
  const engine = exec ? undefined : (unit?.engine ?? defaults?.engine);
97
105
  const model = exec ? undefined : (unit?.model ?? defaults?.model);
98
106
  const timeoutMs = unit?.timeoutMs !== undefined ? unit.timeoutMs : defaults?.timeoutMs;
@@ -126,16 +134,21 @@ function summarizeStepOrchestration(step, defaults) {
126
134
  };
127
135
  return Object.keys(summary).length > 0 ? summary : undefined;
128
136
  }
129
- function projectStepDefinitions(document) {
130
- return document.steps.map((step) => {
131
- const orchestration = summarizeStepOrchestration(step, document.defaults);
137
+ function projectStepDefinitions(sourceIr) {
138
+ const flattened = sourceIr.jobs.flatMap((job) => job.steps.map((step) => ({ jobId: job.id, step })));
139
+ const counts = new Map();
140
+ for (const { step } of flattened)
141
+ counts.set(step.id, (counts.get(step.id) ?? 0) + 1);
142
+ return flattened.map(({ jobId, step }, sequenceIndex) => {
143
+ const id = (counts.get(step.id) ?? 0) > 1 ? `${jobId}-${step.id}` : step.id;
144
+ const orchestration = summarizeStepOrchestration(step, sourceIr.defaults);
132
145
  return {
133
- id: step.id,
134
- // No titles anywhere in the unified format — a step IS its id.
146
+ id,
147
+ // No titles in the shared source IR — a step IS its id.
135
148
  title: step.id,
136
149
  instructions: stepInstructions(step),
137
- ...(step.gateRubric?.text.trim() ? { completionCriteria: [step.gateRubric.text] } : {}),
138
- sequenceIndex: step.sequenceIndex,
150
+ ...(step.gate?.rubric?.trim() ? { completionCriteria: [step.gate.rubric] } : {}),
151
+ sequenceIndex,
139
152
  ...(orchestration ? { orchestration } : {}),
140
153
  };
141
154
  });
@@ -144,26 +157,26 @@ export const workflowMdRenderer = {
144
157
  name: "workflow-md",
145
158
  buildShowResponse(ctx) {
146
159
  const name = deriveName(ctx);
147
- const doc = loadDocument(ctx);
160
+ const sourceIr = loadSourceIr(ctx);
148
161
  // WI-8.5b (display flip): the `akm workflow run <ref>` action is DISPLAY
149
162
  // output — its spelling follows the D-R5 display rule (`displayRef`). A
150
163
  // primary/default-bundle workflow renders the SHORT conceptId
151
164
  // (`workflows/<name>`); a named source qualifies it as
152
165
  // (`<bundle>//workflows/<name>`).
153
166
  const ref = displayRef({ type: "workflow", name, bundleId: ctx.origin }, ctx.defaultBundle);
154
- const parameters = projectParameters(doc);
167
+ const parameters = projectParameters(sourceIr);
155
168
  return {
156
169
  type: "workflow",
157
170
  name,
158
171
  path: ctx.absPath,
159
172
  action: buildWorkflowAction(ref),
160
- ...(doc.preamble ? { content: doc.preamble } : {}),
161
- description: doc.description,
162
- // No authored title in the unified format — the asset's human name is
173
+ ...(sourceIr.preamble ? { content: sourceIr.preamble } : {}),
174
+ description: sourceIr.description,
175
+ // No authored title in the shared source IR — the asset's human name is
163
176
  // its `description`/H1 like any other asset; this is its canonical name.
164
177
  workflowTitle: name,
165
178
  ...(parameters ? { parameters: parameters.map((p) => p.name), workflowParameters: parameters } : {}),
166
- steps: projectStepDefinitions(doc),
179
+ steps: projectStepDefinitions(sourceIr),
167
180
  };
168
181
  },
169
182
  };
@@ -1,6 +1,7 @@
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
+ import { EXECUTION_MAX_TIMEOUT_MS } from "../execution/limits.js";
4
5
  export const WORKFLOW_MAX_PLAN_BYTES = 2 * 1024 * 1024;
5
6
  export const WORKFLOW_MAX_SOURCE_BYTES = 1024 * 1024;
6
7
  export const WORKFLOW_MAX_STEPS = 256;
@@ -33,7 +34,7 @@ export const WORKFLOW_MAX_GATE_LOOPS = 100;
33
34
  /** Max retry attempts per unit. */
34
35
  export const WORKFLOW_MAX_RETRIES = 100;
35
36
  /** Max timeout in milliseconds (setTimeout's 32-bit signed ceiling: 2^31-1, ~24.8 days). */
36
- export const WORKFLOW_MAX_TIMEOUT_MS = 2 ** 31 - 1;
37
+ export const WORKFLOW_MAX_TIMEOUT_MS = EXECUTION_MAX_TIMEOUT_MS;
37
38
  /** Engine names: lowercase dash-separated runs of letters/digits, starting with a letter. */
38
39
  export const WORKFLOW_ENGINE_NAME_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
39
40
  export const WORKFLOW_MAX_ENGINE_NAME_LENGTH = 63;
@@ -51,10 +52,8 @@ export const WORKFLOW_MAX_EXEC_CWD_LENGTH = 1024;
51
52
  /**
52
53
  * Max entries in an exec unit's `pass_env:` list.
53
54
  *
54
- * `pass_env` is the "one or two more toolchain variables" escape hatch, not a
55
- * second way to spell `inherit_env:` a workflow reaching for more than this
56
- * many names wants full inheritance and should say so where a reviewer can see
57
- * it.
55
+ * `pass_env` is bounded; use explicit named `env:` bindings for a larger set.
56
+ * New v4 starts do not offer whole-process inheritance.
58
57
  */
59
58
  export const WORKFLOW_MAX_EXEC_PASS_ENV = 32;
60
59
  /**
@@ -2,13 +2,13 @@
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
- * Resolve the agent harness + session identity for the current process.
5
+ * Resolve the invoking harness/session identity for the current process.
6
6
  *
7
- * This is the first concrete slice of #501 / #506: capturing *who* is driving a
8
- * workflow run so a future (separately-approved) monitor can correlate runs
9
- * with session activity. It deliberately does NOT start any background thread,
10
- * timer, or daemon — it only reads identity that the surrounding agent harness
11
- * already exposes via the environment.
7
+ * This is the first concrete slice of #501 / #506: capturing the invoking
8
+ * harness/session identity so a future (separately-approved) monitor can
9
+ * correlate runs with session activity. It deliberately does NOT start any
10
+ * background thread, timer, or daemon — it only reads identity that the
11
+ * surrounding agent harness already exposes via the environment.
12
12
  *
13
13
  * Resolution is best-effort and environment-driven:
14
14
  * - harness: AKM_AGENT_HARNESS, else inferred from a harness session-id
@@ -30,7 +30,7 @@
30
30
  *
31
31
  * @module workflows/agent-identity
32
32
  */
33
- import { denormalizeRuntimeIdentity, HARNESS_REGISTRY } from "../../integrations/harnesses/index.js";
33
+ import { HARNESS_REGISTRY } from "../../integrations/harnesses/index.js";
34
34
  /**
35
35
  * Derive a marker table from one registry env-var field, ordered by canonical
36
36
  * id. The sort keeps the pre-derivation precedence byte-identical ('claude'
@@ -67,15 +67,13 @@ export function resolveAgentIdentity(env = process.env) {
67
67
  if (!harness) {
68
68
  // Infer the harness from a harness-specific *session* env var first
69
69
  // (registry `identityEnv` markers). A concrete session id is the
70
- // strongest evidence of the immediate driver, so it outranks any
70
+ // strongest evidence of the invoking harness/session context, so it
71
+ // outranks any
71
72
  // presence flag — e.g. opencode launched inside a codex sandbox
72
73
  // (OPENCODE_SESSION_ID + CODEX_SANDBOX) attributes to opencode.
73
74
  for (const marker of SESSION_MARKERS) {
74
75
  if (firstNonEmpty(env, marker.envKeys)) {
75
- // Report the harness's RUNTIME identity (e.g. canonical 'claude' →
76
- // 'claude-code') via the registry's #562 bridge so the persisted
77
- // runtime string can't drift.
78
- harness = denormalizeRuntimeIdentity(marker.harnessId);
76
+ harness = marker.harnessId;
79
77
  break;
80
78
  }
81
79
  }
@@ -87,7 +85,7 @@ export function resolveAgentIdentity(env = process.env) {
87
85
  // but they carry no session id, so sessionId stays null below.
88
86
  for (const marker of PRESENCE_MARKERS) {
89
87
  if (firstNonEmpty(env, marker.envKeys)) {
90
- harness = denormalizeRuntimeIdentity(marker.harnessId);
88
+ harness = marker.harnessId;
91
89
  break;
92
90
  }
93
91
  }
@@ -3,7 +3,7 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import { UsageError } from "../../core/errors.js";
5
5
  import { decodeCanonicalPlan } from "../ir/plan-hash.js";
6
- import { WORKFLOW_IR_VERSION } from "../ir/schema.js";
6
+ import { WORKFLOW_IR_V4_VERSION } from "../ir/schema-v4.js";
7
7
  /** Validate that a live run carries exactly the current frozen-plan format. */
8
8
  export function classifyWorkflowRunPlan(row) {
9
9
  const runId = row.id ?? "(unknown)";
@@ -16,31 +16,31 @@ export function classifyWorkflowRunPlan(row) {
16
16
  }
17
17
  if (row.plan_ir_version !== null &&
18
18
  row.plan_ir_version !== undefined &&
19
- row.plan_ir_version !== WORKFLOW_IR_VERSION) {
19
+ row.plan_ir_version !== WORKFLOW_IR_V4_VERSION) {
20
20
  return {
21
21
  support: "unsupported-version",
22
22
  irVersion: row.plan_ir_version,
23
- error: `Workflow run ${runId} uses unsupported workflow IR version ${row.plan_ir_version}; this runtime requires version ${WORKFLOW_IR_VERSION}.`,
23
+ error: `Workflow run ${runId} uses unsupported workflow IR version ${row.plan_ir_version}; this runtime supports only workflow IR version 4. Start a new run from the authored workflow.`,
24
24
  };
25
25
  }
26
- if (row.plan_ir_version !== WORKFLOW_IR_VERSION) {
26
+ if (row.plan_ir_version !== WORKFLOW_IR_V4_VERSION) {
27
27
  return {
28
28
  support: "corrupt-plan",
29
29
  irVersion: null,
30
- error: `Workflow run ${runId} does not declare workflow IR version ${WORKFLOW_IR_VERSION}.`,
30
+ error: `Workflow run ${runId} does not declare a supported workflow IR version.`,
31
31
  };
32
32
  }
33
33
  try {
34
34
  return {
35
35
  support: "supported",
36
- irVersion: WORKFLOW_IR_VERSION,
37
- plan: decodeCanonicalPlan(runId, row.plan_json, row.plan_hash),
36
+ irVersion: row.plan_ir_version,
37
+ plan: decodeCanonicalPlan(runId, row.plan_json, row.plan_hash, row.plan_ir_version),
38
38
  };
39
39
  }
40
40
  catch (cause) {
41
41
  return {
42
42
  support: "corrupt-plan",
43
- irVersion: WORKFLOW_IR_VERSION,
43
+ irVersion: row.plan_ir_version,
44
44
  error: cause instanceof Error ? cause.message : String(cause),
45
45
  };
46
46
  }
@@ -13,10 +13,9 @@ import { getCurrentWorkflowScopeKey } from "../authoring/scope-key.js";
13
13
  import { frozenSummaryJudge } from "../exec/frozen-judge.js";
14
14
  import { detectSecretShapedParams } from "../exec/param-secrets.js";
15
15
  import { collectWorkflowWarnings } from "../ir/compile.js";
16
- import { compileResolveFreezeWorkflow } from "../ir/freeze.js";
16
+ import { compileResolveFreezeWorkflowV4 } from "../ir/freeze-v4.js";
17
17
  import { materializeWorkflowParameterFlags, validateWorkflowParams } from "../ir/params.js";
18
18
  import { canonicalPlanJson, computePlanHash } from "../ir/plan-hash.js";
19
- import { decodeWorkflowPlanV3, WORKFLOW_IR_VERSION } from "../ir/schema.js";
20
19
  import { clip, utf8Bytes, WORKFLOW_EVIDENCE_TRUNCATION_PREVIEW_CHARS, WORKFLOW_MAX_EVIDENCE_JSON_BYTES, WORKFLOW_UNIT_DIAGNOSTIC_CLIP, } from "../resource-limits.js";
21
20
  import { validateStepSummary } from "../validate-summary.js";
22
21
  import { resolveAgentIdentity } from "./agent-identity.js";
@@ -33,7 +32,7 @@ const IR_RUNTIME_KINDS = { llm: true, agent: true, sdk: true, exec: true };
33
32
  function runtimeKindOf(runner) {
34
33
  return runner !== null && Object.hasOwn(IR_RUNTIME_KINDS, runner) ? runner : null;
35
34
  }
36
- function toUnitDiagnostic(row, stale, plannedEngine) {
35
+ function toUnitDiagnostic(row, stale) {
37
36
  let diagnostic = null;
38
37
  if (row.result_json !== null) {
39
38
  // `result_json` is a JSON-encoded value: a bare JSON string for a free-text
@@ -69,7 +68,7 @@ function toUnitDiagnostic(row, stale, plannedEngine) {
69
68
  claimExpiresAt: row.claim_expires_at,
70
69
  engine: row.engine ?? null,
71
70
  runtimeKind: runtimeKindOf(row.runner),
72
- platform: plannedEngine?.kind === "agent" ? plannedEngine.platform : null,
71
+ platform: null,
73
72
  };
74
73
  }
75
74
  export async function startWorkflowRun(ref, params = {}, options) {
@@ -78,8 +77,8 @@ export async function startWorkflowRun(ref, params = {}, options) {
78
77
  // persist it on the run row in the same transaction as the insert. Every
79
78
  // later invocation executes this snapshot — the asset file is never re-read
80
79
  // for an in-flight run; re-planning is an explicit new run.
81
- const frozen = compileResolveFreezeWorkflow(asset, loadConfig());
82
- const plan = decodeWorkflowPlanV3(frozen.plan);
80
+ const frozen = await compileResolveFreezeWorkflowV4(asset, loadConfig());
81
+ const plan = frozen.plan;
83
82
  if (options?.parameterFlags?.length && Object.keys(params).length > 0) {
84
83
  throw new UsageError("Workflow parameters must use either an object or per-parameter flags, not both.");
85
84
  }
@@ -89,7 +88,7 @@ export async function startWorkflowRun(ref, params = {}, options) {
89
88
  // Non-fatal WARNINGS: untyped-step and undeclared-param advisories surface
90
89
  // as `warn()` lines at start (stderr, consistent with the repo's other
91
90
  // author-facing warnings) without blocking the run.
92
- for (const w of collectWorkflowWarnings(asset.document)) {
91
+ for (const w of collectWorkflowWarnings(asset.sourceIr)) {
93
92
  warn(`workflow run: ${asset.path}:${w.line} — ${w.message}`);
94
93
  }
95
94
  // Reviewer #12: validate supplied parameters against the frozen param
@@ -111,7 +110,7 @@ export async function startWorkflowRun(ref, params = {}, options) {
111
110
  const scopeKey = getCurrentWorkflowScopeKey();
112
111
  const currentStepId = plan.steps[0]?.stepId ?? null;
113
112
  const workflowEntryId = resolveWorkflowEntryId(asset.sourcePath, asset.ref, asset.adapterId);
114
- // Capture the agent harness + session driving this run. Explicit options
113
+ // Capture the invoking harness/session identity for this run. Explicit options
115
114
  // win; otherwise fall back to best-effort environment detection. This is
116
115
  // identity-only — no background thread or timer is started here.
117
116
  const detected = resolveAgentIdentity();
@@ -127,15 +126,10 @@ export async function startWorkflowRun(ref, params = {}, options) {
127
126
  // per the workflow-agent check-in ADR) so a stalled run can be
128
127
  // re-targeted with a `continue` directive. The agent harness + session id
129
128
  // are already resolved above (agentHarness/agentSessionId, from #501).
130
- repo.immediateTransaction(() => {
131
- if (!options?.force) {
132
- const existing = repo.findActiveRunForScope(workflowRefs, scopeKey);
133
- if (existing) {
134
- throw new UsageError(`Workflow ${asset.ref} already has an active run in this scope (id=${existing.id}, step=${existing.current_step_id ?? "—"}). ` +
135
- `Use 'akm workflow run ${asset.ref}' to resume it or 'akm workflow abandon ${existing.id}' to give up on it.`, "RESOURCE_ALREADY_EXISTS");
136
- }
137
- }
138
- repo.insertRun({
129
+ repo.publishWorkflowRunV4({
130
+ workflowRefs,
131
+ ...(options?.force ? { force: true } : {}),
132
+ run: {
139
133
  id: runId,
140
134
  workflowRef: asset.ref,
141
135
  scopeKey,
@@ -148,17 +142,18 @@ export async function startWorkflowRun(ref, params = {}, options) {
148
142
  agentHarness,
149
143
  agentSessionId,
150
144
  checkinArmedAt: now,
151
- });
152
- repo.insertSteps(frozenStepRows(plan).map((step) => ({
145
+ },
146
+ steps: frozenStepRows(plan).map((step) => ({
153
147
  runId,
154
148
  stepId: step.stepId,
155
149
  stepTitle: step.stepTitle,
156
150
  instructions: step.instructions,
157
151
  completionJson: step.completionJson,
158
152
  sequenceIndex: step.sequenceIndex,
159
- })));
160
- // Same transaction as the insert: a run row never exists without its frozen plan.
161
- repo.setRunPlan(runId, planJson, planHash, WORKFLOW_IR_VERSION);
153
+ })),
154
+ planJson,
155
+ planHash,
156
+ revalidateSources: () => frozen.sourceCollector.revalidate(),
162
157
  });
163
158
  const result = await getWorkflowStatus(runId);
164
159
  // #13: params are declared non-secret (they are copied verbatim into every
@@ -174,16 +169,6 @@ export async function startWorkflowRun(ref, params = {}, options) {
174
169
  // re-announces a decision it did not make.
175
170
  if (frozen.engineAnnouncement)
176
171
  result.warnings = [...(result.warnings ?? []), frozen.engineAnnouncement];
177
- // 07 P1-B: emit only the run id + status — NOT the raw workflowTitle (which
178
- // comes verbatim from the workflow asset's frontmatter and is therefore
179
- // attacker-influenceable). Keeping raw titles out of the events stream
180
- // shrinks the injectable footprint for any consumer that re-surfaces events
181
- // into agent context.
182
- appendEvent({
183
- eventType: "workflow_started",
184
- ref: asset.ref,
185
- metadata: { runId: result.run.id, status: result.run.status },
186
- });
187
172
  return result;
188
173
  });
189
174
  }
@@ -201,9 +186,7 @@ export async function getWorkflowStatus(runId, opts) {
201
186
  // injected for deterministic tests) so a unit left `running` by a process
202
187
  // that died surfaces as stale here, not just as raw `running`.
203
188
  const staleById = new Map(evaluateStaleUnits(rows, opts.now ?? Date.now()).map((u) => [u.unitId, u]));
204
- const classified = classifyWorkflowRunPlan(run);
205
- const engines = classified.support === "supported" ? classified.plan.execution?.engines : undefined;
206
- detail.units = rows.map((row) => toUnitDiagnostic(row, staleById.get(row.unit_id), row.engine ? engines?.[row.engine] : undefined));
189
+ detail.units = rows.map((row) => toUnitDiagnostic(row, staleById.get(row.unit_id)));
207
190
  }
208
191
  return detail;
209
192
  });
@@ -296,9 +279,9 @@ function projectNextResult(run, steps) {
296
279
  export async function resumeWorkflowRun(runId) {
297
280
  return withWorkflowRunsRepo((repo) => {
298
281
  const run = readWorkflowRun(repo, runId);
299
- const plan = requireExecutableWorkflowPlan(run);
282
+ const storedPlan = requireExecutableWorkflowPlan(run);
300
283
  const steps = readWorkflowRunSteps(repo, run.id);
301
- assertWorkflowSpineMatchesPlan(plan, run, steps);
284
+ assertWorkflowSpineMatchesPlan(storedPlan, run, steps);
302
285
  if (run.status === "completed") {
303
286
  throw new UsageError(`Workflow run ${run.id} is already completed and cannot be resumed.`);
304
287
  }
@@ -473,9 +456,9 @@ export async function completeWorkflowStep(input) {
473
456
  // the write transaction — a slow/hung LLM must never hold a db write lock.
474
457
  const preflight = await withWorkflowRunsRepo((repo) => {
475
458
  const run = readWorkflowRun(repo, input.runId);
476
- const plan = requireExecutableWorkflowPlan(run);
459
+ const storedPlan = requireExecutableWorkflowPlan(run);
477
460
  const steps = readWorkflowRunSteps(repo, run.id);
478
- assertWorkflowSpineMatchesPlan(plan, run, steps);
461
+ assertWorkflowSpineMatchesPlan(storedPlan, run, steps);
479
462
  if (run.status !== "active") {
480
463
  throw new UsageError(`Workflow run ${run.id} is ${run.status} and cannot be updated.`);
481
464
  }
@@ -490,10 +473,10 @@ export async function completeWorkflowStep(input) {
490
473
  if (run.current_step_id !== existing.step_id) {
491
474
  throw new UsageError(`Step "${input.stepId}" is not the current step for workflow run ${run.id}. Complete "${run.current_step_id}" first.`);
492
475
  }
493
- const stepPlan = plan.steps.find((step) => step.stepId === input.stepId);
476
+ const stepPlan = storedPlan.steps.find((step) => step.stepId === input.stepId);
494
477
  if (!stepPlan)
495
478
  throw new NotFoundError(`Step "${input.stepId}" was not found in workflow run ${run.id}.`);
496
- return { existing, plan, stepPlan };
479
+ return { existing, plan: storedPlan, stepPlan };
497
480
  });
498
481
  const summary = input.summary?.trim();
499
482
  // #506: completing a step requires a summary of the work done.
@@ -510,7 +493,7 @@ export async function completeWorkflowStep(input) {
510
493
  ? // Manual completion journals no gate row, so there is no `<stepId>.gate:l<loop>`
511
494
  // identity to agree with — but the dispatch still names the REAL run and
512
495
  // step (frozen-judge falls back to the gate node id for the unit id).
513
- frozenSummaryJudge(preflight.plan, preflight.stepPlan.gate.judge, input.signal, undefined, {
496
+ frozenSummaryJudge(preflight.stepPlan.gate.frozenJudge, input.signal, undefined, {
514
497
  runId: input.runId,
515
498
  stepId: input.stepId,
516
499
  })
@@ -750,7 +733,8 @@ function toWorkflowRunSummary(run) {
750
733
  planIrVersion: plan.irVersion,
751
734
  executionSupport: plan.support,
752
735
  // Surface the engine lease (holder id + expiry — never workflow-authored
753
- // content) so `workflow run`/`status` show who is driving the run.
736
+ // content) so `workflow run`/`status` show which native execution
737
+ // invocation currently holds the run lease.
754
738
  ...(run.engine_lease_holder && run.engine_lease_until
755
739
  ? { engineLease: { holder: run.engine_lease_holder, until: run.engine_lease_until } }
756
740
  : {}),