akm-cli 0.9.0-rc.1 → 0.9.0-rc.13

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 (587) hide show
  1. package/CHANGELOG.md +1190 -52
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -0,0 +1,131 @@
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 { UsageError } from "../../core/errors.js";
5
+ import { decodeCanonicalPlan } from "../ir/plan-hash.js";
6
+ import { WORKFLOW_IR_VERSION } from "../ir/schema.js";
7
+ /** Validate that a live run carries exactly the current frozen-plan format. */
8
+ export function classifyWorkflowRunPlan(row) {
9
+ const runId = row.id ?? "(unknown)";
10
+ if (!row.plan_json) {
11
+ return {
12
+ support: "missing-plan",
13
+ irVersion: row.plan_ir_version ?? null,
14
+ error: `Workflow run ${runId} has no frozen workflow plan.`,
15
+ };
16
+ }
17
+ if (row.plan_ir_version !== null &&
18
+ row.plan_ir_version !== undefined &&
19
+ row.plan_ir_version !== WORKFLOW_IR_VERSION) {
20
+ return {
21
+ support: "unsupported-version",
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}.`,
24
+ };
25
+ }
26
+ if (row.plan_ir_version !== WORKFLOW_IR_VERSION) {
27
+ return {
28
+ support: "corrupt-plan",
29
+ irVersion: null,
30
+ error: `Workflow run ${runId} does not declare workflow IR version ${WORKFLOW_IR_VERSION}.`,
31
+ };
32
+ }
33
+ try {
34
+ return {
35
+ support: "supported",
36
+ irVersion: WORKFLOW_IR_VERSION,
37
+ plan: decodeCanonicalPlan(runId, row.plan_json, row.plan_hash),
38
+ };
39
+ }
40
+ catch (cause) {
41
+ return {
42
+ support: "corrupt-plan",
43
+ irVersion: WORKFLOW_IR_VERSION,
44
+ error: cause instanceof Error ? cause.message : String(cause),
45
+ };
46
+ }
47
+ }
48
+ /** Reject any operation that requires a valid current frozen plan. */
49
+ export function requireExecutableWorkflowPlan(row) {
50
+ const classified = classifyWorkflowRunPlan(row);
51
+ if (classified.support === "supported")
52
+ return classified.plan;
53
+ throw new UsageError(classified.error, "INVALID_JSON_ARGUMENT");
54
+ }
55
+ /** Project persisted spine rows from the decoded plan, never from the mutable source asset. */
56
+ export function frozenStepRows(plan) {
57
+ return plan.steps.map((step) => ({
58
+ stepId: step.stepId,
59
+ stepTitle: step.title,
60
+ instructions: step.root
61
+ ? step.root.kind === "map"
62
+ ? step.root.template.instructions
63
+ : step.root.instructions
64
+ : routeInstructions(step.route),
65
+ completionJson: step.gate.criteria.length > 0 ? JSON.stringify(step.gate.criteria) : null,
66
+ sequenceIndex: step.sequenceIndex,
67
+ }));
68
+ }
69
+ /** Verify the durable spine still agrees with the decoded/hash-verified plan before any mutation. */
70
+ export function assertWorkflowSpineMatchesPlan(plan, run, rows) {
71
+ const expected = frozenStepRows(plan);
72
+ if (rows.length !== expected.length)
73
+ corruptSpine(run.id, "step count differs from the frozen plan");
74
+ for (let index = 0; index < expected.length; index++) {
75
+ const actual = rows[index];
76
+ const planned = expected[index];
77
+ // The length check above (corruptSpine returns `never`) guarantees both are
78
+ // present; the guard narrows them and preserves the "missing row" message.
79
+ if (!actual || !planned) {
80
+ corruptSpine(run.id, `step row ${index} differs from the frozen plan (missing row)`);
81
+ }
82
+ if (actual.step_id !== planned.stepId ||
83
+ actual.step_title !== planned.stepTitle ||
84
+ actual.instructions !== planned.instructions ||
85
+ actual.completion_json !== planned.completionJson ||
86
+ actual.sequence_index !== planned.sequenceIndex) {
87
+ const fields = [
88
+ actual.step_id !== planned.stepId ? "step_id" : "",
89
+ actual.step_title !== planned.stepTitle ? "step_title" : "",
90
+ actual.instructions !== planned.instructions ? "instructions" : "",
91
+ actual.completion_json !== planned.completionJson ? "completion_json" : "",
92
+ actual.sequence_index !== planned.sequenceIndex ? "sequence_index" : "",
93
+ ].filter(Boolean);
94
+ corruptSpine(run.id, `step row ${index} differs from the frozen plan (${fields.join(", ")})`);
95
+ }
96
+ }
97
+ if (run.current_step_id !== null && !expected.some((step) => step.stepId === run.current_step_id))
98
+ corruptSpine(run.id, `current step ${run.current_step_id} is not in the frozen plan`);
99
+ const current = run.current_step_id ? rows.find((row) => row.step_id === run.current_step_id) : undefined;
100
+ if (run.status === "active") {
101
+ const firstPending = rows.find((row) => row.status === "pending");
102
+ if (!current || current.status !== "pending" || firstPending?.step_id !== current.step_id)
103
+ corruptSpine(run.id, "active status/current step does not match the first pending plan step");
104
+ }
105
+ else if (run.status === "blocked") {
106
+ if (!current || current.status !== "blocked")
107
+ corruptSpine(run.id, `${run.status} status does not match the current plan step`);
108
+ }
109
+ else if (run.status === "failed") {
110
+ // `workflow abandon` marks the run failed while intentionally leaving its
111
+ // current step pending so `resume` can reopen the same work.
112
+ if (!current || (current.status !== "failed" && current.status !== "pending"))
113
+ corruptSpine(run.id, `${run.status} status does not match the current plan step`);
114
+ }
115
+ else if (run.status === "completed") {
116
+ if (run.current_step_id !== null ||
117
+ rows.some((row) => row.status === "pending" || row.status === "blocked" || row.status === "failed"))
118
+ corruptSpine(run.id, "completed status disagrees with the plan spine");
119
+ }
120
+ }
121
+ function routeInstructions(route) {
122
+ const branches = Object.entries(route.when)
123
+ .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
124
+ .map(([match, stepId]) => `"${match}" -> ${stepId}`);
125
+ if (route.defaultStepId !== undefined)
126
+ branches.push(`default -> ${route.defaultStepId}`);
127
+ return `Route on ${route.input}: ${branches.join(", ")}.`;
128
+ }
129
+ function corruptSpine(runId, detail) {
130
+ throw new UsageError(`Workflow run ${runId} has a corrupt durable step spine: ${detail}. Refusing to mutate state that disagrees with its frozen plan.`, "INVALID_JSON_ARGUMENT");
131
+ }
@@ -2,26 +2,30 @@
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
  import { randomUUID } from "node:crypto";
5
- import { parseAssetRef } from "../../core/asset/asset-ref.js";
6
- import { canonicalizeWorkflowName } from "../../core/asset/asset-spec.js";
7
- import { getDefaultLlmConfig, loadConfig } from "../../core/config/config.js";
5
+ import { parseBundleRef } from "../../core/asset/asset-ref.js";
6
+ import { loadConfig } from "../../core/config/config.js";
8
7
  import { NotFoundError, UsageError } from "../../core/errors.js";
9
8
  import { appendEvent } from "../../core/events.js";
10
9
  import { warn } from "../../core/warn.js";
10
+ import { insertEventOnce } from "../../storage/repositories/events-repository.js";
11
11
  import { withWorkflowRunsRepo, } from "../../storage/repositories/workflow-runs-repository.js";
12
12
  import { getCurrentWorkflowScopeKey } from "../authoring/scope-key.js";
13
+ import { frozenSummaryJudge } from "../exec/frozen-judge.js";
13
14
  import { detectSecretShapedParams } from "../exec/param-secrets.js";
14
- import { collectProgramWarnings } from "../ir/compile.js";
15
+ import { collectWorkflowWarnings } from "../ir/compile.js";
16
+ import { compileResolveFreezeWorkflow } from "../ir/freeze.js";
15
17
  import { validateWorkflowParams } from "../ir/params.js";
16
18
  import { canonicalPlanJson, computePlanHash } from "../ir/plan-hash.js";
19
+ import { decodeWorkflowPlanV3, WORKFLOW_IR_VERSION } from "../ir/schema.js";
17
20
  import { validateStepSummary } from "../validate-summary.js";
18
21
  import { resolveAgentIdentity } from "./agent-identity.js";
19
22
  import { evaluateCheckin } from "./checkin.js";
23
+ import { assertWorkflowSpineMatchesPlan, classifyWorkflowRunPlan, frozenStepRows, requireExecutableWorkflowPlan, } from "./plan-classifier.js";
20
24
  import { evaluateStaleUnits } from "./unit-checkin.js";
21
- import { compileWorkflowAssetPlan, loadWorkflowAsset, resolveWorkflowEntryId } from "./workflow-asset-loader.js";
25
+ import { canonicalizeWorkflowRefInput, loadWorkflowAsset, resolveWorkflowEntryId } from "./workflow-asset-loader.js";
22
26
  /** Clip bound for a unit's `result_json` on the `--units` diagnostic surface. */
23
27
  const UNIT_DIAGNOSTIC_CLIP = 2000;
24
- function toUnitDiagnostic(row, stale) {
28
+ function toUnitDiagnostic(row, stale, plannedEngine) {
25
29
  let diagnostic = null;
26
30
  if (row.result_json !== null) {
27
31
  // `result_json` is a JSON-encoded value: a bare JSON string for a free-text
@@ -55,6 +59,9 @@ function toUnitDiagnostic(row, stale) {
55
59
  staleIdleMs: stale ? (Number.isFinite(stale.idleMs) ? stale.idleMs : null) : null,
56
60
  claimHolder: row.claim_holder,
57
61
  claimExpiresAt: row.claim_expires_at,
62
+ engine: row.engine ?? null,
63
+ runtimeKind: row.engine && (row.runner === "llm" || row.runner === "agent" || row.runner === "sdk") ? row.runner : null,
64
+ platform: plannedEngine?.kind === "agent" ? plannedEngine.platform : null,
58
65
  };
59
66
  }
60
67
  export async function startWorkflowRun(ref, params = {}, options) {
@@ -63,15 +70,12 @@ export async function startWorkflowRun(ref, params = {}, options) {
63
70
  // persist it on the run row in the same transaction as the insert. Every
64
71
  // later invocation executes this snapshot — the asset file is never re-read
65
72
  // for an in-flight run; re-planning is an explicit new run.
66
- const plan = compileWorkflowAssetPlan(asset);
67
- // Non-fatal WARNINGS (redesign addendum): a YAML program's untyped-step and
68
- // undeclared-param advisories surface as `warn()` lines at start (stderr,
69
- // consistent with the repo's other author-facing warnings) without blocking
70
- // the run. Markdown workflows carry no `program` and warn about nothing.
71
- if (asset.program) {
72
- for (const w of collectProgramWarnings(asset.program)) {
73
- warn(`workflow start: ${asset.path}:${w.line} — ${w.message}`);
74
- }
73
+ const plan = decodeWorkflowPlanV3(compileResolveFreezeWorkflow(asset, loadConfig()).plan);
74
+ // Non-fatal WARNINGS: untyped-step and undeclared-param advisories surface
75
+ // as `warn()` lines at start (stderr, consistent with the repo's other
76
+ // author-facing warnings) without blocking the run.
77
+ for (const w of collectWorkflowWarnings(asset.document)) {
78
+ warn(`workflow start: ${asset.path}:${w.line} — ${w.message}`);
75
79
  }
76
80
  // Reviewer #12: validate supplied `--params` against the frozen param
77
81
  // schemas BEFORE creating the run, so a type-mismatched param (e.g. a string
@@ -85,12 +89,13 @@ export async function startWorkflowRun(ref, params = {}, options) {
85
89
  }
86
90
  const planJson = canonicalPlanJson(plan);
87
91
  const planHash = computePlanHash(plan);
92
+ const workflowRefs = await workflowRunRefSet(asset.ref, ref);
88
93
  return withWorkflowRunsRepo(async (repo) => {
89
94
  const now = new Date().toISOString();
90
95
  const runId = randomUUID();
91
96
  const scopeKey = getCurrentWorkflowScopeKey();
92
- const currentStepId = asset.steps[0]?.id ?? null;
93
- const workflowEntryId = resolveWorkflowEntryId(asset.sourcePath, asset.ref);
97
+ const currentStepId = plan.steps[0]?.stepId ?? null;
98
+ const workflowEntryId = resolveWorkflowEntryId(asset.sourcePath, asset.ref, asset.adapterId);
94
99
  // Capture the agent harness + session driving this run. Explicit options
95
100
  // win; otherwise fall back to best-effort environment detection. This is
96
101
  // identity-only — no background thread or timer is started here.
@@ -101,19 +106,20 @@ export async function startWorkflowRun(ref, params = {}, options) {
101
106
  // (workflow_ref, scope_key) pair, refuse to create a parallel run unless
102
107
  // `force: true` is set. Previously every call inserted unconditionally,
103
108
  // so two terminals running `akm workflow start <ref>` left two runs
104
- // racing; `akm workflow next` then non-deterministically picked one.
105
- if (!options?.force) {
106
- const existing = repo.findActiveRunForScope(asset.ref, scopeKey);
107
- if (existing) {
108
- throw new UsageError(`Workflow ${asset.ref} already has an active run in this scope (id=${existing.id}, step=${existing.current_step_id ?? "—"}). ` +
109
- `Use 'akm workflow next ${asset.ref}' to resume it, 'akm workflow abandon ${existing.id}' to give up on it, or pass --force to start a parallel run.`, "RESOURCE_ALREADY_EXISTS");
110
- }
111
- }
109
+ // racing; `akm workflow next` then non-deterministically picked one. The
110
+ // active-alias query and all inserts now share this immediate transaction.
112
111
  // #506: arm a file-signal check-in (a timestamp, NOT a background thread —
113
- // see docs/technical/workflow-agent-checkin-adr.md) so a stalled run can be
112
+ // per the workflow-agent check-in ADR) so a stalled run can be
114
113
  // re-targeted with a `continue` directive. The agent harness + session id
115
114
  // are already resolved above (agentHarness/agentSessionId, from #501).
116
- repo.transaction(() => {
115
+ repo.immediateTransaction(() => {
116
+ if (!options?.force) {
117
+ const existing = repo.findActiveRunForScope(workflowRefs, scopeKey);
118
+ if (existing) {
119
+ throw new UsageError(`Workflow ${asset.ref} already has an active run in this scope (id=${existing.id}, step=${existing.current_step_id ?? "—"}). ` +
120
+ `Use 'akm workflow next ${asset.ref}' to resume it, 'akm workflow abandon ${existing.id}' to give up on it, or pass --force to start a parallel run.`, "RESOURCE_ALREADY_EXISTS");
121
+ }
122
+ }
117
123
  repo.insertRun({
118
124
  id: runId,
119
125
  workflowRef: asset.ref,
@@ -128,17 +134,16 @@ export async function startWorkflowRun(ref, params = {}, options) {
128
134
  agentSessionId,
129
135
  checkinArmedAt: now,
130
136
  });
131
- repo.insertSteps(asset.steps.map((step) => ({
137
+ repo.insertSteps(frozenStepRows(plan).map((step) => ({
132
138
  runId,
133
- stepId: step.id,
134
- stepTitle: step.title,
139
+ stepId: step.stepId,
140
+ stepTitle: step.stepTitle,
135
141
  instructions: step.instructions,
136
- completionJson: step.completionCriteria ? JSON.stringify(step.completionCriteria) : null,
137
- sequenceIndex: step.sequenceIndex ?? 0,
142
+ completionJson: step.completionJson,
143
+ sequenceIndex: step.sequenceIndex,
138
144
  })));
139
- // Same transaction as the insert: a run row never exists without its
140
- // frozen plan (rows with NULL plan_json are pre-006 legacy runs).
141
- repo.setRunPlan(runId, planJson, planHash);
145
+ // Same transaction as the insert: a run row never exists without its frozen plan.
146
+ repo.setRunPlan(runId, planJson, planHash, WORKFLOW_IR_VERSION);
142
147
  });
143
148
  const result = await getWorkflowStatus(runId);
144
149
  // #13: params are declared non-secret (they are copied verbatim into every
@@ -156,7 +161,7 @@ export async function startWorkflowRun(ref, params = {}, options) {
156
161
  // into agent context.
157
162
  appendEvent({
158
163
  eventType: "workflow_started",
159
- ref: ref,
164
+ ref: asset.ref,
160
165
  metadata: { runId: result.run.id, status: result.run.status },
161
166
  });
162
167
  return result;
@@ -176,7 +181,9 @@ export async function getWorkflowStatus(runId, opts) {
176
181
  // uses (`now` injected for deterministic tests) so a dead driver's claimed
177
182
  // `running` unit surfaces as stale here too, not just as raw `running`.
178
183
  const staleById = new Map(evaluateStaleUnits(rows, opts.now ?? Date.now()).map((u) => [u.unitId, u]));
179
- detail.units = rows.map((row) => toUnitDiagnostic(row, staleById.get(row.unit_id)));
184
+ const classified = classifyWorkflowRunPlan(run);
185
+ const engines = classified.support === "supported" ? classified.plan.execution?.engines : undefined;
186
+ detail.units = rows.map((row) => toUnitDiagnostic(row, staleById.get(row.unit_id), row.engine ? engines?.[row.engine] : undefined));
180
187
  }
181
188
  return detail;
182
189
  });
@@ -185,28 +192,50 @@ export async function hasWorkflowRun(runId) {
185
192
  return withWorkflowRunsRepo((repo) => repo.hasRun(runId));
186
193
  }
187
194
  export async function listWorkflowRuns(input) {
188
- return withWorkflowRunsRepo((repo) => {
189
- const scopeKey = getCurrentWorkflowScopeKey();
190
- let workflowRef;
191
- if (input?.workflowRef) {
192
- const parsed = parseAssetRef(input.workflowRef);
193
- if (parsed.type !== "workflow") {
194
- throw new UsageError(`Expected a workflow ref (workflow:<name>), got "${input.workflowRef}".`);
195
- }
196
- workflowRef = `${parsed.origin ? `${parsed.origin}//` : ""}workflow:${canonicalizeWorkflowName(parsed.name)}`;
195
+ const scopeKey = getCurrentWorkflowScopeKey();
196
+ const activeOnly = input?.activeOnly === true;
197
+ if (input?.workflowRef === undefined) {
198
+ return withWorkflowRunsRepo((repo) => ({
199
+ runs: repo.listRuns({ scopeKey, ...(activeOnly ? { activeOnly: true } : {}) }).map(toWorkflowRunSummary),
200
+ }));
201
+ }
202
+ const exactRef = input.workflowRef.trim();
203
+ if (!exactRef) {
204
+ throw new UsageError("Workflow ref filter cannot be empty.", "INVALID_FLAG_VALUE");
205
+ }
206
+ const parsedExactRef = parseBundleRef(exactRef);
207
+ if (parsedExactRef.fragment !== undefined) {
208
+ throw new UsageError("Workflow ref filters do not accept fragments.", "INVALID_FLAG_VALUE");
209
+ }
210
+ let workflowRefs = [exactRef];
211
+ try {
212
+ const canonicalRef = await canonicalizeWorkflowSpecifier(exactRef);
213
+ workflowRefs = await workflowRunRefSet(canonicalRef, exactRef);
214
+ }
215
+ catch (error) {
216
+ if (parsedExactRef.bundle !== undefined) {
217
+ const exactRows = await withWorkflowRunsRepo((repo) => repo.listRuns({ scopeKey, workflowRef: exactRef }));
218
+ if (exactRows.length === 0)
219
+ throw error;
220
+ return {
221
+ runs: exactRows.filter((row) => !activeOnly || row.status === "active").map(toWorkflowRunSummary),
222
+ };
197
223
  }
198
- const rows = repo.listRuns({
199
- scopeKey,
200
- ...(workflowRef ? { workflowRef } : {}),
201
- ...(input?.activeOnly ? { activeOnly: true } : {}),
202
- });
203
- return { runs: rows.map(toWorkflowRunSummary) };
204
- });
224
+ if (!(error instanceof NotFoundError))
225
+ throw error;
226
+ }
227
+ return withWorkflowRunsRepo((repo) => ({
228
+ runs: repo
229
+ .listRuns({ scopeKey, workflowRefs, ...(activeOnly ? { activeOnly: true } : {}) })
230
+ .map(toWorkflowRunSummary),
231
+ }));
205
232
  }
206
233
  export async function getNextWorkflowStep(specifier, params) {
207
234
  return withWorkflowRunsRepo(async (repo) => {
208
235
  const { run, autoStarted } = await resolveRunSpecifier(repo, specifier, params);
209
236
  const steps = readWorkflowRunSteps(repo, run.id);
237
+ const plan = requireExecutableWorkflowPlan(run);
238
+ assertWorkflowSpineMatchesPlan(plan, run, steps);
210
239
  return { ...projectNextResult(run, steps), ...(autoStarted ? { autoStarted: true } : {}) };
211
240
  });
212
241
  }
@@ -255,6 +284,8 @@ export async function snapshotRunForDriver(runId) {
255
284
  return withWorkflowRunsRepo((repo) => repo.transaction(() => {
256
285
  const run = readWorkflowRun(repo, runId);
257
286
  const steps = readWorkflowRunSteps(repo, run.id);
287
+ const plan = requireExecutableWorkflowPlan(run);
288
+ assertWorkflowSpineMatchesPlan(plan, run, steps);
258
289
  const units = repo.getUnitsForRun(run.id);
259
290
  return { next: projectNextResult(run, steps), run, units };
260
291
  }));
@@ -262,11 +293,13 @@ export async function snapshotRunForDriver(runId) {
262
293
  export async function resumeWorkflowRun(runId) {
263
294
  return withWorkflowRunsRepo((repo) => {
264
295
  const run = readWorkflowRun(repo, runId);
296
+ const plan = requireExecutableWorkflowPlan(run);
297
+ const steps = readWorkflowRunSteps(repo, run.id);
298
+ assertWorkflowSpineMatchesPlan(plan, run, steps);
265
299
  if (run.status === "completed") {
266
300
  throw new UsageError(`Workflow run ${run.id} is already completed and cannot be resumed.`);
267
301
  }
268
302
  if (run.status === "active") {
269
- const steps = readWorkflowRunSteps(repo, run.id);
270
303
  return buildWorkflowRunDetail(run, steps);
271
304
  }
272
305
  // blocked or failed → flip back to active and re-open the current step so
@@ -279,8 +312,8 @@ export async function resumeWorkflowRun(runId) {
279
312
  repo.markRunActive(run.id, now);
280
313
  });
281
314
  const updated = { ...run, status: "active", updated_at: now };
282
- const steps = readWorkflowRunSteps(repo, run.id);
283
- return buildWorkflowRunDetail(updated, steps);
315
+ const refreshedSteps = readWorkflowRunSteps(repo, run.id);
316
+ return buildWorkflowRunDetail(updated, refreshedSteps);
284
317
  });
285
318
  }
286
319
  /**
@@ -291,18 +324,24 @@ export async function resumeWorkflowRun(runId) {
291
324
  */
292
325
  export async function abandonWorkflowRun(runId) {
293
326
  return withWorkflowRunsRepo((repo) => {
294
- const run = readWorkflowRun(repo, runId);
295
- if (run.status === "completed" || run.status === "failed") {
296
- throw new UsageError(`Workflow run ${run.id} is already ${run.status}.`);
297
- }
298
327
  const now = new Date().toISOString();
299
- repo.updateRunState({
300
- status: "failed",
301
- currentStepId: run.current_step_id,
302
- updatedAt: now,
303
- completedAt: now,
304
- checkinArmedAt: now,
305
- runId: run.id,
328
+ const run = repo.immediateTransaction((db) => {
329
+ const current = readWorkflowRun(repo, runId);
330
+ if (current.status === "completed" || current.status === "failed") {
331
+ throw new UsageError(`Workflow run ${current.id} is already ${current.status}.`);
332
+ }
333
+ if (!repo.markRunAbandoned(current.id, now)) {
334
+ throw new UsageError(`Workflow run ${current.id} is ${current.status} and cannot be abandoned.`);
335
+ }
336
+ insertEventOnce(db, {
337
+ eventType: "workflow_abandoned",
338
+ ts: now,
339
+ ref: current.workflow_ref,
340
+ metadata: { runId: current.id },
341
+ idempotencyKey: current.id,
342
+ idempotencyMetadataKey: "runId",
343
+ });
344
+ return current;
306
345
  });
307
346
  const updated = {
308
347
  ...run,
@@ -313,9 +352,6 @@ export async function abandonWorkflowRun(runId) {
313
352
  };
314
353
  const steps = readWorkflowRunSteps(repo, run.id);
315
354
  const detail = buildWorkflowRunDetail(updated, steps);
316
- // Same injectable-footprint rule as workflow_started (07 P1-B): ids and
317
- // status only, never the frontmatter-derived title.
318
- appendEvent({ eventType: "workflow_abandoned", ref: run.workflow_ref, metadata: { runId: run.id } });
319
355
  return detail;
320
356
  });
321
357
  }
@@ -324,6 +360,9 @@ export async function completeWorkflowStep(input) {
324
360
  // the write transaction — a slow/hung LLM must never hold a db write lock.
325
361
  const preflight = await withWorkflowRunsRepo((repo) => {
326
362
  const run = readWorkflowRun(repo, input.runId);
363
+ const plan = requireExecutableWorkflowPlan(run);
364
+ const steps = readWorkflowRunSteps(repo, run.id);
365
+ assertWorkflowSpineMatchesPlan(plan, run, steps);
327
366
  if (run.status !== "active") {
328
367
  throw new UsageError(`Workflow run ${run.id} is ${run.status} and cannot be updated.`);
329
368
  }
@@ -338,7 +377,10 @@ export async function completeWorkflowStep(input) {
338
377
  if (run.current_step_id !== existing.step_id) {
339
378
  throw new UsageError(`Step "${input.stepId}" is not the current step for workflow run ${run.id}. Complete "${run.current_step_id}" first.`);
340
379
  }
341
- return { existing };
380
+ const stepPlan = plan.steps.find((step) => step.stepId === input.stepId);
381
+ if (!stepPlan)
382
+ throw new NotFoundError(`Step "${input.stepId}" was not found in workflow run ${run.id}.`);
383
+ return { existing, plan, stepPlan };
342
384
  });
343
385
  const summary = input.summary?.trim();
344
386
  // #506: completing a step requires a summary of the work done.
@@ -349,9 +391,11 @@ export async function completeWorkflowStep(input) {
349
391
  // completionCriteria via the configured LLM. Fail-open when no criteria or no
350
392
  // judge. Only a well-formed `complete: false` blocks completion.
351
393
  if (input.status === "completed" && summary) {
352
- const criteria = parseJsonArray(preflight.existing.completion_json) ?? [];
353
- const judge = input.summaryJudge === undefined ? buildDefaultSummaryJudge() : input.summaryJudge;
354
- const verdict = await validateStepSummary({ stepTitle: preflight.existing.step_title, completionCriteria: criteria, summary }, judge ?? undefined, { required: input.requireGate === true });
394
+ const criteria = preflight.stepPlan.gate.criteria;
395
+ const judge = input.summaryJudge === undefined
396
+ ? frozenSummaryJudge(preflight.plan, preflight.stepPlan.gate.judge)
397
+ : input.summaryJudge;
398
+ const verdict = await validateStepSummary({ stepTitle: preflight.stepPlan.title, completionCriteria: criteria, summary }, judge ?? undefined);
355
399
  if (!verdict.complete) {
356
400
  // Re-arm the check-in so a subsequent stall is still nudged, but leave the
357
401
  // step pending and return corrective feedback instead of completing.
@@ -364,9 +408,6 @@ export async function completeWorkflowStep(input) {
364
408
  stepId: input.stepId,
365
409
  missing: verdict.missing,
366
410
  feedback: verdict.feedback ?? "The summary does not satisfy the step's completion criteria.",
367
- // A REQUIRED gate that could not be judged (finding A): the caller BLOCKS
368
- // rather than treating this as a normal, retryable gate rejection.
369
- ...(verdict.errored ? { errored: true } : {}),
370
411
  };
371
412
  }
372
413
  }
@@ -375,6 +416,9 @@ export async function completeWorkflowStep(input) {
375
416
  let refreshedSteps = [];
376
417
  repo.transaction(() => {
377
418
  const run = readWorkflowRun(repo, input.runId);
419
+ const plan = requireExecutableWorkflowPlan(run);
420
+ const spine = readWorkflowRunSteps(repo, run.id);
421
+ assertWorkflowSpineMatchesPlan(plan, run, spine);
378
422
  if (run.status !== "active") {
379
423
  throw new UsageError(`Workflow run ${run.id} is ${run.status} and cannot be updated.`);
380
424
  }
@@ -449,16 +493,28 @@ async function resolveRunSpecifier(repo, specifier, params) {
449
493
  }
450
494
  return { run: explicitRun, autoStarted: false };
451
495
  }
452
- if (!specifier.includes(":")) {
453
- throw new NotFoundError(`Workflow run "${specifier}" not found.`, "WORKFLOW_NOT_FOUND");
496
+ const scopeKey = getCurrentWorkflowScopeKey();
497
+ const exactRef = specifier.trim();
498
+ const parsedExact = parseBundleRef(exactRef);
499
+ const qualifiedExact = parsedExact.bundle !== undefined && parsedExact.fragment === undefined;
500
+ const detached = qualifiedExact ? repo.getActiveRunRowForScope(exactRef, scopeKey) : undefined;
501
+ let ref;
502
+ try {
503
+ ref = await canonicalizeWorkflowSpecifier(specifier);
454
504
  }
455
- const parsed = parseAssetRef(specifier);
456
- if (parsed.type !== "workflow") {
457
- throw new UsageError(`Expected a workflow ref or workflow run id, got "${specifier}".`);
505
+ catch (error) {
506
+ if (detached) {
507
+ if (params && Object.keys(params).length > 0) {
508
+ throw new UsageError(`--params can only be set on a new run; ${specifier} already has an active run`);
509
+ }
510
+ return { run: detached, autoStarted: false };
511
+ }
512
+ if (error instanceof NotFoundError && !specifier.includes(":") && !specifier.includes("/")) {
513
+ throw new NotFoundError(`Workflow run or workflow "${specifier}" not found.`, "WORKFLOW_NOT_FOUND");
514
+ }
515
+ throw error;
458
516
  }
459
- const ref = `${parsed.origin ? `${parsed.origin}//` : ""}workflow:${canonicalizeWorkflowName(parsed.name)}`;
460
- const scopeKey = getCurrentWorkflowScopeKey();
461
- const active = repo.getActiveRunRowForScope(ref, scopeKey);
517
+ const active = repo.getActiveRunRowForScope(await workflowRunRefSet(ref, exactRef), scopeKey);
462
518
  if (active) {
463
519
  if (params && Object.keys(params).length > 0) {
464
520
  throw new UsageError(`--params can only be set on a new run; ${ref} already has an active run`);
@@ -468,6 +524,62 @@ async function resolveRunSpecifier(repo, specifier, params) {
468
524
  const started = await startWorkflowRun(ref, params ?? {});
469
525
  return { run: readWorkflowRun(repo, started.run.id), autoStarted: true };
470
526
  }
527
+ async function canonicalizeWorkflowSpecifier(specifier) {
528
+ return canonicalizeWorkflowRefInput(specifier);
529
+ }
530
+ async function workflowRunRefSet(canonicalRef, exactRef) {
531
+ const parsed = parseBundleRef(canonicalRef);
532
+ const refs = new Set([canonicalRef, exactRef.trim()]);
533
+ const exact = parseBundleRef(exactRef.trim());
534
+ if (exact.bundle === undefined) {
535
+ refs.add(parsed.conceptId);
536
+ }
537
+ else {
538
+ try {
539
+ if ((await canonicalizeWorkflowSpecifier(parsed.conceptId)) === canonicalRef)
540
+ refs.add(parsed.conceptId);
541
+ }
542
+ catch (error) {
543
+ if (!(error instanceof NotFoundError))
544
+ throw error;
545
+ }
546
+ }
547
+ return [...refs];
548
+ }
549
+ /** Resolve an existing active run without auto-starting or rebinding a detached short ref. */
550
+ export async function resolveExistingWorkflowRunId(target) {
551
+ return withWorkflowRunsRepo(async (repo) => {
552
+ const byId = repo.getRunById(target);
553
+ if (byId)
554
+ return byId.id;
555
+ const scopeKey = getCurrentWorkflowScopeKey();
556
+ const exactRef = target.trim();
557
+ if (!exactRef.includes(":") && !exactRef.includes("/")) {
558
+ throw new NotFoundError(`Workflow run or workflow "${target}" not found.`, "WORKFLOW_NOT_FOUND");
559
+ }
560
+ const parsedExact = parseBundleRef(exactRef);
561
+ const detached = parsedExact.bundle && parsedExact.fragment === undefined
562
+ ? repo.getActiveRunRowForScope(exactRef, scopeKey)
563
+ : undefined;
564
+ let canonicalRef;
565
+ try {
566
+ canonicalRef = await canonicalizeWorkflowSpecifier(exactRef);
567
+ }
568
+ catch (error) {
569
+ if (detached)
570
+ return detached.id;
571
+ if (error instanceof NotFoundError) {
572
+ throw new NotFoundError(`Workflow run or workflow "${target}" not found.`, "WORKFLOW_NOT_FOUND");
573
+ }
574
+ throw error;
575
+ }
576
+ const active = repo.getActiveRunRowForScope(await workflowRunRefSet(canonicalRef, exactRef), scopeKey);
577
+ if (!active) {
578
+ throw new NotFoundError(`No active workflow run for ${canonicalRef} in this scope.`, "WORKFLOW_NOT_FOUND");
579
+ }
580
+ return active.id;
581
+ });
582
+ }
471
583
  function readWorkflowRun(repo, runId) {
472
584
  const run = repo.getRunById(runId);
473
585
  if (!run) {
@@ -500,6 +612,7 @@ function buildWorkflowRunDetail(run, steps) {
500
612
  };
501
613
  }
502
614
  function toWorkflowRunSummary(run) {
615
+ const plan = classifyWorkflowRunPlan(run);
503
616
  return {
504
617
  id: run.id,
505
618
  workflowRef: run.workflow_ref,
@@ -514,6 +627,8 @@ function toWorkflowRunSummary(run) {
514
627
  params: parseJsonObject(run.params_json),
515
628
  agentHarness: run.agent_harness ?? null,
516
629
  agentSessionId: run.agent_session_id ?? null,
630
+ planIrVersion: plan.irVersion,
631
+ executionSupport: plan.support,
517
632
  // Surface the engine lease (holder id + expiry — never workflow-authored
518
633
  // content) so `workflow next`/`status` show who is driving the run.
519
634
  ...(run.engine_lease_holder && run.engine_lease_until
@@ -579,34 +694,6 @@ function deriveRunState(steps) {
579
694
  .at(-1);
580
695
  return { status: "completed", currentStepId: null, completedAt: completedAt ?? null };
581
696
  }
582
- /**
583
- * Build the default summary-validation judge from the configured LLM, or return
584
- * `null` when no LLM is configured (gate is then skipped — fail-open). Lazily
585
- * imports the client/config so the workflow engine has no hard LLM dependency.
586
- *
587
- * Exported for the engine loop (`exec/run-workflow.ts`), which wraps the judge
588
- * to journal engine-driven gate evaluations as unit rows (addendum R2).
589
- */
590
- export function buildDefaultSummaryJudge() {
591
- let llm;
592
- try {
593
- const config = loadConfig();
594
- llm = getDefaultLlmConfig(config);
595
- }
596
- catch {
597
- return null;
598
- }
599
- if (!llm)
600
- return null;
601
- const resolved = llm;
602
- return async ({ system, user }) => {
603
- const { chatCompletion } = await import("../../llm/client.js");
604
- return chatCompletion(resolved, [
605
- { role: "system", content: system },
606
- { role: "user", content: user },
607
- ]);
608
- };
609
- }
610
697
  function parseJsonObject(value) {
611
698
  if (!value)
612
699
  return undefined;
@@ -1,7 +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 { GATE_EVALUATION_PHASE } from "../exec/step-work.js";
4
+ import { GATE_EVALUATION_PHASE } from "./unit-phases.js";
5
5
  /**
6
6
  * Default staleness window. A unit claimed `running` whose last heartbeat (or,
7
7
  * absent any heartbeat, its first claim) is older than this is surfaced as