akm-cli 0.9.16 → 0.9.17-alpha.10

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 (403) hide show
  1. package/CHANGELOG.md +2101 -0
  2. package/STABILITY.md +11 -10
  3. package/dist/akm +124 -193
  4. package/dist/akm-migrate +38 -19
  5. package/dist/assets/hints/cli-hints-full.md +6 -7
  6. package/dist/assets/improve-strategies/catchup.json +0 -3
  7. package/dist/assets/improve-strategies/consolidate.json +0 -1
  8. package/dist/assets/improve-strategies/default.json +1 -2
  9. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
  10. package/dist/assets/improve-strategies/quick.json +1 -2
  11. package/dist/assets/improve-strategies/reflect-distill.json +1 -2
  12. package/dist/assets/improve-strategies/thorough.json +0 -3
  13. package/dist/assets/prompts/consolidate-pair.md +20 -0
  14. package/dist/assets/prompts/consolidate-system.md +4 -11
  15. package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
  17. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
  18. package/dist/assets/templates/html/health.html +3 -5
  19. package/dist/cli/retired-commands.js +1 -1
  20. package/dist/cli/shared.js +6 -2
  21. package/dist/cli/unknown-flags.js +24 -1
  22. package/dist/cli.js +68 -10
  23. package/dist/commands/agent/agent-dispatch.js +1 -1
  24. package/dist/commands/command/command-execution.js +24 -62
  25. package/dist/commands/feedback-cli.js +0 -1
  26. package/dist/commands/health/accept-rate.js +6 -0
  27. package/dist/commands/health/archive-usage.js +92 -0
  28. package/dist/commands/health/checks.js +83 -74
  29. package/dist/commands/health/config-skew.js +38 -0
  30. package/dist/commands/health/data-dir-usage.js +25 -13
  31. package/dist/commands/health/egress.js +54 -0
  32. package/dist/commands/health/html-report.js +1 -42
  33. package/dist/commands/health/improve-metrics.js +136 -591
  34. package/dist/commands/health/md-report.js +1 -6
  35. package/dist/commands/health/plugin-staleness.js +53 -3
  36. package/dist/commands/health/renderers.js +12 -4
  37. package/dist/commands/health/report-view-model.js +14 -120
  38. package/dist/commands/health/types-improve.js +4 -19
  39. package/dist/commands/health/windows.js +64 -74
  40. package/dist/commands/health.js +145 -143
  41. package/dist/commands/improve/consolidate/chunking.js +26 -117
  42. package/dist/commands/improve/consolidate/continuity-check.js +137 -0
  43. package/dist/commands/improve/consolidate/pair-pass.js +791 -0
  44. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  45. package/dist/commands/improve/consolidate.js +589 -1127
  46. package/dist/commands/improve/content-hash.js +16 -24
  47. package/dist/commands/improve/distill/content-repair.js +18 -100
  48. package/dist/commands/improve/distill-guards.js +20 -81
  49. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  50. package/dist/commands/improve/distill.js +608 -1041
  51. package/dist/commands/improve/eligibility.js +126 -390
  52. package/dist/commands/improve/execution.js +8 -10
  53. package/dist/commands/improve/extract-prompt.js +1 -2
  54. package/dist/commands/improve/extract.js +487 -1046
  55. package/dist/commands/improve/feedback-valence.js +0 -25
  56. package/dist/commands/improve/improve-cli.js +75 -169
  57. package/dist/commands/improve/improve-result-file.js +10 -66
  58. package/dist/commands/improve/improve-strategies.js +52 -4
  59. package/dist/commands/improve/improve-usage-report.js +18 -64
  60. package/dist/commands/improve/improve.js +480 -1074
  61. package/dist/commands/improve/ledger.js +119 -0
  62. package/dist/commands/improve/locks.js +2 -8
  63. package/dist/commands/improve/loop-stages.js +415 -1073
  64. package/dist/commands/improve/memory/derived-ref.js +12 -77
  65. package/dist/commands/improve/memory/memory-belief.js +16 -118
  66. package/dist/commands/improve/memory/memory-improve.js +266 -14
  67. package/dist/commands/improve/outcome-loop.js +28 -156
  68. package/dist/commands/improve/planner.js +5 -15
  69. package/dist/commands/improve/preparation.js +779 -2319
  70. package/dist/commands/improve/proactive-maintenance.js +34 -101
  71. package/dist/commands/improve/reflect-noise.js +104 -280
  72. package/dist/commands/improve/reflect.js +642 -1353
  73. package/dist/commands/improve/retrieval-gate.js +127 -0
  74. package/dist/commands/improve/retrieval-scope.js +92 -0
  75. package/dist/commands/improve/salience.js +41 -240
  76. package/dist/commands/improve/session-asset.js +19 -100
  77. package/dist/commands/improve/stage.js +322 -0
  78. package/dist/commands/lint/base-linter.js +37 -15
  79. package/dist/commands/proposal/drain.js +261 -578
  80. package/dist/commands/proposal/proposal-cli.js +19 -20
  81. package/dist/commands/proposal/proposal-types.js +31 -24
  82. package/dist/commands/proposal/proposal.js +38 -8
  83. package/dist/commands/proposal/propose.js +134 -160
  84. package/dist/commands/proposal/repository.js +1097 -1394
  85. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  86. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  87. package/dist/commands/proposal/validators/proposals.js +22 -89
  88. package/dist/commands/read/curate.js +105 -462
  89. package/dist/commands/read/knowledge.js +3 -2
  90. package/dist/commands/read/search-cli.js +16 -33
  91. package/dist/commands/read/search.js +17 -23
  92. package/dist/commands/read/show.js +57 -108
  93. package/dist/commands/sources/bundle-cli.js +25 -2
  94. package/dist/commands/sources/bundle-config-ops.js +4 -0
  95. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  96. package/dist/commands/sources/info.js +127 -29
  97. package/dist/commands/sources/installed-stashes.js +197 -746
  98. package/dist/commands/sources/schema-repair.js +98 -129
  99. package/dist/commands/sources/source-add.js +62 -12
  100. package/dist/commands/sources/source-manage.js +9 -2
  101. package/dist/commands/sources/stash-cli.js +24 -4
  102. package/dist/commands/tasks/explain.js +10 -13
  103. package/dist/commands/tasks/tasks-cli.js +12 -13
  104. package/dist/commands/tasks/tasks.js +350 -936
  105. package/dist/commands/tasks/validate.js +26 -24
  106. package/dist/commands/workflow/plan.js +22 -29
  107. package/dist/commands/workflow-cli.js +4 -4
  108. package/dist/core/adapter/adapters/akm-adapter.js +2 -1
  109. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  110. package/dist/core/adapter/adapters/akm-metadata.js +42 -12
  111. package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
  112. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  113. package/dist/core/adapter/execution-source.js +17 -29
  114. package/dist/core/asset/asset-placement.js +4 -13
  115. package/dist/core/asset/frontmatter.js +106 -1
  116. package/dist/core/asset/resolve-ref.js +1 -1
  117. package/dist/core/bundle-id.js +42 -5
  118. package/dist/core/bundle-rename.js +285 -0
  119. package/dist/core/config/config-io.js +1 -2
  120. package/dist/core/config/config-schema.js +9 -34
  121. package/dist/core/config/config-walker.js +1 -1
  122. package/dist/core/config/config.js +184 -111
  123. package/dist/core/config/engine-semantics.js +0 -2
  124. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  125. package/dist/core/config/schema/embedding.js +20 -5
  126. package/dist/core/config/schema/engines.js +5 -0
  127. package/dist/core/config/schema/execution.js +1 -1
  128. package/dist/core/config/schema/experimental.js +1 -1
  129. package/dist/core/config/schema/improve-processes.js +54 -125
  130. package/dist/core/config/schema/improve.js +4 -42
  131. package/dist/core/config/schema/index-config.js +9 -48
  132. package/dist/core/config/schema/scheduler.js +12 -12
  133. package/dist/core/config/schema/search.js +6 -22
  134. package/dist/core/env-secret-ref.js +0 -1
  135. package/dist/core/errors.js +8 -9
  136. package/dist/core/file-change.js +13 -5
  137. package/dist/core/file-lock.js +76 -173
  138. package/dist/core/improve-result.js +35 -7
  139. package/dist/core/improve-types.js +0 -1
  140. package/dist/core/logs-db.js +2 -2
  141. package/dist/core/loopback.js +7 -12
  142. package/dist/core/non-task-input.js +20 -0
  143. package/dist/core/parse.js +13 -16
  144. package/dist/core/paths.js +0 -24
  145. package/dist/core/redaction.js +109 -2
  146. package/dist/core/run-lock.js +2 -5
  147. package/dist/core/spawn-env.js +1 -1
  148. package/dist/core/state/migrations.js +123 -61
  149. package/dist/core/state-db-scope.js +2 -4
  150. package/dist/core/state-db.js +126 -692
  151. package/dist/core/time.js +0 -20
  152. package/dist/core/type-presentation.js +1 -9
  153. package/dist/core/write-source.js +294 -1005
  154. package/dist/execution/input-contract.js +1 -1
  155. package/dist/execution/resolved-request.js +135 -689
  156. package/dist/execution/source.js +63 -257
  157. package/dist/execution/target-ref.js +1 -1
  158. package/dist/indexer/bundle-identity-guard.js +2 -2
  159. package/dist/indexer/db/llm-cache.js +2 -2
  160. package/dist/indexer/ensure-index.js +77 -73
  161. package/dist/indexer/index-rebuild-lock.js +3 -11
  162. package/dist/indexer/index-writer-lock.js +8 -17
  163. package/dist/indexer/index-written-assets.js +141 -154
  164. package/dist/indexer/indexer.js +400 -1124
  165. package/dist/indexer/links/declared-links.js +90 -0
  166. package/dist/indexer/materialize-embeddings.js +60 -397
  167. package/dist/indexer/passes/memory-inference.js +96 -90
  168. package/dist/indexer/passes/metadata.js +132 -219
  169. package/dist/indexer/read-preflight.js +0 -7
  170. package/dist/indexer/scan/doc-to-entry.js +2 -3
  171. package/dist/indexer/scan/drain-dir.js +1 -1
  172. package/dist/indexer/search/db-search.js +190 -590
  173. package/dist/indexer/search/fts-query.js +30 -41
  174. package/dist/indexer/search/ranking.js +28 -154
  175. package/dist/indexer/search/search-attribution.js +12 -32
  176. package/dist/indexer/search/search-fields.js +11 -15
  177. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  178. package/dist/indexer/search/search-source.js +1 -4
  179. package/dist/indexer/usage/usage-events.js +36 -7
  180. package/dist/indexer/walk/walker.js +3 -4
  181. package/dist/integrations/agent/engine-fallback.js +23 -40
  182. package/dist/integrations/agent/engine-resolution.js +93 -183
  183. package/dist/integrations/agent/execution.js +507 -0
  184. package/dist/integrations/agent/model-map.js +28 -156
  185. package/dist/integrations/agent/request-lowering.js +66 -141
  186. package/dist/integrations/agent/runner-dispatch.js +143 -321
  187. package/dist/integrations/agent/runner.js +54 -14
  188. package/dist/integrations/lockfile.js +53 -101
  189. package/dist/llm/client.js +18 -6
  190. package/dist/llm/embedders/deterministic.js +2 -3
  191. package/dist/llm/embedders/profile.js +71 -0
  192. package/dist/llm/embedders/remote.js +11 -17
  193. package/dist/llm/feature-gate.js +0 -8
  194. package/dist/llm/index-passes.js +3 -5
  195. package/dist/llm/memory-infer.js +1 -2
  196. package/dist/llm/structured-call.js +5 -24
  197. package/dist/output/generic-render.js +23 -11
  198. package/dist/output/html-render.js +13 -10
  199. package/dist/output/render-registry.js +3 -32
  200. package/dist/output/shapes/helpers.js +25 -38
  201. package/dist/output/shapes/passthrough.js +1 -9
  202. package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
  203. package/dist/output/text/command-format.js +69 -31
  204. package/dist/output/text/helpers.js +1 -1
  205. package/dist/output/text/migrate.js +5 -14
  206. package/dist/output/text/proposal-format.js +48 -3
  207. package/dist/output/text/show-format.js +13 -17
  208. package/dist/output/text/workflow-format.js +0 -32
  209. package/dist/output/text.js +2 -0
  210. package/dist/registry/factory.js +4 -19
  211. package/dist/registry/network.js +66 -220
  212. package/dist/registry/providers/index.js +0 -2
  213. package/dist/registry/providers/skills-sh.js +3 -14
  214. package/dist/registry/providers/static-index.js +24 -26
  215. package/dist/registry/resolve.js +55 -131
  216. package/dist/scripts/akm-migrate-node.js +42948 -92369
  217. package/dist/scripts/akm-migrate.js +42935 -92354
  218. package/dist/setup/registry-stash-loader.js +4 -13
  219. package/dist/setup/semantic-assets.js +3 -44
  220. package/dist/setup/setup.js +1 -1
  221. package/dist/setup/steps/connection.js +5 -6
  222. package/dist/setup/steps/platforms.js +2 -2
  223. package/dist/setup/steps/tasks.js +25 -15
  224. package/dist/sources/provider-factory.js +17 -18
  225. package/dist/sources/providers/filesystem.js +2 -3
  226. package/dist/sources/providers/git-install.js +7 -1
  227. package/dist/sources/providers/git-provider.js +0 -3
  228. package/dist/sources/providers/git-stash.js +83 -21
  229. package/dist/sources/providers/npm.js +2 -4
  230. package/dist/sources/providers/provider-utils.js +5 -10
  231. package/dist/sources/providers/website.js +0 -2
  232. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  233. package/dist/sources/website-url.js +2 -2
  234. package/dist/storage/database.js +9 -35
  235. package/dist/storage/repositories/improve-ledger-repository.js +209 -0
  236. package/dist/storage/repositories/index-connection.js +39 -72
  237. package/dist/storage/repositories/index-entries-repository.js +131 -129
  238. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  239. package/dist/storage/repositories/index-entry-schema.js +101 -268
  240. package/dist/storage/repositories/index-fts-repository.js +86 -256
  241. package/dist/storage/repositories/index-links-repository.js +143 -0
  242. package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
  243. package/dist/storage/repositories/index-meta-repository.js +6 -4
  244. package/dist/storage/repositories/index-schema.js +257 -325
  245. package/dist/storage/repositories/index-utility-repository.js +8 -29
  246. package/dist/storage/repositories/index-vec-repository.js +133 -414
  247. package/dist/storage/repositories/outcome-repository.js +2 -1
  248. package/dist/storage/repositories/proposals-repository.js +104 -1
  249. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  250. package/dist/storage/repositories/salience-repository.js +1 -19
  251. package/dist/storage/repositories/task-history-repository.js +26 -4
  252. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  253. package/dist/storage/sqlite-migrations.js +136 -0
  254. package/dist/storage/sqlite-pragmas.js +11 -9
  255. package/dist/storage/sqlite-transaction.js +170 -0
  256. package/dist/storage/state-db-integrity.js +130 -0
  257. package/dist/tasks/activation-config.js +134 -62
  258. package/dist/tasks/backends/cron.js +191 -302
  259. package/dist/tasks/backends/exec-utils.js +2 -5
  260. package/dist/tasks/backends/launchd.js +141 -748
  261. package/dist/tasks/backends/schtasks.js +119 -623
  262. package/dist/tasks/prepare/prepare-support.js +5 -15
  263. package/dist/tasks/prepare/prepare.js +0 -2
  264. package/dist/tasks/resolve-akm-bin.js +20 -79
  265. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  266. package/dist/tasks/run/load-task.js +1 -1
  267. package/dist/tasks/scheduler-binding.js +20 -238
  268. package/dist/tasks/scheduler-invocation.js +136 -244
  269. package/dist/tasks/scheduler-lock.js +53 -0
  270. package/dist/tasks/scheduler-sync.js +368 -679
  271. package/dist/tasks/source/parse-task-source.js +55 -9
  272. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  273. package/dist/tasks/source/task-to-v4.js +464 -88
  274. package/dist/workflows/authoring/authoring.js +3 -12
  275. package/dist/workflows/compile.js +211 -0
  276. package/dist/workflows/concurrency-policy.js +13 -74
  277. package/dist/workflows/exec/child-invocation.js +3 -17
  278. package/dist/workflows/exec/child-workflow.js +32 -141
  279. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  280. package/dist/workflows/exec/environment.js +98 -0
  281. package/dist/workflows/exec/exec-unit.js +33 -140
  282. package/dist/workflows/exec/frozen-judge.js +7 -59
  283. package/dist/workflows/exec/native-executor.js +82 -341
  284. package/dist/workflows/exec/param-secrets.js +29 -47
  285. package/dist/workflows/exec/run-workflow.js +154 -387
  286. package/dist/workflows/exec/scheduler.js +9 -36
  287. package/dist/workflows/exec/step-work.js +127 -430
  288. package/dist/workflows/exec/unit-dispatch.js +11 -63
  289. package/dist/workflows/exec/unit-writer.js +8 -52
  290. package/dist/workflows/exec/worktree.js +39 -273
  291. package/dist/workflows/freeze/child-output-references.js +4 -15
  292. package/dist/workflows/freeze/environment.js +99 -92
  293. package/dist/workflows/freeze/freeze.js +172 -0
  294. package/dist/workflows/freeze/step-values.js +19 -21
  295. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  296. package/dist/workflows/freeze/targets/command.js +10 -33
  297. package/dist/workflows/freeze/targets/script.js +5 -12
  298. package/dist/workflows/freeze/targets/shell.js +3 -6
  299. package/dist/workflows/freeze/targets/task.js +25 -80
  300. package/dist/workflows/freeze/task-bindings.js +20 -67
  301. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  302. package/dist/workflows/ir/params.js +6 -51
  303. package/dist/workflows/ir/plan-hash.js +2 -34
  304. package/dist/workflows/parser.js +140 -43
  305. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  306. package/dist/workflows/renderer.js +36 -69
  307. package/dist/workflows/resource-limits.js +12 -120
  308. package/dist/workflows/runtime/agent-identity.js +8 -40
  309. package/dist/workflows/runtime/run-outputs.js +3 -6
  310. package/dist/workflows/runtime/run-plan.js +316 -0
  311. package/dist/workflows/runtime/runs.js +48 -200
  312. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  313. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  314. package/dist/workflows/validate-summary.js +2 -7
  315. package/docs/integration/bundling-akm.md +49 -42
  316. package/docs/migration/README.md +1 -0
  317. package/docs/migration/release-notes/0.9.17.md +43 -0
  318. package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
  319. package/docs/reference/cli.md +232 -135
  320. package/docs/reference/configuration.md +71 -57
  321. package/docs/reference/data-and-telemetry.md +20 -21
  322. package/docs/reference/tasks.md +105 -39
  323. package/docs/reference/workflow-schema.md +14 -18
  324. package/docs/reference/workflows.md +6 -9
  325. package/package.json +1 -1
  326. package/schemas/akm-config.json +115 -738
  327. package/schemas/akm-workflow.json +1 -0
  328. package/dist/assets/improve-strategies/graph-refresh.json +0 -15
  329. package/dist/assets/prompts/contradiction-judge.md +0 -33
  330. package/dist/assets/prompts/graph-extract-system.md +0 -1
  331. package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
  332. package/dist/assets/prompts/metadata-enhance-system.md +0 -1
  333. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
  334. package/dist/commands/health/advisories.js +0 -150
  335. package/dist/commands/health/metrics.js +0 -329
  336. package/dist/commands/health/surfaces.js +0 -102
  337. package/dist/commands/improve/anti-collapse.js +0 -83
  338. package/dist/commands/improve/collapse-detector.js +0 -432
  339. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  340. package/dist/commands/improve/consolidate/merge.js +0 -149
  341. package/dist/commands/improve/distill/promote-memory.js +0 -291
  342. package/dist/commands/improve/distill/quality-gate.js +0 -337
  343. package/dist/commands/improve/eval-cases.js +0 -52
  344. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  345. package/dist/commands/improve/proposal-envelope.js +0 -31
  346. package/dist/commands/improve/run-context.js +0 -123
  347. package/dist/commands/improve/shared.js +0 -31
  348. package/dist/commands/improve/source-identity.js +0 -28
  349. package/dist/commands/improve/triage.js +0 -96
  350. package/dist/commands/proposal/drain-policies.js +0 -151
  351. package/dist/commands/sources/update-transaction.js +0 -220
  352. package/dist/core/action-contributors.js +0 -28
  353. package/dist/core/config/config-version-shim.js +0 -101
  354. package/dist/core/fs-txn.js +0 -405
  355. package/dist/core/lexical-score.js +0 -25
  356. package/dist/core/maintenance-barrier.js +0 -167
  357. package/dist/execution/executable-identity.js +0 -105
  358. package/dist/execution/guarded-source.js +0 -427
  359. package/dist/indexer/db/graph-db.js +0 -444
  360. package/dist/indexer/graph/graph-boost.js +0 -427
  361. package/dist/indexer/graph/graph-dedup.js +0 -95
  362. package/dist/indexer/graph/graph-extraction.js +0 -1108
  363. package/dist/indexer/search/name-match.js +0 -35
  364. package/dist/indexer/search/ranking-contributors.js +0 -515
  365. package/dist/indexer/search/ranking-types.js +0 -4
  366. package/dist/indexer/walk/project-context.js +0 -192
  367. package/dist/integrations/agent/execution-cascade.js +0 -566
  368. package/dist/integrations/agent/execution-definitions.js +0 -202
  369. package/dist/integrations/agent/execution-lowering.js +0 -841
  370. package/dist/integrations/agent/execution-preparation.js +0 -98
  371. package/dist/integrations/agent/inline-execution.js +0 -74
  372. package/dist/llm/graph-extract.js +0 -728
  373. package/dist/llm/metadata-enhance.js +0 -96
  374. package/dist/registry/create-provider-registry.js +0 -29
  375. package/dist/registry/pinned-request-helper.js +0 -247
  376. package/dist/registry/pinned-transport.js +0 -717
  377. package/dist/sources/providers/index.js +0 -14
  378. package/dist/storage/engines/sqlite-migrations.js +0 -271
  379. package/dist/storage/repositories/canaries-repository.js +0 -107
  380. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  381. package/dist/storage/repositories/registry-cache.js +0 -113
  382. package/dist/tasks/scheduler-sync-preview.js +0 -52
  383. package/dist/tasks/source/task-to-v3.js +0 -507
  384. package/dist/workflows/freeze/resolve-steps.js +0 -86
  385. package/dist/workflows/freeze/source-freeze.js +0 -64
  386. package/dist/workflows/ir/compile.js +0 -321
  387. package/dist/workflows/ir/environment-v4.js +0 -330
  388. package/dist/workflows/ir/freeze-v4.js +0 -153
  389. package/dist/workflows/ir/schema-v4.js +0 -745
  390. package/dist/workflows/ir/schema.js +0 -354
  391. package/dist/workflows/program/schema.js +0 -77
  392. package/dist/workflows/runtime/checkin.js +0 -57
  393. package/dist/workflows/runtime/plan-classifier.js +0 -196
  394. package/dist/workflows/runtime/unit-checkin.js +0 -45
  395. package/dist/workflows/runtime/unit-phases.js +0 -20
  396. package/dist/workflows/schema.js +0 -4
  397. package/dist/workflows/source-ir/compile.js +0 -200
  398. package/dist/workflows/source-ir/program.js +0 -50
  399. package/dist/workflows/source-ir/result.js +0 -26
  400. package/dist/workflows/source-ir/schema.js +0 -786
  401. package/dist/workflows/source-ir/triggers.js +0 -79
  402. package/dist/workflows/source-ir/uses.js +0 -40
  403. package/dist/workflows/validator.js +0 -60
