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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/CHANGELOG.md +756 -0
  2. package/dist/akm +94 -196
  3. package/dist/cli/shared.js +6 -2
  4. package/dist/cli.js +22 -9
  5. package/dist/commands/agent/agent-dispatch.js +1 -1
  6. package/dist/commands/command/command-execution.js +24 -62
  7. package/dist/commands/feedback-cli.js +0 -1
  8. package/dist/commands/health/accept-rate.js +2 -2
  9. package/dist/commands/health/checks.js +30 -75
  10. package/dist/commands/health/config-skew.js +38 -0
  11. package/dist/commands/health/egress.js +54 -0
  12. package/dist/commands/health/html-report.js +0 -38
  13. package/dist/commands/health/improve-metrics.js +123 -562
  14. package/dist/commands/health/plugin-staleness.js +53 -3
  15. package/dist/commands/health/renderers.js +12 -4
  16. package/dist/commands/health/report-view-model.js +11 -106
  17. package/dist/commands/health/types-improve.js +4 -19
  18. package/dist/commands/health/windows.js +64 -73
  19. package/dist/commands/health.js +122 -143
  20. package/dist/commands/improve/consolidate/chunking.js +25 -100
  21. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  22. package/dist/commands/improve/consolidate.js +538 -1075
  23. package/dist/commands/improve/content-hash.js +16 -24
  24. package/dist/commands/improve/distill/content-repair.js +18 -100
  25. package/dist/commands/improve/distill-guards.js +20 -81
  26. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  27. package/dist/commands/improve/distill.js +608 -1075
  28. package/dist/commands/improve/eligibility.js +126 -400
  29. package/dist/commands/improve/execution.js +3 -5
  30. package/dist/commands/improve/extract.js +487 -1046
  31. package/dist/commands/improve/feedback-valence.js +0 -25
  32. package/dist/commands/improve/improve-cli.js +29 -166
  33. package/dist/commands/improve/improve-result-file.js +10 -66
  34. package/dist/commands/improve/improve-strategies.js +12 -7
  35. package/dist/commands/improve/improve-usage-report.js +18 -64
  36. package/dist/commands/improve/improve.js +443 -1063
  37. package/dist/commands/improve/ledger.js +114 -0
  38. package/dist/commands/improve/locks.js +2 -8
  39. package/dist/commands/improve/loop-stages.js +459 -1172
  40. package/dist/commands/improve/memory/derived-ref.js +12 -77
  41. package/dist/commands/improve/memory/memory-belief.js +14 -118
  42. package/dist/commands/improve/memory/memory-improve.js +4 -3
  43. package/dist/commands/improve/outcome-loop.js +28 -156
  44. package/dist/commands/improve/planner.js +5 -10
  45. package/dist/commands/improve/preparation.js +851 -2339
  46. package/dist/commands/improve/proactive-maintenance.js +34 -101
  47. package/dist/commands/improve/reflect-noise.js +104 -280
  48. package/dist/commands/improve/reflect.js +621 -1367
  49. package/dist/commands/improve/salience.js +46 -232
  50. package/dist/commands/improve/session-asset.js +19 -100
  51. package/dist/commands/improve/stage.js +323 -0
  52. package/dist/commands/proposal/drain.js +251 -644
  53. package/dist/commands/proposal/proposal-cli.js +3 -18
  54. package/dist/commands/proposal/proposal-types.js +20 -41
  55. package/dist/commands/proposal/proposal.js +1 -2
  56. package/dist/commands/proposal/propose.js +134 -160
  57. package/dist/commands/proposal/repository.js +502 -1487
  58. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  59. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  60. package/dist/commands/proposal/validators/proposals.js +13 -89
  61. package/dist/commands/read/curate.js +63 -413
  62. package/dist/commands/read/search-cli.js +16 -33
  63. package/dist/commands/read/search.js +17 -23
  64. package/dist/commands/read/show.js +2 -13
  65. package/dist/commands/sources/bundle-cli.js +25 -2
  66. package/dist/commands/sources/bundle-config-ops.js +7 -0
  67. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  68. package/dist/commands/sources/info.js +2 -11
  69. package/dist/commands/sources/installed-stashes.js +197 -746
  70. package/dist/commands/sources/schema-repair.js +98 -129
  71. package/dist/commands/sources/source-add.js +62 -12
  72. package/dist/commands/sources/stash-cli.js +1 -1
  73. package/dist/commands/tasks/explain.js +10 -13
  74. package/dist/commands/tasks/tasks-cli.js +9 -8
  75. package/dist/commands/tasks/tasks.js +326 -930
  76. package/dist/commands/tasks/validate.js +42 -21
  77. package/dist/commands/workflow/plan.js +22 -29
  78. package/dist/commands/workflow-cli.js +4 -4
  79. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  80. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  81. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  82. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  83. package/dist/core/adapter/execution-source.js +17 -29
  84. package/dist/core/asset/resolve-ref.js +1 -1
  85. package/dist/core/bundle-id.js +42 -5
  86. package/dist/core/bundle-rename.js +291 -0
  87. package/dist/core/config/config-io.js +1 -2
  88. package/dist/core/config/config-schema.js +1 -33
  89. package/dist/core/config/config-walker.js +1 -1
  90. package/dist/core/config/config.js +163 -68
  91. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  92. package/dist/core/config/schema/embedding.js +20 -5
  93. package/dist/core/config/schema/engines.js +5 -0
  94. package/dist/core/config/schema/execution.js +1 -1
  95. package/dist/core/config/schema/experimental.js +1 -1
  96. package/dist/core/config/schema/improve-processes.js +21 -95
  97. package/dist/core/config/schema/improve.js +4 -42
  98. package/dist/core/config/schema/scheduler.js +12 -12
  99. package/dist/core/config/schema/search.js +6 -22
  100. package/dist/core/env-secret-ref.js +0 -1
  101. package/dist/core/errors.js +8 -9
  102. package/dist/core/file-lock.js +76 -173
  103. package/dist/core/logs-db.js +2 -2
  104. package/dist/core/paths.js +0 -27
  105. package/dist/core/redaction.js +109 -2
  106. package/dist/core/run-lock.js +2 -5
  107. package/dist/core/spawn-env.js +1 -1
  108. package/dist/core/state/migrations.js +108 -61
  109. package/dist/core/state-db-scope.js +2 -4
  110. package/dist/core/state-db.js +126 -692
  111. package/dist/core/type-presentation.js +1 -9
  112. package/dist/core/write-source.js +293 -1012
  113. package/dist/execution/input-contract.js +1 -1
  114. package/dist/execution/resolved-request.js +135 -689
  115. package/dist/execution/source.js +63 -257
  116. package/dist/execution/target-ref.js +1 -1
  117. package/dist/indexer/bundle-identity-guard.js +2 -2
  118. package/dist/indexer/db/graph-db.js +106 -46
  119. package/dist/indexer/ensure-index.js +44 -85
  120. package/dist/indexer/graph/graph-extraction.js +340 -562
  121. package/dist/indexer/graph/graph-related.js +130 -0
  122. package/dist/indexer/index-rebuild-lock.js +3 -11
  123. package/dist/indexer/index-writer-lock.js +8 -17
  124. package/dist/indexer/index-written-assets.js +139 -151
  125. package/dist/indexer/indexer.js +524 -846
  126. package/dist/indexer/materialize-embeddings.js +60 -397
  127. package/dist/indexer/passes/memory-inference.js +81 -90
  128. package/dist/indexer/passes/metadata.js +132 -200
  129. package/dist/indexer/read-preflight.js +0 -7
  130. package/dist/indexer/scan/doc-to-entry.js +1 -3
  131. package/dist/indexer/scan/drain-dir.js +1 -1
  132. package/dist/indexer/search/db-search.js +181 -590
  133. package/dist/indexer/search/fts-query.js +30 -41
  134. package/dist/indexer/search/ranking.js +28 -154
  135. package/dist/indexer/search/search-attribution.js +12 -32
  136. package/dist/indexer/search/search-fields.js +11 -15
  137. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  138. package/dist/indexer/search/search-source.js +1 -4
  139. package/dist/indexer/usage/usage-events.js +2 -7
  140. package/dist/integrations/agent/engine-fallback.js +23 -40
  141. package/dist/integrations/agent/engine-resolution.js +93 -183
  142. package/dist/integrations/agent/execution.js +507 -0
  143. package/dist/integrations/agent/model-map.js +28 -156
  144. package/dist/integrations/agent/request-lowering.js +66 -141
  145. package/dist/integrations/agent/runner-dispatch.js +143 -321
  146. package/dist/integrations/agent/runner.js +54 -14
  147. package/dist/integrations/lockfile.js +53 -101
  148. package/dist/llm/embedders/deterministic.js +2 -3
  149. package/dist/llm/embedders/profile.js +71 -0
  150. package/dist/llm/embedders/remote.js +10 -15
  151. package/dist/llm/graph-extract.js +3 -12
  152. package/dist/llm/index-passes.js +3 -5
  153. package/dist/llm/memory-infer.js +1 -2
  154. package/dist/llm/metadata-enhance.js +1 -2
  155. package/dist/llm/structured-call.js +5 -24
  156. package/dist/output/generic-render.js +23 -11
  157. package/dist/output/html-render.js +13 -10
  158. package/dist/output/render-registry.js +3 -32
  159. package/dist/output/shapes/helpers.js +2 -34
  160. package/dist/output/shapes/passthrough.js +1 -9
  161. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  162. package/dist/output/text/command-format.js +60 -23
  163. package/dist/output/text/helpers.js +1 -1
  164. package/dist/output/text/migrate.js +5 -14
  165. package/dist/output/text/proposal-format.js +1 -2
  166. package/dist/output/text/workflow-format.js +0 -32
  167. package/dist/output/text.js +2 -0
  168. package/dist/registry/factory.js +4 -19
  169. package/dist/registry/network.js +66 -220
  170. package/dist/registry/providers/index.js +0 -2
  171. package/dist/registry/providers/skills-sh.js +3 -14
  172. package/dist/registry/providers/static-index.js +24 -26
  173. package/dist/registry/resolve.js +55 -131
  174. package/dist/scripts/akm-migrate-node.js +43937 -93313
  175. package/dist/scripts/akm-migrate.js +43697 -93071
  176. package/dist/setup/registry-stash-loader.js +4 -13
  177. package/dist/setup/semantic-assets.js +3 -44
  178. package/dist/setup/setup.js +1 -1
  179. package/dist/setup/steps/tasks.js +25 -15
  180. package/dist/sources/provider-factory.js +17 -18
  181. package/dist/sources/providers/filesystem.js +2 -3
  182. package/dist/sources/providers/git-install.js +7 -1
  183. package/dist/sources/providers/git-provider.js +0 -3
  184. package/dist/sources/providers/git-stash.js +0 -17
  185. package/dist/sources/providers/npm.js +2 -4
  186. package/dist/sources/providers/provider-utils.js +5 -10
  187. package/dist/sources/providers/website.js +0 -2
  188. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  189. package/dist/sources/website-url.js +2 -2
  190. package/dist/storage/database.js +9 -35
  191. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  192. package/dist/storage/repositories/index-connection.js +34 -70
  193. package/dist/storage/repositories/index-entries-repository.js +69 -111
  194. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  195. package/dist/storage/repositories/index-entry-schema.js +83 -269
  196. package/dist/storage/repositories/index-fts-repository.js +86 -256
  197. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  198. package/dist/storage/repositories/index-meta-repository.js +6 -4
  199. package/dist/storage/repositories/index-schema.js +192 -220
  200. package/dist/storage/repositories/index-utility-repository.js +8 -29
  201. package/dist/storage/repositories/index-vec-repository.js +133 -414
  202. package/dist/storage/repositories/outcome-repository.js +2 -1
  203. package/dist/storage/repositories/proposals-repository.js +35 -0
  204. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  205. package/dist/storage/repositories/task-history-repository.js +26 -4
  206. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  207. package/dist/storage/sqlite-migrations.js +136 -0
  208. package/dist/storage/sqlite-pragmas.js +11 -9
  209. package/dist/storage/sqlite-transaction.js +170 -0
  210. package/dist/storage/state-db-integrity.js +34 -27
  211. package/dist/tasks/activation-config.js +134 -62
  212. package/dist/tasks/backends/cron.js +129 -277
  213. package/dist/tasks/backends/exec-utils.js +2 -5
  214. package/dist/tasks/backends/launchd.js +125 -745
  215. package/dist/tasks/backends/schtasks.js +101 -620
  216. package/dist/tasks/prepare/prepare-support.js +5 -15
  217. package/dist/tasks/prepare/prepare.js +0 -2
  218. package/dist/tasks/resolve-akm-bin.js +20 -79
  219. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  220. package/dist/tasks/scheduler-binding.js +18 -238
  221. package/dist/tasks/scheduler-invocation.js +52 -52
  222. package/dist/tasks/scheduler-lock.js +53 -0
  223. package/dist/tasks/scheduler-sync.js +363 -679
  224. package/dist/tasks/source/parse-task-source.js +160 -10
  225. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  226. package/dist/tasks/source/task-to-v4.js +2 -2
  227. package/dist/workflows/authoring/authoring.js +3 -12
  228. package/dist/workflows/compile.js +211 -0
  229. package/dist/workflows/concurrency-policy.js +13 -74
  230. package/dist/workflows/exec/child-invocation.js +3 -17
  231. package/dist/workflows/exec/child-workflow.js +32 -141
  232. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  233. package/dist/workflows/exec/environment.js +98 -0
  234. package/dist/workflows/exec/exec-unit.js +33 -140
  235. package/dist/workflows/exec/frozen-judge.js +7 -59
  236. package/dist/workflows/exec/native-executor.js +82 -341
  237. package/dist/workflows/exec/param-secrets.js +29 -47
  238. package/dist/workflows/exec/run-workflow.js +154 -387
  239. package/dist/workflows/exec/scheduler.js +9 -36
  240. package/dist/workflows/exec/step-work.js +127 -430
  241. package/dist/workflows/exec/unit-dispatch.js +11 -63
  242. package/dist/workflows/exec/unit-writer.js +8 -52
  243. package/dist/workflows/exec/worktree.js +39 -273
  244. package/dist/workflows/freeze/child-output-references.js +4 -15
  245. package/dist/workflows/freeze/environment.js +99 -92
  246. package/dist/workflows/freeze/freeze.js +172 -0
  247. package/dist/workflows/freeze/step-values.js +19 -21
  248. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  249. package/dist/workflows/freeze/targets/command.js +10 -33
  250. package/dist/workflows/freeze/targets/script.js +5 -12
  251. package/dist/workflows/freeze/targets/shell.js +3 -6
  252. package/dist/workflows/freeze/targets/task.js +25 -80
  253. package/dist/workflows/freeze/task-bindings.js +20 -67
  254. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  255. package/dist/workflows/ir/params.js +6 -51
  256. package/dist/workflows/ir/plan-hash.js +2 -34
  257. package/dist/workflows/parser.js +140 -43
  258. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  259. package/dist/workflows/renderer.js +36 -69
  260. package/dist/workflows/resource-limits.js +12 -120
  261. package/dist/workflows/runtime/agent-identity.js +8 -40
  262. package/dist/workflows/runtime/run-outputs.js +3 -6
  263. package/dist/workflows/runtime/run-plan.js +316 -0
  264. package/dist/workflows/runtime/runs.js +48 -200
  265. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  266. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  267. package/dist/workflows/validate-summary.js +2 -7
  268. package/docs/integration/bundling-akm.md +49 -42
  269. package/docs/migration/README.md +1 -0
  270. package/docs/migration/release-notes/0.9.17.md +41 -0
  271. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  272. package/docs/reference/cli.md +182 -125
  273. package/docs/reference/configuration.md +49 -56
  274. package/docs/reference/data-and-telemetry.md +19 -20
  275. package/docs/reference/tasks.md +86 -38
  276. package/docs/reference/workflow-schema.md +14 -18
  277. package/docs/reference/workflows.md +6 -9
  278. package/package.json +1 -1
  279. package/schemas/akm-config.json +87 -406
  280. package/dist/commands/health/advisories.js +0 -150
  281. package/dist/commands/health/metrics.js +0 -329
  282. package/dist/commands/health/surfaces.js +0 -102
  283. package/dist/commands/improve/anti-collapse.js +0 -83
  284. package/dist/commands/improve/collapse-detector.js +0 -432
  285. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  286. package/dist/commands/improve/consolidate/merge.js +0 -146
  287. package/dist/commands/improve/distill/promote-memory.js +0 -329
  288. package/dist/commands/improve/distill/quality-gate.js +0 -500
  289. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  290. package/dist/commands/improve/proposal-envelope.js +0 -31
  291. package/dist/commands/improve/run-context.js +0 -123
  292. package/dist/commands/improve/shared.js +0 -21
  293. package/dist/commands/improve/source-identity.js +0 -28
  294. package/dist/commands/improve/triage.js +0 -96
  295. package/dist/commands/proposal/drain-policies.js +0 -151
  296. package/dist/commands/sources/update-transaction.js +0 -220
  297. package/dist/core/action-contributors.js +0 -28
  298. package/dist/core/config/config-version-shim.js +0 -101
  299. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  300. package/dist/core/fs-txn.js +0 -405
  301. package/dist/core/lexical-score.js +0 -25
  302. package/dist/core/maintenance-barrier.js +0 -167
  303. package/dist/execution/executable-identity.js +0 -105
  304. package/dist/execution/guarded-source.js +0 -427
  305. package/dist/indexer/graph/graph-boost.js +0 -427
  306. package/dist/indexer/graph/graph-dedup.js +0 -95
  307. package/dist/indexer/search/name-match.js +0 -35
  308. package/dist/indexer/search/ranking-contributors.js +0 -515
  309. package/dist/indexer/walk/project-context.js +0 -192
  310. package/dist/integrations/agent/execution-cascade.js +0 -566
  311. package/dist/integrations/agent/execution-definitions.js +0 -202
  312. package/dist/integrations/agent/execution-lowering.js +0 -841
  313. package/dist/integrations/agent/execution-preparation.js +0 -98
  314. package/dist/integrations/agent/inline-execution.js +0 -74
  315. package/dist/registry/create-provider-registry.js +0 -29
  316. package/dist/registry/pinned-request-helper.js +0 -247
  317. package/dist/registry/pinned-transport.js +0 -717
  318. package/dist/sources/providers/index.js +0 -14
  319. package/dist/storage/engines/sqlite-migrations.js +0 -271
  320. package/dist/storage/repositories/canaries-repository.js +0 -107
  321. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  322. package/dist/storage/repositories/registry-cache.js +0 -113
  323. package/dist/tasks/scheduler-sync-preview.js +0 -52
  324. package/dist/workflows/freeze/resolve-steps.js +0 -86
  325. package/dist/workflows/freeze/source-freeze.js +0 -64
  326. package/dist/workflows/ir/compile.js +0 -321
  327. package/dist/workflows/ir/environment-v4.js +0 -330
  328. package/dist/workflows/ir/freeze-v4.js +0 -153
  329. package/dist/workflows/ir/schema-v4.js +0 -745
  330. package/dist/workflows/ir/schema.js +0 -354
  331. package/dist/workflows/program/schema.js +0 -78
  332. package/dist/workflows/runtime/checkin.js +0 -57
  333. package/dist/workflows/runtime/plan-classifier.js +0 -196
  334. package/dist/workflows/runtime/unit-checkin.js +0 -45
  335. package/dist/workflows/runtime/unit-phases.js +0 -20
  336. package/dist/workflows/schema.js +0 -4
  337. package/dist/workflows/source-ir/compile.js +0 -200
  338. package/dist/workflows/source-ir/program.js +0 -50
  339. package/dist/workflows/source-ir/result.js +0 -26
  340. package/dist/workflows/source-ir/schema.js +0 -786
  341. package/dist/workflows/source-ir/triggers.js +0 -79
  342. package/dist/workflows/source-ir/uses.js +0 -40
  343. package/dist/workflows/validator.js +0 -60
@@ -1,196 +0,0 @@
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 { warnOnce } from "../../core/warn.js";
6
- import { decodeCanonicalPlan } from "../ir/plan-hash.js";
7
- import { WORKFLOW_IR_V5_VERSION } from "../ir/schema-v4.js";
8
- /** Validate that a live run carries exactly the current frozen-plan format. */
9
- export function classifyWorkflowRunPlan(row) {
10
- const runId = row.id ?? "(unknown)";
11
- if (!row.plan_json) {
12
- return {
13
- support: "missing-plan",
14
- irVersion: row.plan_ir_version ?? null,
15
- error: `Workflow run ${runId} has no frozen workflow plan.`,
16
- };
17
- }
18
- if (row.plan_ir_version !== null &&
19
- row.plan_ir_version !== undefined &&
20
- row.plan_ir_version !== WORKFLOW_IR_V5_VERSION) {
21
- return {
22
- support: "unsupported-version",
23
- irVersion: row.plan_ir_version,
24
- // §3.2's exact complete-or-abandon policy string (A-N2): pre-irVersion-5
25
- // plans keep status/list/abandon working but can no longer execute. A
26
- // version ABOVE the current one (#919) is a distinct situation — never
27
- // an "upgrade" problem — so it gets its own text below rather than
28
- // being folded into the pre-5 wording.
29
- error: row.plan_ir_version < WORKFLOW_IR_V5_VERSION
30
- ? // Issue 8: leads with the remedy available to a user who has
31
- `Workflow run ${runId} was frozen as workflow plan irVersion ${row.plan_ir_version}; pre-irVersion-5 ` +
32
- `plans cannot execute after the 0.9.2 upgrade. Run 'akm workflow abandon ${runId}' and start a new ` +
33
- `run from the authored workflow to continue. 'akm workflow status' and 'akm workflow list' still ` +
34
- `work on this run.`
35
- : `Workflow run ${runId} was frozen with workflow plan irVersion ${row.plan_ir_version}, which this akm ` +
36
- `(irVersion ${WORKFLOW_IR_V5_VERSION}) does not understand; it was probably written by a newer akm. ` +
37
- `Complete it with that akm version, or run 'akm workflow abandon ${runId}' and start a new run from ` +
38
- `the authored workflow. 'akm workflow status' and 'akm workflow list' still work on this run.`,
39
- };
40
- }
41
- try {
42
- return {
43
- support: "supported",
44
- irVersion: WORKFLOW_IR_V5_VERSION,
45
- plan: decodeCanonicalPlan(runId, row.plan_json, row.plan_hash, row.plan_ir_version),
46
- };
47
- }
48
- catch (cause) {
49
- return {
50
- support: "corrupt-plan",
51
- irVersion: row.plan_ir_version ?? null,
52
- error: cause instanceof Error ? cause.message : String(cause),
53
- };
54
- }
55
- }
56
- /**
57
- * Reject any operation that requires a valid current frozen plan. A
58
- * non-current stored `plan_ir_version` (`unsupported-version`) fails closed
59
- * under `WORKFLOW_IR_VERSION_UNSUPPORTED` (A-N2) — distinct from the
60
- * `missing-plan` / `corrupt-plan` decode-corruption family, which keeps
61
- * `INVALID_JSON_ARGUMENT`.
62
- */
63
- export function requireExecutableWorkflowPlan(row) {
64
- const classified = classifyWorkflowRunPlan(row);
65
- if (classified.support === "supported")
66
- return classified.plan;
67
- if (classified.support === "unsupported-version") {
68
- throw new UsageError(classified.error, "WORKFLOW_IR_VERSION_UNSUPPORTED");
69
- }
70
- throw new UsageError(classified.error, "INVALID_JSON_ARGUMENT");
71
- }
72
- /** Project persisted spine rows from the decoded plan, never from the mutable source asset. */
73
- export function frozenStepRows(plan) {
74
- return plan.steps.map((step) => ({
75
- stepId: step.stepId,
76
- stepTitle: step.title,
77
- instructions: step.root
78
- ? step.root.kind === "map"
79
- ? step.root.template.instructions
80
- : step.root.instructions
81
- : routeInstructions(step.route),
82
- completionJson: step.gate.criteria.length > 0 ? JSON.stringify(step.gate.criteria) : null,
83
- sequenceIndex: step.sequenceIndex,
84
- }));
85
- }
86
- /**
87
- * Verify the durable spine's STEP IDENTITY still agrees with the
88
- * decoded/hash-verified plan: the same number of steps, and the same set of
89
- * step ids. A published plan's own step ids are fixed forever at freeze
90
- * time, so a mismatch here means the row set itself is wrong — genuine
91
- * corruption, not something a later akm release could have caused by
92
- * changing how a field is FORMATTED (that is
93
- * {@link reconcileWorkflowSpineWithPlan}'s concern, issue 7).
94
- */
95
- function assertSpineIdentityMatchesPlan(runId, expected, rows) {
96
- if (rows.length !== expected.length)
97
- corruptSpine(runId, "step count differs from the frozen plan");
98
- const expectedIds = new Set(expected.map((step) => step.stepId));
99
- for (const row of rows) {
100
- if (!expectedIds.has(row.step_id))
101
- corruptSpine(runId, `step "${row.step_id}" is not in the frozen plan`);
102
- }
103
- }
104
- /**
105
- * Reconcile the durable spine's PURE-DERIVATION fields (title, instructions,
106
- * completion criteria, sequence position) against the plan (issue 7).
107
- *
108
- * These are recomputed from the plan by {@link frozenStepRows} on every
109
- * read; a later akm release changing how one of them is FORMATTED from the
110
- * SAME plan data used to mark every in-flight run from the previous release
111
- * "corrupt" the moment anything (`akm workflow status`, `resume`, a step
112
- * completion) touched it. A mismatch here is warned about, once per run,
113
- * rather than blocking the caller — never step identity (row count, which
114
- * step ids exist), which stays a hard failure in
115
- * {@link assertSpineIdentityMatchesPlan} because the plan cannot have
116
- * produced a different step id for an already-frozen run.
117
- *
118
- * The durable row — not the plan — is what a driving agent actually acts
119
- * on: `getNextWorkflowStep` reads `instructions` straight off this row
120
- * (`toWorkflowRunStepState`/`projectNextResult` in `runtime/runs.ts`), and
121
- * `exec/run-workflow.ts`/`exec/step-work.ts` dispatch from that result. So
122
- * warning and proceeding with the STORED row (rather than rewriting it to
123
- * match the plan's current formatting) is the conservative choice: the
124
- * durable spine is the contract this run has been executing against since
125
- * freeze, and a newer akm formatting the same plan data differently should
126
- * not retroactively change an in-flight run's instructions out from under
127
- * it mid-execution. This module has no write path for that anyway
128
- * (`workflow_run_steps` is owned by
129
- * `storage/repositories/workflow-runs-repository.ts`) — and it should not
130
- * gain one for this purpose. Step
131
- * identity (row count, which step ids exist) is the part that would
132
- * actually desynchronize execution from the plan, which is exactly why
133
- * {@link assertSpineIdentityMatchesPlan} keeps that a hard failure.
134
- */
135
- export function reconcileWorkflowSpineWithPlan(plan, run, rows) {
136
- const expected = frozenStepRows(plan);
137
- assertSpineIdentityMatchesPlan(run.id, expected, rows);
138
- const expectedById = new Map(expected.map((step) => [step.stepId, step]));
139
- const drifted = [];
140
- for (const row of rows) {
141
- const planned = expectedById.get(row.step_id);
142
- if (!planned)
143
- continue; // unreachable after assertSpineIdentityMatchesPlan; kept defensive.
144
- if (row.step_title !== planned.stepTitle ||
145
- row.instructions !== planned.instructions ||
146
- row.completion_json !== planned.completionJson ||
147
- row.sequence_index !== planned.sequenceIndex) {
148
- drifted.push(row.step_id);
149
- }
150
- }
151
- if (drifted.length > 0) {
152
- warnOnce(`workflow-spine-drift:${run.id}`, `Workflow run ${run.id}: durable step row(s) [${drifted.join(", ")}] no longer match the frozen plan's ` +
153
- "title/instructions/completion-criteria/sequence derivation (an akm upgrade likely changed how one of " +
154
- "these is formatted from the same plan data). Continuing with the stored row(s) as-is — this run keeps " +
155
- "executing against the instructions it was frozen with, rather than having them rewritten mid-flight.");
156
- }
157
- }
158
- export function assertRunStatusMatchesSpine(run, rows) {
159
- const current = run.current_step_id ? rows.find((row) => row.step_id === run.current_step_id) : undefined;
160
- if (run.current_step_id !== null && !current)
161
- corruptSpine(run.id, `current step ${run.current_step_id} is not in the frozen plan`);
162
- if (run.status === "active") {
163
- const firstPending = rows.find((row) => row.status === "pending");
164
- if (!current || current.status !== "pending" || firstPending?.step_id !== current.step_id)
165
- corruptSpine(run.id, "active status/current step does not match the first pending plan step");
166
- }
167
- else if (run.status === "blocked") {
168
- if (!current || current.status !== "blocked")
169
- corruptSpine(run.id, `${run.status} status does not match the current plan step`);
170
- }
171
- else if (run.status === "failed") {
172
- // `workflow abandon` marks the run failed while intentionally leaving its
173
- // current step unchanged so `resume` can reopen the same work. An active
174
- // run leaves a pending step; a blocked run leaves a blocked step; and an
175
- // execution failure already carries a failed step. All three are honest
176
- // failed-run spines that `resumeWorkflowRun` normalizes back to pending.
177
- if (!current || (current.status !== "failed" && current.status !== "pending" && current.status !== "blocked"))
178
- corruptSpine(run.id, `${run.status} status does not match the current plan step`);
179
- }
180
- else if (run.status === "completed") {
181
- if (run.current_step_id !== null ||
182
- rows.some((row) => row.status === "pending" || row.status === "blocked" || row.status === "failed"))
183
- corruptSpine(run.id, "completed status disagrees with the plan spine");
184
- }
185
- }
186
- function routeInstructions(route) {
187
- const branches = Object.entries(route.when)
188
- .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
189
- .map(([match, stepId]) => `"${match}" -> ${stepId}`);
190
- if (route.defaultStepId !== undefined)
191
- branches.push(`default -> ${route.defaultStepId}`);
192
- return `Route on ${route.input}: ${branches.join(", ")}.`;
193
- }
194
- function corruptSpine(runId, detail) {
195
- 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");
196
- }
@@ -1,45 +0,0 @@
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 { GATE_EVALUATION_PHASE } from "./unit-phases.js";
5
- /**
6
- * Default staleness window. A unit claimed `running` whose last heartbeat (or,
7
- * absent any heartbeat, its first claim) is older than this is surfaced as
8
- * stale. Matches the run-level {@link ../runtime/checkin.CHECKIN_STALL_MS}.
9
- */
10
- export const UNIT_STALE_MS = 90_000;
11
- function parseIso(value) {
12
- if (!value)
13
- return null;
14
- const ms = Date.parse(value);
15
- return Number.isNaN(ms) ? null : ms;
16
- }
17
- /**
18
- * Pure stale-unit evaluator. Returns every `running` DISPATCH unit whose last
19
- * heartbeat (`last_checkin_at`, else the first-claim `started_at`) is older than
20
- * `staleMs`. Gate-evaluation rows (`phase = "gate"`) are excluded — they are
21
- * synchronous engine judge calls, never separately claimed work. A running row with
22
- * no usable timestamp at all is treated as stale (a claim we can no longer age).
23
- * Deterministic in `now` — free of timer flakiness.
24
- */
25
- export function evaluateStaleUnits(rows, now = Date.now(), staleMs = UNIT_STALE_MS) {
26
- const stale = [];
27
- for (const row of rows) {
28
- if (row.status !== "running")
29
- continue;
30
- if (row.phase === GATE_EVALUATION_PHASE)
31
- continue;
32
- const lastSeenAt = row.last_checkin_at ?? row.started_at;
33
- const lastSeen = parseIso(lastSeenAt);
34
- const idleMs = lastSeen === null ? Number.POSITIVE_INFINITY : now - lastSeen;
35
- if (idleMs < staleMs)
36
- continue;
37
- stale.push({
38
- unitId: row.unit_id,
39
- stepId: row.step_id,
40
- idleMs,
41
- lastSeenAt: lastSeenAt ?? null,
42
- });
43
- }
44
- return stale;
45
- }
@@ -1,20 +0,0 @@
1
- // This Source Code Form is subject to the terms of the Mozilla Public
2
- // License, v. 2.0. If a copy of the MPL was not distributed with this
3
- // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * Unit-row phase markers — a leaf module (imports nothing) so both the exec
6
- * modules (step-work, run-workflow) and the runtime (unit-checkin) can key on
7
- * the phase discriminator without an exec ↔ runtime import cycle.
8
- * Extracting {@link GATE_EVALUATION_PHASE} here broke the last workflows-
9
- * runtime knot (step-work → runs → unit-checkin → step-work; chunk-8 WI-8.6,
10
- * DoD 11).
11
- */
12
- /**
13
- * `phase` marker stamped on gate-evaluation unit rows. Step ids cannot contain
14
- * dots (`PROGRAM_STEP_ID_PATTERN`), so a step can never be NAMED `x.gate` and
15
- * the synthetic `<stepId>.gate` node id is collision-free against user step
16
- * ids. The phase column is nonetheless the discriminator we key on — an
17
- * explicit marker, not a `node_id` suffix match, so recovery stays robust even
18
- * if the id scheme evolves. Dispatch rows always journal `phase: null`.
19
- */
20
- export const GATE_EVALUATION_PHASE = "gate";
@@ -1,4 +0,0 @@
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
- export const WORKFLOW_SCHEMA_VERSION = 2;
@@ -1,200 +0,0 @@
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 path from "node:path";
5
- import { parseFrontmatterBlock } from "../../core/asset/frontmatter.js";
6
- import { parseWorkflow } from "../parser.js";
7
- import { projectExecCore } from "../program/schema.js";
8
- import { parseGithubWorkflowSource } from "./github-yaml.js";
9
- import { sourceFailureResult, WorkflowSourceFailure } from "./result.js";
10
- import { decodeWorkflowSourceIrV1, } from "./schema.js";
11
- import { canonicalizeWorkflowWorkingDirectory, WorkflowSourceSemanticError } from "./semantics.js";
12
- import { classifyWorkflowYamlTriggers } from "./triggers.js";
13
- import { classifyWorkflowSourceUses } from "./uses.js";
14
- export { looksLikeGithubWorkflowSource } from "./github-yaml.js";
15
- export function compileGithubWorkflowSource(source, options) {
16
- try {
17
- return {
18
- ok: true,
19
- ir: decodeWorkflowSourceIrV1(parseGithubWorkflowSource(source, {
20
- ...options,
21
- classifyUses: options.classifyUses ?? classifyWorkflowSourceUses,
22
- classifyTriggers: options.classifyTriggers ?? classifyWorkflowYamlTriggers,
23
- }), {
24
- workspaceRoot: options.workspaceRoot,
25
- }),
26
- };
27
- }
28
- catch (cause) {
29
- return sourceFailureResult(cause, options.path);
30
- }
31
- }
32
- export function compileMarkdownWorkflowSource(source, options) {
33
- const parsed = parseWorkflow(source, {
34
- path: options.path,
35
- validateExecCwd: (value) => {
36
- try {
37
- return { ok: true, value: canonicalizeWorkflowWorkingDirectory(value, options.workspaceRoot) };
38
- }
39
- catch (cause) {
40
- if (cause instanceof WorkflowSourceSemanticError) {
41
- return { ok: false, code: cause.code, message: cause.message };
42
- }
43
- return {
44
- ok: false,
45
- code: "working-directory-unverifiable",
46
- message: cause instanceof Error ? cause.message : "working-directory cannot be physically verified.",
47
- };
48
- }
49
- },
50
- });
51
- if (!parsed.ok) {
52
- return {
53
- ok: false,
54
- errors: parsed.errors.map((error) => ({
55
- code: error.code ?? "invalid-markdown-workflow",
56
- message: error.message,
57
- path: options.path,
58
- line: error.line,
59
- })),
60
- };
61
- }
62
- try {
63
- const sourceSpan = wholeSourceSpan(source, options.path);
64
- const steps = parsed.document.steps.map((step) => markdownStep(step, options.path));
65
- const ir = {
66
- sourceIrVersion: 1,
67
- name: markdownName(source, options.path),
68
- ...(parsed.document.description ? { description: parsed.document.description } : {}),
69
- ...(parsed.document.tags ? { tags: [...parsed.document.tags] } : {}),
70
- ...(parsed.document.params ? { params: jsonClone(parsed.document.params) } : {}),
71
- ...(parsed.document.outputs
72
- ? { outputs: jsonClone(parsed.document.outputs) }
73
- : {}),
74
- ...(parsed.document.defaults
75
- ? { defaults: jsonClone(parsed.document.defaults) }
76
- : {}),
77
- ...(parsed.document.budget ? { budget: jsonClone(parsed.document.budget) } : {}),
78
- ...(parsed.document.preamble ? { preamble: parsed.document.preamble } : {}),
79
- triggers: [{ kind: "workflow_dispatch", source: sourceSpan }],
80
- jobs: [
81
- {
82
- id: "contract",
83
- needs: [],
84
- steps,
85
- source: sourceSpan,
86
- },
87
- ],
88
- extensions: {
89
- "akm.dev/workflow-markdown": jsonExtension({
90
- workflowSchemaVersion: parsed.document.schemaVersion,
91
- }),
92
- },
93
- source: sourceSpan,
94
- };
95
- return {
96
- ok: true,
97
- ir: decodeWorkflowSourceIrV1(ir, { workspaceRoot: options.workspaceRoot }),
98
- };
99
- }
100
- catch (cause) {
101
- return sourceFailureResult(cause, options.path);
102
- }
103
- }
104
- /** Compile by authoritative source extension without rewriting either format. */
105
- export function compileWorkflowSource(source, options) {
106
- const extension = path.extname(options.path).toLowerCase();
107
- if (extension === ".md")
108
- return compileMarkdownWorkflowSource(source, options);
109
- if (extension === ".yml")
110
- return compileGithubWorkflowSource(source, options);
111
- return {
112
- ok: false,
113
- errors: [
114
- {
115
- code: "unsupported-workflow-extension",
116
- message: `Workflow source ${options.path} must use .md or .yml.`,
117
- path: options.path,
118
- line: 1,
119
- },
120
- ],
121
- };
122
- }
123
- function markdownStep(step, filePath) {
124
- const source = step.source ?? { path: filePath, start: 1, end: 1 };
125
- const dispatchUnit = step.map?.unit ?? step.unit;
126
- const unit = markdownUnit(dispatchUnit);
127
- const common = {
128
- id: step.id,
129
- ...(unit ? { unit } : {}),
130
- ...(step.map
131
- ? {
132
- map: {
133
- over: step.map.over,
134
- ...(step.map.concurrency !== undefined ? { concurrency: step.map.concurrency } : {}),
135
- ...(step.map.reducer !== undefined ? { reducer: step.map.reducer } : {}),
136
- },
137
- }
138
- : {}),
139
- ...(step.route ? { route: jsonClone(step.route) } : {}),
140
- ...(step.inputs ? { inputs: [...step.inputs] } : {}),
141
- ...(step.output ? { output: jsonClone(step.output) } : {}),
142
- ...(step.gate || step.gateRubric
143
- ? {
144
- gate: {
145
- ...(step.gate?.maxLoops !== undefined ? { maxLoops: step.gate.maxLoops } : {}),
146
- ...(step.gateRubric?.text.trim() ? { rubric: step.gateRubric.text } : {}),
147
- },
148
- }
149
- : {}),
150
- source,
151
- };
152
- if (step.route) {
153
- return {
154
- ...common,
155
- ...(step.instructions?.text.trim() ? { instructions: step.instructions.text } : {}),
156
- };
157
- }
158
- if (dispatchUnit?.exec) {
159
- return {
160
- ...common,
161
- exec: projectExecCore(dispatchUnit.exec),
162
- ...(step.instructions?.text.trim() ? { instructions: step.instructions.text } : {}),
163
- };
164
- }
165
- const content = step.instructions?.text ?? "";
166
- if (content.trim() === "") {
167
- throw new WorkflowSourceFailure("markdown-command-content-required", `Markdown step ${JSON.stringify(step.id)} has no executable command content.`, source);
168
- }
169
- return {
170
- ...common,
171
- uses: "akm/command",
172
- commandMode: "literal",
173
- with: { content },
174
- };
175
- }
176
- function markdownUnit(value) {
177
- if (!value)
178
- return undefined;
179
- const { exec: _exec, source: _source, ...unit } = value;
180
- return Object.keys(unit).length > 0
181
- ? jsonClone(unit)
182
- : undefined;
183
- }
184
- function markdownName(source, filePath) {
185
- const block = parseFrontmatterBlock(source);
186
- const body = block?.content ?? source;
187
- const title = body.match(/^#\s+(.+?)\s*$/m)?.[1]?.trim();
188
- if (title)
189
- return title;
190
- return path.basename(filePath, path.extname(filePath));
191
- }
192
- function wholeSourceSpan(source, filePath) {
193
- return { path: filePath, start: 1, end: Math.max(1, source.split(/\r?\n/).length) };
194
- }
195
- function jsonClone(value) {
196
- return JSON.parse(JSON.stringify(value));
197
- }
198
- function jsonExtension(value) {
199
- return JSON.parse(JSON.stringify(value));
200
- }
@@ -1,50 +0,0 @@
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 { parseBuiltinCommandAction } from "../../commands/command/builtin-action.js";
5
- import { PORTABLE_ARGUMENTS_PLACEHOLDER } from "../../commands/command/portable-template.js";
6
- /** Lower one adapter-neutral source-IR step into the shared execution unit. */
7
- export function sourceStepProgramUnit(source) {
8
- const unit = {
9
- ...(source.unit ? structuredClone(source.unit) : {}),
10
- source: sourceStepRef(source),
11
- };
12
- if (source.exec)
13
- unit.exec = { ...source.exec };
14
- if (source.run !== undefined) {
15
- unit.exec = {
16
- command: workflowShellCommand(source.shell ?? "sh", source.run),
17
- ...(source.workingDirectory ? { cwd: source.workingDirectory } : {}),
18
- };
19
- }
20
- return unit;
21
- }
22
- /** Derive the instruction bytes consumed by the one workflow engine. */
23
- export function sourceStepInstructions(source) {
24
- if (source.instructions !== undefined)
25
- return source.instructions;
26
- if (source.run !== undefined)
27
- return `Run ${source.run}.`;
28
- if (source.uses === "akm/command") {
29
- const action = parseBuiltinCommandAction(source.with);
30
- if (action.kind === "stored") {
31
- return `Invoke stored command ${action.ref}${action.arguments === undefined ? "" : " with arguments"}.`;
32
- }
33
- if (source.commandMode === "literal")
34
- return action.content;
35
- return action.content.split(PORTABLE_ARGUMENTS_PLACEHOLDER).join(action.arguments ?? "");
36
- }
37
- if (source.uses !== undefined)
38
- return `Invoke local target ${source.uses}.`;
39
- return "";
40
- }
41
- export function workflowShellCommand(shell, content) {
42
- if (shell === "cmd")
43
- return ["cmd", "/d", "/s", "/c", content];
44
- if (shell === "pwsh" || shell === "powershell")
45
- return [shell, "-Command", content];
46
- return [shell, "-c", content];
47
- }
48
- export function sourceStepRef(source) {
49
- return { path: source.source.path, start: source.source.start, end: source.source.end };
50
- }
@@ -1,26 +0,0 @@
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
- export class WorkflowSourceFailure extends Error {
5
- error;
6
- constructor(code, message, source) {
7
- super(message);
8
- this.name = "WorkflowSourceFailure";
9
- this.error = { code, message, path: source.path, line: source.start };
10
- }
11
- }
12
- export function sourceFailureResult(cause, path) {
13
- if (cause instanceof WorkflowSourceFailure)
14
- return { ok: false, errors: [cause.error] };
15
- return {
16
- ok: false,
17
- errors: [
18
- {
19
- code: "invalid-workflow-source",
20
- message: cause instanceof Error ? cause.message : String(cause),
21
- path,
22
- line: 1,
23
- },
24
- ],
25
- };
26
- }