@@ -1,354 +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 { isContainedRelativePath, isRecord } from "../../core/common.js";
5
- import { UsageError } from "../../core/errors.js";
6
- import { parseReference } from "../program/expressions.js";
7
- import { PROGRAM_PARAM_NAME_PATTERN, PROGRAM_RETRY_REASONS, PROGRAM_STEP_ID_PATTERN } from "../program/schema.js";
8
- import { jsonBytes, utf8Bytes, WORKFLOW_ENV_VAR_NAME_PATTERN, WORKFLOW_MAX_CONCURRENCY, WORKFLOW_MAX_INSTRUCTION_BYTES, WORKFLOW_MAX_SCHEMA_BYTES, WORKFLOW_MAX_TIMEOUT_MS, } from "../resource-limits.js";
9
- // Shared dispatch-significant bounds now live in `../resource-limits` so the
10
- // parser, the published JSON Schema, and this decoder enforce identical
11
- // values. Re-exported here for existing importers (e.g. `commands/workflow-cli.ts`).
12
- export { WORKFLOW_MAX_CONCURRENCY, WORKFLOW_MAX_TIMEOUT_MS };
13
- const MAX_LIST_ITEMS = 1024;
14
- const MAX_STRING_LENGTH = 1_000_000;
15
- /** Validate the current durable execution graph. */
16
- export function validateWorkflowPlanStructure(input, options) {
17
- if (!isRecord(input) || input.irVersion !== options.expectedVersion) {
18
- fail(`irVersion must be ${options.expectedVersion}`);
19
- }
20
- assertJson(input);
21
- const plan = input;
22
- assertKeys(input, ["irVersion", "title", "params", "paramSchemas", "budget", "execution", "steps", ...(options.planExtraKeys ?? [])], "plan");
23
- assertString(plan.title, "title");
24
- validateParams(plan.params, plan.paramSchemas);
25
- validateBudget(plan.budget);
26
- if (!isRecord(plan.execution) ||
27
- !Number.isInteger(plan.execution.maxConcurrency) ||
28
- plan.execution.maxConcurrency < 1 ||
29
- plan.execution.maxConcurrency > WORKFLOW_MAX_CONCURRENCY) {
30
- fail(`execution.maxConcurrency must be an integer from 1 through ${WORKFLOW_MAX_CONCURRENCY}`);
31
- }
32
- assertKeys(plan.execution, ["maxConcurrency"], "execution");
33
- if (!Array.isArray(plan.steps) || plan.steps.length === 0)
34
- fail("steps must be a non-empty array");
35
- const stepIds = new Set();
36
- const nodeIds = new Set();
37
- for (let index = 0; index < plan.steps.length; index++) {
38
- const step = plan.steps[index];
39
- if (!isRecord(step) ||
40
- typeof step.stepId !== "string" ||
41
- !PROGRAM_STEP_ID_PATTERN.test(step.stepId) ||
42
- stepIds.has(step.stepId))
43
- fail("step ids must be unique non-empty strings");
44
- stepIds.add(step.stepId);
45
- if (step.sequenceIndex !== index)
46
- fail("step sequence indices must be contiguous and unique");
47
- assertString(step.title, `step ${step.stepId} title`);
48
- if (!!step.root === !!step.route)
49
- fail(`step ${step.stepId} must contain exactly one of root or route`);
50
- assertKeys(step, ["stepId", "title", "sequenceIndex", "root", "route", "outputSchema", "gate"], `step ${step.stepId}`);
51
- if (step.outputSchema !== undefined)
52
- validateSchema(step.outputSchema, `step ${step.stepId} outputSchema`);
53
- if (step.root)
54
- validateNode(step.root, step.stepId, nodeIds, options.unitExtraKeys ?? []);
55
- if (step.route)
56
- validateRoute(step.route, step.stepId);
57
- validateGate(step.gate, step.stepId, nodeIds, options.gateExtraKeys ?? []);
58
- }
59
- const stepIndex = new Map(plan.steps.map((step, index) => [step.stepId, index]));
60
- for (const [index, step] of plan.steps.entries()) {
61
- for (const target of step.route
62
- ? [...Object.values(step.route.when), ...(step.route.defaultStepId ? [step.route.defaultStepId] : [])]
63
- : []) {
64
- const targetIndex = stepIndex.get(target);
65
- if (targetIndex === undefined)
66
- fail(`route target ${target} does not name a step`);
67
- if (targetIndex <= index)
68
- fail(`route target ${target} must come after step ${step.stepId}`);
69
- }
70
- validateStepExpressions(step, index, stepIndex);
71
- }
72
- }
73
- function validateNode(node, stepId, nodeIds, unitExtraKeys) {
74
- if (!isRecord(node) ||
75
- (node.kind !== "unit" && node.kind !== "map") ||
76
- typeof node.id !== "string" ||
77
- !node.id ||
78
- nodeIds.has(node.id))
79
- fail("node ids must be unique non-empty strings");
80
- nodeIds.add(node.id);
81
- if (node.kind === "map") {
82
- assertKeys(node, ["kind", "id", "over", "template", "concurrency", "reducer", "source"], `map ${node.id}`);
83
- if (typeof node.over !== "string" ||
84
- !node.over ||
85
- !Number.isInteger(node.concurrency) ||
86
- node.concurrency < 1 ||
87
- node.concurrency > WORKFLOW_MAX_CONCURRENCY ||
88
- (node.reducer !== "collect" && node.reducer !== "vote"))
89
- fail(`map ${node.id} is invalid`);
90
- if (node.id !== `${stepId}.map`)
91
- fail(`map ${node.id} does not match step ${stepId}`);
92
- validateSource(node.source, `map ${node.id} source`);
93
- validateNode(node.template, stepId, nodeIds, unitExtraKeys);
94
- if (!isRecord(node.template) || node.template.kind !== "unit")
95
- fail(`map ${node.id} template must be a unit`);
96
- if (node.template.id !== `${stepId}.unit`)
97
- fail(`map ${node.id} template id is invalid`);
98
- return;
99
- }
100
- assertKeys(node, [
101
- "kind",
102
- "id",
103
- "instructions",
104
- "inputs",
105
- "schema",
106
- "retry",
107
- "onError",
108
- "env",
109
- "isolation",
110
- "source",
111
- ...unitExtraKeys,
112
- ], `unit ${node.id}`);
113
- if (typeof node.instructions !== "string" ||
114
- !node.instructions ||
115
- (node.onError !== "fail" && node.onError !== "continue") ||
116
- (node.isolation !== "none" && node.isolation !== "worktree"))
117
- fail(`unit ${node.id} is invalid`);
118
- if (node.id !== stepId && node.id !== `${stepId}.unit`)
119
- fail(`unit ${node.id} does not belong to step ${stepId}`);
120
- if (utf8Bytes(node.instructions) > WORKFLOW_MAX_INSTRUCTION_BYTES)
121
- fail(`unit ${node.id} instructions exceed the 256 KiB resource limit`);
122
- if (node.schema !== undefined)
123
- validateSchema(node.schema, `unit ${node.id} schema`);
124
- validateRetry(node.retry, node.id);
125
- validateStringArray(node.env, `unit ${node.id} env`, MAX_LIST_ITEMS, true);
126
- validateStringArray(node.inputs, `unit ${node.id} inputs`, Infinity, true);
127
- validateSource(node.source, `unit ${node.id} source`);
128
- }
129
- /**
130
- * Strictly decode a frozen {@link IrExecSpec}. This is the corruption gate for
131
- * a persisted plan: the argv bounds, the relative-and-contained `cwd`, and the
132
- * timeout range are all re-checked here, because `plan_json` may have been
133
- * hand-edited between freeze and dispatch.
134
- */
135
- function validateExecSpec(value, label) {
136
- if (!isRecord(value))
137
- fail(`${label} must be an object`);
138
- assertKeys(value, ["command", "cwd", "passEnv", "timeoutMs"], label);
139
- validateExecEnvScope(value, label);
140
- const command = value.command;
141
- if (!Array.isArray(command) ||
142
- command.length === 0 ||
143
- !command.every((arg) => typeof arg === "string" && arg.length > 0)) {
144
- fail(`${label}.command must be an argv array of non-empty strings`);
145
- }
146
- if (value.cwd !== undefined) {
147
- if (typeof value.cwd !== "string" || value.cwd.length === 0 || !isContainedRelativePath(value.cwd)) {
148
- fail(`${label}.cwd must be a relative path contained in the unit working directory`);
149
- }
150
- }
151
- if (!(value.timeoutMs === null ||
152
- (Number.isSafeInteger(value.timeoutMs) &&
153
- value.timeoutMs >= 1 &&
154
- value.timeoutMs <= WORKFLOW_MAX_TIMEOUT_MS))) {
155
- fail(`${label}.timeoutMs must be null or an integer from 1 through ${WORKFLOW_MAX_TIMEOUT_MS}`);
156
- }
157
- }
158
- /** Decode one current frozen exec spec. */
159
- export function decodeWorkflowExecSpec(value, label) {
160
- validateExecSpec(value, label);
161
- return value;
162
- }
163
- /**
164
- * The child's ENVIRONMENT SCOPE half of a frozen exec spec. Split out so
165
- * {@link validateExecSpec} keeps its shape (and the src-fn-size ratchet stays
166
- * shrink-only).
167
- *
168
- * `passEnv` is canonical-form-only and may only be a non-empty deduplicated
169
- * name list. A persisted `[]` means exactly what absence means, and admitting a
170
- * second spelling of the default would give the same unit two different input
171
- * hashes.
172
- */
173
- function validateExecEnvScope(value, label) {
174
- if (value.passEnv === undefined)
175
- return;
176
- const passEnv = value.passEnv;
177
- if (!Array.isArray(passEnv) ||
178
- passEnv.length === 0 ||
179
- !passEnv.every((name) => typeof name === "string" && WORKFLOW_ENV_VAR_NAME_PATTERN.test(name)) ||
180
- new Set(passEnv).size !== passEnv.length) {
181
- fail(`${label}.passEnv must be a non-empty list of distinct environment variable names matching ` +
182
- `${WORKFLOW_ENV_VAR_NAME_PATTERN.source}`);
183
- }
184
- }
185
- function validateGate(gate, stepId, nodeIds, gateExtraKeys) {
186
- if (!isRecord(gate) ||
187
- gate.kind !== "gate" ||
188
- gate.id !== `${stepId}.gate` ||
189
- gate.stepId !== stepId ||
190
- !Array.isArray(gate.criteria) ||
191
- gate.criteria.length > MAX_LIST_ITEMS ||
192
- !gate.criteria.every((x) => typeof x === "string" && x.length > 0 && x.length <= MAX_STRING_LENGTH) ||
193
- !Number.isInteger(gate.maxLoops) ||
194
- gate.maxLoops < 1)
195
- fail(`gate for step ${stepId} is invalid`);
196
- if (nodeIds.has(gate.id))
197
- fail(`gate id ${gate.id} collides with a node`);
198
- assertKeys(gate, ["kind", "id", "stepId", "criteria", "maxLoops", ...gateExtraKeys], `gate ${stepId}`);
199
- nodeIds.add(gate.id);
200
- }
201
- function validateRoute(route, stepId) {
202
- if (!isRecord(route) ||
203
- typeof route.input !== "string" ||
204
- !route.input ||
205
- !isRecord(route.when) ||
206
- Object.keys(route.when).length === 0 ||
207
- !Object.keys(route.when).every((match) => match.length > 0 && match.length <= MAX_STRING_LENGTH) ||
208
- !Object.values(route.when).every((target) => typeof target === "string" && target))
209
- fail(`route for step ${stepId} is invalid`);
210
- assertKeys(route, ["input", "when", "defaultStepId"], `route ${stepId}`);
211
- if (route.defaultStepId !== undefined && (typeof route.defaultStepId !== "string" || !route.defaultStepId))
212
- fail(`route for step ${stepId} has an invalid default target`);
213
- }
214
- function assertKeys(value, allowed, label) {
215
- for (const key of Object.keys(value))
216
- if (!allowed.includes(key))
217
- fail(`${label} contains unknown key ${key}`);
218
- }
219
- function assertJson(value) {
220
- if (value === null || typeof value === "boolean")
221
- return;
222
- if (typeof value === "string") {
223
- if (value.length > MAX_STRING_LENGTH)
224
- fail("plan contains an oversized string");
225
- return;
226
- }
227
- if (typeof value === "number") {
228
- if (!Number.isFinite(value))
229
- fail("plan contains a non-finite number");
230
- return;
231
- }
232
- if (Array.isArray(value)) {
233
- for (const item of value)
234
- assertJson(item);
235
- return;
236
- }
237
- if (isRecord(value)) {
238
- for (const item of Object.values(value))
239
- assertJson(item);
240
- return;
241
- }
242
- fail("plan contains a non-JSON value");
243
- }
244
- function validateParams(params, schemas) {
245
- validateStringArray(params, "params", Infinity, true);
246
- if (params?.some((name) => !PROGRAM_PARAM_NAME_PATTERN.test(name)))
247
- fail("params contains an invalid name");
248
- if (schemas !== undefined) {
249
- if (!isRecord(schemas))
250
- fail("paramSchemas must be an object");
251
- for (const [name, schema] of Object.entries(schemas)) {
252
- if (!PROGRAM_PARAM_NAME_PATTERN.test(name))
253
- fail(`paramSchemas.${name} is invalid`);
254
- validateSchema(schema, `paramSchemas.${name}`);
255
- }
256
- }
257
- const names = params ?? [];
258
- if (schemas && (names.length !== Object.keys(schemas).length || names.some((name) => !Object.hasOwn(schemas, name))))
259
- fail("params and paramSchemas must name the same parameters");
260
- if (!schemas && names.length > 0) {
261
- // Markdown workflows have named parameters but no schemas, which is valid.
262
- return;
263
- }
264
- }
265
- function validateBudget(budget) {
266
- if (budget === undefined)
267
- return;
268
- if (!isRecord(budget))
269
- fail("budget must be an object");
270
- assertKeys(budget, ["maxTokens", "maxUnits"], "budget");
271
- if (budget.maxTokens === undefined && budget.maxUnits === undefined)
272
- fail("budget must declare a ceiling");
273
- validateOptionalPositiveInteger(budget.maxTokens, "budget.maxTokens");
274
- const maxUnits = budget.maxUnits;
275
- if (maxUnits !== undefined && (!Number.isSafeInteger(maxUnits) || maxUnits < 1))
276
- fail("budget.maxUnits must be a positive integer");
277
- }
278
- function validateRetry(retry, nodeId) {
279
- if (retry === undefined)
280
- return;
281
- if (!isRecord(retry))
282
- fail(`unit ${nodeId} retry must be an object`);
283
- assertKeys(retry, ["max", "on"], `unit ${nodeId} retry`);
284
- if (!Number.isSafeInteger(retry.max) || retry.max < 0)
285
- fail(`unit ${nodeId} retry.max is invalid`);
286
- validateStringArray(retry.on, `unit ${nodeId} retry.on`, PROGRAM_RETRY_REASONS.length, true);
287
- if (retry.on === undefined ||
288
- retry.on.length === 0 ||
289
- retry.on.some((reason) => !PROGRAM_RETRY_REASONS.includes(reason)))
290
- fail(`unit ${nodeId} retry.on is invalid`);
291
- }
292
- function validateSchema(value, label) {
293
- if (!isRecord(value))
294
- fail(`${label} must be an object`);
295
- if (jsonBytes(value) > WORKFLOW_MAX_SCHEMA_BYTES)
296
- fail(`${label} exceeds the 256 KiB resource limit`);
297
- }
298
- function validateStepExpressions(step, index, steps) {
299
- const validateReference = (text, label, paramsAllowed) => {
300
- const parsed = parseReference(text);
301
- if (!parsed.ok)
302
- fail(`${label} contains an invalid reference`);
303
- if (parsed.expr.kind === "param" && !paramsAllowed)
304
- fail(`${label} must reference a step output`);
305
- if (parsed.expr.kind === "stepOutput") {
306
- const referenced = steps.get(parsed.expr.stepId);
307
- if (referenced === undefined || referenced >= index)
308
- fail(`${label} references a non-earlier step`);
309
- }
310
- };
311
- if (step.root) {
312
- const unit = step.root.kind === "map" ? step.root.template : step.root;
313
- if (step.root.kind === "map")
314
- validateReference(step.root.over, `map ${step.root.id} over`, true);
315
- for (const reference of unit.inputs ?? [])
316
- validateReference(reference, `unit ${unit.id} inputs`, false);
317
- }
318
- if (step.route)
319
- validateReference(step.route.input, `route ${step.stepId} input`, true);
320
- }
321
- function validateSource(value, label) {
322
- if (value === undefined)
323
- return;
324
- if (!isRecord(value))
325
- fail(`${label} must be an object`);
326
- assertKeys(value, ["path", "start", "end"], label);
327
- if (typeof value.path !== "string" ||
328
- !value.path ||
329
- !Number.isSafeInteger(value.start) ||
330
- !Number.isSafeInteger(value.end) ||
331
- value.start < 1 ||
332
- value.end < value.start)
333
- fail(`${label} is invalid`);
334
- }
335
- function validateStringArray(value, label, max, unique) {
336
- if (value === undefined)
337
- return;
338
- if (!Array.isArray(value) ||
339
- value.length > max ||
340
- !value.every((item) => typeof item === "string" && item.length > 0 && item.length <= MAX_STRING_LENGTH) ||
341
- (unique && new Set(value).size !== value.length))
342
- fail(`${label} is invalid`);
343
- }
344
- function validateOptionalPositiveInteger(value, label) {
345
- if (value !== undefined && (!Number.isSafeInteger(value) || value < 1))
346
- fail(`${label} must be a positive safe integer`);
347
- }
348
- function assertString(value, label) {
349
- if (typeof value !== "string" || value.length === 0 || value.length > MAX_STRING_LENGTH)
350
- fail(`${label} must be a non-empty bounded string`);
351
- }
352
- function fail(message) {
353
- throw new UsageError(`Invalid frozen workflow plan: ${message}.`);
354
- }
@@ -1,77 +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
- /** How a map step folds its per-item unit results into the step artifact. */
5
- export const PROGRAM_REDUCERS = ["collect", "vote"];
6
- /** Failure policy: fail the step on first unit failure, or record and go on. */
7
- export const PROGRAM_ON_ERROR = ["fail", "continue"];
8
- /** Filesystem isolation for file-mutating units. */
9
- export const PROGRAM_ISOLATION_KINDS = ["none", "worktree"];
10
- /**
11
- * `retry.on` vocabulary — exactly the persisted `AgentFailureReason` taxonomy
12
- * from `src/integrations/agent/spawn.ts`. The `satisfies` clause fails the
13
- * typecheck if spawn.ts adds/renames a reason without this list (and the JSON
14
- * Schema, via the drift test) being updated.
15
- */
16
- const RETRY_REASON_SET = {
17
- timeout: true,
18
- spawn_failed: true,
19
- non_zero_exit: true,
20
- parse_error: true,
21
- cooldown: true,
22
- llm_rate_limit: true,
23
- llm_content_filter: true,
24
- llm_invalid_json: true,
25
- content_policy_reject: true,
26
- unsupported_type: true,
27
- no_change: true,
28
- aborted: true,
29
- };
30
- export const PROGRAM_RETRY_REASONS = Object.keys(RETRY_REASON_SET);
31
- /**
32
- * Step ids: `[A-Za-z_][A-Za-z0-9_-]*` (also pinned in the JSON Schema) — the
33
- * ONE id grammar for the shared source IR (workflow-format-unification, spec
34
- * §2.2). This is EXACTLY the `<ident>` grammar `readIdent` accepts in
35
- * `program/expressions.ts` for `steps.<id>.output` references: a
36
- * letter/underscore first char, then letters/digits/underscores/dashes, and
37
- * NO dots (the expression parser treats `.` as the `.output` path separator,
38
- * so a dotted id could never be addressed). Keeping step ids inside the
39
- * addressable grammar guarantees every step can be referenced from map
40
- * inputs, routes, and `inputs:` without renaming.
41
- *
42
- * Forbidding dots additionally keeps the engine's internal gate-row node id
43
- * `<stepId>.gate` collision-free: no user step id can contain a dot, so it can
44
- * never equal another step's `<stepId>.gate` synthetic id.
45
- */
46
- export const PROGRAM_STEP_ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*$/;
47
- /**
48
- * Param names must be `params.<ident>`-addressable, so they are plain
49
- * identifiers (no dots/dashes). Re-exported from the shared input contract
50
- * (`src/execution/input-contract.ts`'s `INPUT_NAME_PATTERN`) so task source
51
- * v4's `inputs:` declarations share the exact same name pattern rather than a
52
- * second, hand-maintained copy (P2a, D3-N1).
53
- */
54
- export { INPUT_NAME_PATTERN as PROGRAM_PARAM_NAME_PATTERN } from "../../execution/input-contract.js";
55
- /**
56
- * The ONE structural projection of an exec spec — ONE encoding per state.
57
- *
58
- * Every layer that carries an exec forward derives from this: the compiled
59
- * draft, the frozen plan (which layers `timeoutMs` on top), and the summary
60
- * `akm workflow show` prints. Written out per layer instead, a field added to
61
- * {@link ProgramExec} reaches whichever copies were remembered and silently
62
- * vanishes from the rest — and nothing catches it, because every key here is
63
- * optional, so an omitted spread is not a type error. What it would cost:
64
- * either the frozen plan loses a field the author wrote (and the canonical
65
- * hash preimage stops matching the authored intent), or `show` describes
66
- * something other than what runs.
67
- *
68
- * The ABSENCE of both env keys is the default allowlist. The parser rejects an
69
- * empty `pass_env` outright, so no layer has to distinguish absent from empty.
70
- */
71
- export function projectExecCore(exec) {
72
- return {
73
- command: [...exec.command],
74
- ...(exec.cwd ? { cwd: exec.cwd } : {}),
75
- ...(exec.passEnv && exec.passEnv.length > 0 ? { passEnv: [...exec.passEnv] } : {}),
76
- };
77
- }
@@ -1,57 +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
- * Agent check-in: a no-background-thread "continue" nudge for stalled workflow
6
- * runs (#506).
7
- *
8
- * The design decision (the workflow-agent check-in ADR)
9
- * reconciles #506 (file/command-loop signal) with #501 (background thread) in
10
- * favour of the former. There is intentionally NO timer or resident process
11
- * here. Arming a check-in writes a timestamp (`checkin_armed_at`) on the run
12
- * row; the next time the agent polls the engine via `workflow run`/`status`,
13
- * {@link evaluateCheckin} is called to decide — purely from timestamps — whether
14
- * the run looks stalled and a strong `continue` directive should be surfaced
15
- * through the normal command output.
16
- *
17
- * @module workflows/checkin
18
- */
19
- /**
20
- * Default stall window. If a run has been active and untouched for at least
21
- * this long since the later of its last update and its armed timestamp, the
22
- * next poll surfaces a check-in directive.
23
- */
24
- export const CHECKIN_STALL_MS = 90_000;
25
- function parseIso(value) {
26
- if (!value)
27
- return null;
28
- const ms = Date.parse(value);
29
- return Number.isNaN(ms) ? null : ms;
30
- }
31
- /**
32
- * Pure check-in evaluator. Returns a `continue` directive when an *active* run
33
- * has been idle past the stall window, otherwise `null`. Deterministic in
34
- * `now`, so it is trivially unit-testable and free of timer flakiness.
35
- */
36
- export function evaluateCheckin(run, now = Date.now(), stallMs = CHECKIN_STALL_MS) {
37
- if (run.status !== "active")
38
- return null;
39
- const updated = parseIso(run.updatedAt);
40
- const armed = parseIso(run.checkinArmedAt);
41
- // Never armed → no check-in (opt-in per run via startWorkflowRun).
42
- if (armed === null)
43
- return null;
44
- const last = Math.max(updated ?? armed, armed);
45
- const idleMs = now - last;
46
- if (idleMs < stallMs)
47
- return null;
48
- return {
49
- signal: "continue",
50
- directive: "CONTINUE: this workflow run has stalled with no progress. Resume immediately — " +
51
- "inspect its status, then call `akm workflow run` with the run id to finish the outstanding work. " +
52
- "Do not stop until the run reaches a terminal state or reports a verification rejection.",
53
- idleMs,
54
- agentHarness: run.agentHarness ?? null,
55
- agentSessionId: run.agentSessionId ?? null,
56
- };
57
- }