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,20 @@
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
+ * drivers (step-work, brief, run-workflow) and the runtime (unit-checkin) can
7
+ * key on 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";
@@ -2,99 +2,242 @@
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 fs from "node:fs";
5
- import { parseAssetRef } from "../../core/asset/asset-ref.js";
6
- import { canonicalizeWorkflowName } from "../../core/asset/asset-spec.js";
5
+ import path from "node:path";
6
+ import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
7
+ import { adapterForId } from "../../core/adapter/registry.js";
8
+ import { makeBundleRef, parseBundleRef } from "../../core/asset/asset-ref.js";
9
+ import { isWithin } from "../../core/common.js";
7
10
  import { loadConfig } from "../../core/config/config.js";
8
11
  import { NotFoundError, UsageError } from "../../core/errors.js";
9
12
  import { getDbPath } from "../../core/paths.js";
13
+ import { canonicalizeWorkflowName, WORKFLOW_EXTENSIONS } from "../../core/recognition-util.js";
14
+ import { deriveInstallations } from "../../indexer/installations.js";
10
15
  import { resolveSourceEntries } from "../../indexer/search/search-source.js";
11
- import { resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
16
+ import { buildFileContext } from "../../indexer/walk/file-context.js";
12
17
  import { resolveAssetPath } from "../../sources/resolve.js";
13
18
  import { withIndexDb } from "../../storage/repositories/index-db.js";
14
19
  import { formatWorkflowErrors } from "../authoring/authoring.js";
15
- import { compileWorkflowPlan, compileWorkflowProgram } from "../ir/compile.js";
16
20
  import { parseWorkflow } from "../parser.js";
17
- import { parseWorkflowProgram } from "../program/parser.js";
18
- import { isWorkflowProgramPath, projectProgramParameters, projectProgramStepDefinitions } from "../program/project.js";
21
+ import { WORKFLOW_SCHEMA_VERSION } from "../schema.js";
19
22
  /**
20
- * Compile a loaded workflow asset into the plan graph that gets frozen on the
21
- * run row. YAML programs compile via `compileWorkflowProgram` with full
22
- * expression validation; markdown documents compile via `compileWorkflowPlan`
23
- * (linear workflows — the stable contract — produce the same linear plan as
24
- * today). Exactly one of `program` / `document` is set by this loader.
23
+ * Build the canonical `workflow_runs.workflow_ref` for an AKM workflow asset.
25
24
  */
26
- export function compileWorkflowAssetPlan(asset) {
27
- if (asset.program) {
28
- const compiled = compileWorkflowProgram(asset.program);
29
- if (!compiled.ok) {
30
- throw new UsageError(formatWorkflowErrors(asset.path, compiled.errors));
31
- }
32
- return compiled.plan;
25
+ export function canonicalWorkflowRunRef(bundle, canonicalName) {
26
+ return makeBundleRef(bundle, `workflows/${canonicalName}`);
27
+ }
28
+ /** Parse a workflow ref using the canonical `[bundle//]conceptId` grammar. */
29
+ export function parseWorkflowRefInput(ref) {
30
+ const parsed = parseBundleRef(ref.trim());
31
+ if (parsed.fragment !== undefined) {
32
+ throw new UsageError(`Export fragment "#${parsed.fragment}" is not accepted in a workflow ref.`, "INVALID_FLAG_VALUE");
33
33
  }
34
- if (asset.document) {
35
- return compileWorkflowPlan(asset.document);
34
+ if (parsed.conceptId.startsWith("workflow:")) {
35
+ throw new UsageError(`Invalid workflow ref "${ref.trim()}". Use [bundle//]conceptId, such as workflows/release.`, "INVALID_FLAG_VALUE");
36
36
  }
37
- // Unreachable for assets produced by loadWorkflowAsset; guards hand-built ones.
38
- throw new UsageError(`Workflow asset ${asset.ref} carries neither a parsed document nor a program to compile.`);
37
+ return parsed;
38
+ }
39
+ /** Resolve input sugar to the workflow's canonical run identity. */
40
+ export async function canonicalizeWorkflowRefInput(ref) {
41
+ return (await loadWorkflowAsset(ref)).ref;
39
42
  }
40
43
  /**
41
- * Resolve a `workflow:<name>` ref to a fully-projected {@link WorkflowAsset}.
42
- *
43
- * Prefers the parsed document cached in `index.db` (fast path) and falls back to
44
- * reading + parsing the source file from disk. Pure loading/parsing concern —
45
- * extracted from the run repository so run orchestration no longer owns asset
46
- * resolution.
44
+ * Resolve a workflow ref to a fully-projected {@link WorkflowAsset}. Prefers the
45
+ * parsed document cached in `index.db` (fast path) and falls back to reading +
46
+ * parsing the source file from disk.
47
47
  */
48
48
  export async function loadWorkflowAsset(ref) {
49
- const parsed = parseAssetRef(ref);
50
- if (parsed.type !== "workflow") {
51
- throw new UsageError(`Expected a workflow ref (workflow:<name>), got "${ref}".`);
52
- }
49
+ const bundleRef = parseWorkflowRefInput(ref);
53
50
  const config = loadConfig();
54
51
  const allSources = resolveSourceEntries(undefined, config);
55
- const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
52
+ const installations = deriveInstallations(allSources);
53
+ const searchSources = allSources.flatMap((source, index) => {
54
+ const bundleId = installations[index]?.id;
55
+ if (!bundleId || (bundleRef.bundle !== undefined && bundleRef.bundle !== bundleId))
56
+ return [];
57
+ return [{ source, bundleId }];
58
+ });
59
+ if (bundleRef.bundle && searchSources.length === 0) {
60
+ throw new UsageError(`Bundle "${bundleRef.bundle}" was not found among configured sources.`, "INVALID_FLAG_VALUE");
61
+ }
56
62
  let assetPath;
57
63
  let sourcePath;
58
- for (const source of searchSources) {
64
+ let sourceBundleId;
65
+ let workflowName;
66
+ let workflowAdapterId;
67
+ let rejectedSource;
68
+ for (const candidateSource of searchSources) {
69
+ const { source, bundleId } = candidateSource;
59
70
  try {
60
- assetPath = await resolveAssetPath(source.path, "workflow", parsed.name);
71
+ const adapterId = source.adapterId ?? detectAdapterId(source.path);
72
+ const candidateName = adapterId === "akm-workflow" ? bundleRef.conceptId : workflowNameFromConceptId(bundleRef.conceptId);
73
+ const ownedSource = source.adapterId ? source : { ...source, adapterId };
74
+ if (!candidateName) {
75
+ if (adapterOwnsConcept(source.path, adapterId, bundleRef.conceptId)) {
76
+ rejectedSource ??= { source: ownedSource, bundleId };
77
+ break;
78
+ }
79
+ continue;
80
+ }
81
+ const candidate = await resolveNativeWorkflowPath(source.path, adapterId, candidateName);
82
+ if (!ownsNativeWorkflowRuntime(ownedSource)) {
83
+ rejectedSource ??= { source: ownedSource, bundleId };
84
+ break;
85
+ }
86
+ assetPath = candidate;
61
87
  sourcePath = source.path;
88
+ sourceBundleId = bundleId;
89
+ workflowName = candidateName;
90
+ workflowAdapterId = adapterId;
62
91
  break;
63
92
  }
64
- catch {
65
- /* continue */
93
+ catch (error) {
94
+ if (error instanceof NotFoundError)
95
+ continue;
96
+ throw error;
66
97
  }
67
98
  }
68
99
  if (!assetPath) {
69
- throw new NotFoundError(`Workflow not found for ref: workflow:${parsed.name}`);
70
- }
71
- const resolvedSourcePath = sourcePath ?? config.stashDir ?? assetPath;
72
- // Canonicalize the stored ref: `workflow:foo.yaml` and `workflow:foo`
73
- // resolve to the same file, so they MUST share one run identity. The raw
74
- // `parsed.name` (with any extension) is what drives file resolution above;
75
- // only the persisted/queried ref is collapsed (matches the index entry key,
76
- // which is keyed by the extension-stripped canonical name).
77
- const canonicalName = canonicalizeWorkflowName(parsed.name);
78
- const fullRef = `${parsed.origin ? `${parsed.origin}//` : ""}workflow:${canonicalName}`;
79
- // Format detection by extension: `.yaml`/`.yml` is a YAML workflow program
80
- // (redesign addendum, R1); everything else is the markdown document format.
81
- if (isWorkflowProgramPath(assetPath)) {
82
- const program = loadWorkflowProgramFromDisk(assetPath);
83
- return projectProgramAsset(program, fullRef, assetPath, resolvedSourcePath);
84
- }
85
- const cached = readWorkflowDocumentFromIndex(resolvedSourcePath, fullRef);
100
+ if (rejectedSource) {
101
+ const sourceName = rejectedSource.bundleId;
102
+ const adapterId = rejectedSource.source.adapterId ?? "unassigned";
103
+ throw new UsageError(`Bundle "${sourceName}" uses adapter "${adapterId}", which does not support native workflow execution.`, "INVALID_FLAG_VALUE");
104
+ }
105
+ throw new NotFoundError(`Workflow not found for ref: ${ref}`);
106
+ }
107
+ const resolvedSourcePath = sourcePath;
108
+ // Canonicalize the stored ref: `workflows/foo.md` and `workflows/foo` resolve
109
+ // to the same file, so they MUST share one run identity.
110
+ const canonicalName = canonicalizeWorkflowName(workflowName);
111
+ const fullRef = workflowAdapterId === "akm-workflow"
112
+ ? makeBundleRef(sourceBundleId, canonicalName)
113
+ : canonicalWorkflowRunRef(sourceBundleId, canonicalName);
114
+ const cached = readWorkflowDocumentFromIndex(resolvedSourcePath, fullRef, workflowAdapterId);
86
115
  const document = cached ?? loadWorkflowDocumentFromDisk(assetPath);
87
- return projectAsset(document, fullRef, assetPath, resolvedSourcePath);
116
+ return projectAsset(document, fullRef, assetPath, resolvedSourcePath, workflowAdapterId, canonicalName);
117
+ }
118
+ function ownsNativeWorkflowRuntime(source) {
119
+ return source.adapterId === "akm" || source.adapterId === "akm-workflow";
120
+ }
121
+ function workflowNameFromConceptId(conceptId) {
122
+ const prefix = "workflows/";
123
+ return conceptId.startsWith(prefix) && conceptId.length > prefix.length ? conceptId.slice(prefix.length) : undefined;
124
+ }
125
+ function adapterOwnsConcept(sourcePath, adapterId, conceptId) {
126
+ const adapter = adapterForId(adapterId);
127
+ if (!adapter)
128
+ return false;
129
+ const normalized = conceptId.replaceAll("\\", "/");
130
+ if (!normalized ||
131
+ path.posix.isAbsolute(normalized) ||
132
+ normalized === ".." ||
133
+ normalized.startsWith("../") ||
134
+ path.posix.normalize(normalized) !== normalized) {
135
+ return false;
136
+ }
137
+ const extensions = [...adapter.extensions].sort((left, right) => right.length - left.length);
138
+ const extension = extensions.find((candidate) => normalized.toLowerCase().endsWith(candidate.toLowerCase()));
139
+ const extensionless = extension ? normalized.slice(0, -extension.length) : normalized;
140
+ const parent = path.join(sourcePath, path.posix.dirname(extensionless));
141
+ let realRoot;
142
+ let realParent;
143
+ try {
144
+ realRoot = fs.realpathSync(sourcePath);
145
+ realParent = fs.realpathSync(parent);
146
+ }
147
+ catch {
148
+ return false;
149
+ }
150
+ if (!isWithin(realParent, realRoot))
151
+ return false;
152
+ const basename = path.posix.basename(extensionless);
153
+ let entries;
154
+ try {
155
+ entries = fs.readdirSync(realParent, { withFileTypes: true });
156
+ }
157
+ catch {
158
+ return false;
159
+ }
160
+ for (const entry of entries) {
161
+ if (!entry.isFile())
162
+ continue;
163
+ const recognizedExtension = extensions.find((candidate) => entry.name.toLowerCase().endsWith(candidate.toLowerCase()) &&
164
+ entry.name.slice(0, -candidate.length) === basename);
165
+ if (!recognizedExtension)
166
+ continue;
167
+ const candidatePath = path.join(realParent, entry.name);
168
+ try {
169
+ const document = adapter.recognize({ id: adapterId, adapter: adapterId, root: realRoot, writable: false }, buildFileContext(realRoot, candidatePath));
170
+ if (document)
171
+ return true;
172
+ }
173
+ catch {
174
+ // A malformed matching file still belongs to the earlier adapter and cannot be bypassed for execution.
175
+ return true;
176
+ }
177
+ }
178
+ return false;
179
+ }
180
+ async function resolveNativeWorkflowPath(sourcePath, adapterId, name) {
181
+ if (adapterId !== "akm-workflow")
182
+ return resolveAssetPath(sourcePath, "workflow", name);
183
+ const canonicalName = canonicalizeWorkflowName(name);
184
+ let realRoot;
185
+ try {
186
+ realRoot = fs.realpathSync(sourcePath);
187
+ }
188
+ catch {
189
+ throw new NotFoundError(`Workflow bundle root not found: ${sourcePath}`);
190
+ }
191
+ const parent = path.join(sourcePath, path.dirname(canonicalName));
192
+ if (!isWithin(parent, realRoot)) {
193
+ throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
194
+ }
195
+ let entries;
196
+ try {
197
+ entries = fs.readdirSync(parent, { withFileTypes: true });
198
+ }
199
+ catch {
200
+ throw new NotFoundError(`Workflow not found: ${name}`);
201
+ }
202
+ const basename = path.basename(canonicalName);
203
+ for (const extension of WORKFLOW_EXTENSIONS) {
204
+ const matches = entries.filter((entry) => {
205
+ if (!entry.isFile() && !entry.isSymbolicLink())
206
+ return false;
207
+ const entryExtension = path.extname(entry.name);
208
+ return entryExtension.toLowerCase() === extension && entry.name.slice(0, -entryExtension.length) === basename;
209
+ });
210
+ if (matches.length > 1) {
211
+ throw new UsageError(`Workflow "${canonicalName}" has multiple ${extension} files that differ only by extension case.`, "RESOURCE_ALREADY_EXISTS");
212
+ }
213
+ const match = matches[0];
214
+ if (!match)
215
+ continue;
216
+ const candidate = path.join(parent, match.name);
217
+ let realTarget;
218
+ try {
219
+ if (!fs.statSync(candidate).isFile())
220
+ continue;
221
+ realTarget = fs.realpathSync(candidate);
222
+ }
223
+ catch {
224
+ continue;
225
+ }
226
+ if (!isWithin(realTarget, realRoot)) {
227
+ throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
228
+ }
229
+ return realTarget;
230
+ }
231
+ throw new NotFoundError(`Workflow not found: ${name}`);
88
232
  }
89
233
  /**
90
234
  * Resolve the `entries.id` for an indexed workflow, or null when the index
91
235
  * database does not yet exist or has no matching entry.
92
236
  */
93
- export function resolveWorkflowEntryId(sourcePath, ref) {
237
+ export function resolveWorkflowEntryId(sourcePath, ref, adapterId) {
94
238
  if (!fs.existsSync(getDbPath()))
95
239
  return null;
96
- const parsed = parseAssetRef(ref);
97
- const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
240
+ const entryKey = workflowEntryKey(sourcePath, ref, adapterId);
98
241
  return withIndexDb((db) => {
99
242
  const row = db
100
243
  .prepare(`SELECT id
@@ -106,14 +249,6 @@ export function resolveWorkflowEntryId(sourcePath, ref) {
106
249
  return row?.id ?? null;
107
250
  });
108
251
  }
109
- function loadWorkflowProgramFromDisk(assetPath) {
110
- const content = fs.readFileSync(assetPath, "utf8");
111
- const result = parseWorkflowProgram(content, { path: assetPath });
112
- if (!result.ok) {
113
- throw new UsageError(formatWorkflowErrors(assetPath, result.errors));
114
- }
115
- return result.program;
116
- }
117
252
  function loadWorkflowDocumentFromDisk(assetPath) {
118
253
  const content = fs.readFileSync(assetPath, "utf8");
119
254
  const result = parseWorkflow(content, { path: assetPath });
@@ -122,20 +257,19 @@ function loadWorkflowDocumentFromDisk(assetPath) {
122
257
  }
123
258
  return result.document;
124
259
  }
125
- function readWorkflowDocumentFromIndex(sourcePath, ref) {
260
+ function readWorkflowDocumentFromIndex(sourcePath, ref, adapterId) {
126
261
  if (!fs.existsSync(getDbPath()))
127
262
  return null;
128
- const parsed = parseAssetRef(ref);
129
- const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
263
+ const entryKey = workflowEntryKey(sourcePath, ref, adapterId);
130
264
  return withIndexDb((db) => {
131
265
  const row = db
132
- .prepare(`SELECT wd.document_json AS document_json
266
+ .prepare(`SELECT wd.document_json AS document_json, wd.schema_version AS schema_version
133
267
  FROM workflow_documents wd
134
268
  JOIN entries e ON e.id = wd.entry_id
135
269
  WHERE e.entry_type = 'workflow' AND e.entry_key = ?
136
270
  LIMIT 1`)
137
271
  .get(entryKey);
138
- if (!row)
272
+ if (!row || row.schema_version !== WORKFLOW_SCHEMA_VERSION)
139
273
  return null;
140
274
  try {
141
275
  return JSON.parse(row.document_json);
@@ -145,44 +279,48 @@ function readWorkflowDocumentFromIndex(sourcePath, ref) {
145
279
  }
146
280
  });
147
281
  }
148
- function projectAsset(doc, ref, assetPath, sourcePath) {
282
+ function workflowEntryKey(sourcePath, ref, adapterId) {
283
+ const bundleRef = parseBundleRef(ref);
284
+ if ((adapterId ?? detectAdapterId(sourcePath)) === "akm-workflow") {
285
+ return `${sourcePath}:concept:${bundleRef.conceptId}`;
286
+ }
287
+ const name = workflowNameFromConceptId(bundleRef.conceptId);
288
+ if (!name)
289
+ throw new UsageError(`Expected a workflow ref, got "${ref}".`);
290
+ return `${sourcePath}:workflow:${name}`;
291
+ }
292
+ function projectAsset(doc, ref, assetPath, sourcePath, adapterId, canonicalName) {
293
+ const title = canonicalName.split("/").pop() || canonicalName;
149
294
  return {
150
295
  ref,
151
296
  path: assetPath,
152
297
  sourcePath,
153
- title: doc.title,
154
- ...(doc.parameters
298
+ adapterId,
299
+ title,
300
+ ...(doc.params
155
301
  ? {
156
- parameters: doc.parameters.map((p) => ({
157
- name: p.name,
158
- ...(p.description ? { description: p.description } : {}),
159
- })),
302
+ parameters: Object.entries(doc.params).map(([name, schema]) => {
303
+ const description = schema.description;
304
+ return { name, ...(typeof description === "string" && description ? { description } : {}) };
305
+ }),
160
306
  }
161
307
  : {}),
162
308
  steps: doc.steps.map((s) => ({
163
309
  id: s.id,
164
- title: s.title,
165
- instructions: s.instructions.text,
166
- ...(s.completionCriteria ? { completionCriteria: s.completionCriteria.map((c) => c.text) } : {}),
310
+ title: s.id,
311
+ instructions: s.instructions?.text ?? stepFallbackInstructions(s),
312
+ ...(s.gateRubric?.text.trim() ? { completionCriteria: [s.gateRubric.text] } : {}),
167
313
  sequenceIndex: s.sequenceIndex,
168
314
  })),
169
315
  document: doc,
170
316
  };
171
317
  }
172
- /**
173
- * Project a parsed YAML program into the run-repository asset shape. Step
174
- * instructions carry the RAW `${{ … }}` templates — resolution happens in
175
- * the engine against the frozen plan, never here.
176
- */
177
- function projectProgramAsset(program, ref, assetPath, sourcePath) {
178
- const parameters = projectProgramParameters(program);
179
- return {
180
- ref,
181
- path: assetPath,
182
- sourcePath,
183
- title: program.name,
184
- ...(parameters ? { parameters } : {}),
185
- steps: projectProgramStepDefinitions(program),
186
- program,
187
- };
318
+ /** A route-only step with no body section still needs a non-empty spine instructions string. */
319
+ function stepFallbackInstructions(step) {
320
+ if (!step.route)
321
+ return "";
322
+ const branches = step.route.branches.map((b) => `"${b.match}" -> ${b.stepId}`);
323
+ if (step.route.defaultStepId !== undefined)
324
+ branches.push(`default -> ${step.route.defaultStepId}`);
325
+ return `Route on ${step.route.input}: ${branches.join(", ")}.`;
188
326
  }
@@ -1,14 +1,4 @@
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
- /**
5
- * Validated JSON shape for a workflow asset.
6
- *
7
- * `parseWorkflow` (parser.ts) converts a workflow markdown file into a
8
- * `WorkflowDocument` plus a list of `WorkflowError`s. The document is the
9
- * single source of truth consumed by the renderer, the indexer (cached
10
- * into `workflow_documents` in `index.db`), and the run engine. Source
11
- * markdown is referenced by `SourceRef` line spans so editors and agents
12
- * can rewrite content in place without a full re-parse.
13
- */
14
- export const WORKFLOW_SCHEMA_VERSION = 1;
4
+ export const WORKFLOW_SCHEMA_VERSION = 2;
@@ -11,16 +11,13 @@
11
11
  *
12
12
  * The LLM call is injected (`judge`) so the gate is unit-testable without a
13
13
  * live endpoint, and the whole gate is fail-open: when no criteria exist or no
14
- * judge is available the step completes as before. See
15
- * docs/technical/workflow-agent-checkin-adr.md.
14
+ * judge is available the step completes as before (per the workflow-agent
15
+ * check-in ADR).
16
16
  *
17
17
  * @module workflows/validate-summary
18
18
  */
19
19
  import validateSummaryJudgePrompt from "../assets/prompts/validate-summary-judge.md" with { type: "text" };
20
20
  import { parseJsonResponse } from "../core/parse.js";
21
- /** Feedback surfaced when a REQUIRED gate's judge could not be evaluated. */
22
- const REQUIRED_GATE_JUDGE_UNAVAILABLE_FEEDBACK = "The required completion gate could not be judged — the LLM threw, was unreachable, or returned an " +
23
- "unparseable verdict. A required gate must be judged; refusing to pass it. Restore the judge and re-evaluate.";
24
21
  const JUDGE_SYSTEM = validateSummaryJudgePrompt;
25
22
  function buildUserPrompt(input) {
26
23
  const criteria = input.completionCriteria.map((c, i) => `${i + 1}. ${c}`).join("\n");
@@ -39,22 +36,14 @@ function buildUserPrompt(input) {
39
36
  /**
40
37
  * Run the summary-validation gate.
41
38
  *
42
- * Fail-open contract (NON-required gates):
39
+ * Fail-open contract:
43
40
  * - no criteria → `{ complete: true, skipped: true }`
44
41
  * - no judge → `{ complete: true, skipped: true }`
45
42
  * - judge throws / returns unparseable → `{ complete: true, skipped: true }`
46
43
  *
47
- * REQUIRED gates (`opts.required`) do NOT fail open on an un-evaluable judge
48
- * (Codex round-3 finding A): a judge that throws / is unreachable, or returns an
49
- * unparseable / malformed verdict, yields `{ complete: false, errored: true }`
50
- * so the caller BLOCKS the step rather than silently passing an unjudged gate.
51
- * (A required gate with NO judge at all is blocked upstream in
52
- * `finalizeExecutedStep` before this gate runs, so that branch stays fail-open.)
53
- *
54
44
  * Only a well-formed `complete: false` verdict blocks completion.
55
45
  */
56
- export async function validateStepSummary(input, judge, opts) {
57
- const required = opts?.required === true;
46
+ export async function validateStepSummary(input, judge) {
58
47
  const criteria = input.completionCriteria.filter((c) => c.trim().length > 0);
59
48
  if (criteria.length === 0) {
60
49
  return { complete: true, missing: [], skipped: true };
@@ -67,21 +56,10 @@ export async function validateStepSummary(input, judge, opts) {
67
56
  raw = await judge({ system: JUDGE_SYSTEM, user: buildUserPrompt({ ...input, completionCriteria: criteria }) });
68
57
  }
69
58
  catch {
70
- // LLM unreachable / errored. A REQUIRED gate must be judged — block rather
71
- // than pass an unjudged gate; a non-required gate fails open so offline use
72
- // keeps working.
73
- if (required) {
74
- return { complete: false, missing: [], errored: true, feedback: REQUIRED_GATE_JUDGE_UNAVAILABLE_FEEDBACK };
75
- }
76
59
  return { complete: true, missing: [], skipped: true };
77
60
  }
78
61
  const parsed = parseJsonResponse(raw);
79
62
  if (!parsed || typeof parsed.complete !== "boolean") {
80
- // An unparseable / malformed verdict is a judge that did not actually judge:
81
- // a required gate blocks; a non-required gate fails open.
82
- if (required) {
83
- return { complete: false, missing: [], errored: true, feedback: REQUIRED_GATE_JUDGE_UNAVAILABLE_FEEDBACK };
84
- }
85
63
  return { complete: true, missing: [], skipped: true };
86
64
  }
87
65
  if (parsed.complete) {
@@ -1,44 +1,66 @@
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
- const STEP_ID_REGEX = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
5
- const ALLOWED_FRONTMATTER_KEYS = new Set(["description", "tags", "params", "name", "updated", "when_to_use"]);
4
+ /**
5
+ * Cross-cutting semantic checks over an assembled `WorkflowDocument` draft
6
+ * that need the whole document (not just one frontmatter key) at once.
7
+ *
8
+ * Per-key structural checks (unknown keys, id/param-name patterns, timeout
9
+ * format, retry taxonomy, route target ordering, duplicate ids, gate/body
10
+ * binding) all live in `parser.ts`, where line-anchored errors are cheapest to
11
+ * produce. The workflow-only closed frontmatter allowlist that used to live
12
+ * here (`ALLOWED_FRONTMATTER_KEYS`/`checkFrontmatterKeys`) is GONE —
13
+ * `schemas/akm-workflow.json` (`additionalProperties: false` over the shared
14
+ * asset envelope ∪ the workflow keys) is the closed-key authority now; this
15
+ * module only runs checks the schema cannot express (canonical xref shape,
16
+ * resource limits).
17
+ */
18
+ import { bundleRefToString, parseBundleRef } from "../core/asset/asset-ref.js";
19
+ import { utf8Bytes, WORKFLOW_MAX_INSTRUCTION_BYTES, WORKFLOW_MAX_PARAMS, WORKFLOW_MAX_STEPS } from "./resource-limits.js";
6
20
  export function runSemanticChecks(draft, frontmatterData, frontmatterEndLine, errors) {
7
- checkFrontmatterKeys(frontmatterData, frontmatterEndLine, errors);
8
- checkStepIdFormat(draft, errors);
9
- checkDuplicateStepIds(draft, errors);
21
+ checkXrefs(frontmatterData.xrefs, frontmatterEndLine, errors);
22
+ checkResourceLimits(draft, errors);
10
23
  }
11
- function checkFrontmatterKeys(data, fmEndLine, errors) {
12
- for (const key of Object.keys(data)) {
13
- if (ALLOWED_FRONTMATTER_KEYS.has(key))
14
- continue;
15
- errors.push({
16
- line: fmEndLine,
17
- message: `Workflow frontmatter "${key}" is not supported. Use only: description, tags, params, name, updated, when_to_use.`,
18
- });
24
+ function checkXrefs(value, line, errors) {
25
+ if (value === undefined)
26
+ return;
27
+ if (!Array.isArray(value))
28
+ return; // shape already flagged by parser.ts's checkXrefs
29
+ for (const ref of value) {
30
+ try {
31
+ if (typeof ref !== "string")
32
+ throw new Error("non-canonical ref");
33
+ const parsed = parseBundleRef(ref);
34
+ if (parsed.conceptId.includes(":") || ref !== bundleRefToString(parsed))
35
+ throw new Error("non-canonical ref");
36
+ }
37
+ catch {
38
+ errors.push({
39
+ line,
40
+ message: `Workflow frontmatter "xrefs" contains an invalid or non-canonical ref: ${String(ref)}.`,
41
+ });
42
+ }
19
43
  }
20
44
  }
21
- function checkStepIdFormat(draft, errors) {
22
- for (const step of draft.steps) {
23
- if (STEP_ID_REGEX.test(step.id))
24
- continue;
25
- errors.push({
26
- line: step.source.start,
27
- message: `Step ID "${step.id}" is invalid. Use letters, numbers, ".", "_" or "-" (e.g. "deploy-job").`,
28
- });
45
+ function checkResourceLimits(draft, errors) {
46
+ if (draft.steps.length > WORKFLOW_MAX_STEPS) {
47
+ errors.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_STEPS} steps.` });
48
+ }
49
+ if (Object.keys(draft.params ?? {}).length > WORKFLOW_MAX_PARAMS) {
50
+ errors.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_PARAMS} parameters.` });
29
51
  }
30
- }
31
- function checkDuplicateStepIds(draft, errors) {
32
- const firstSeenLine = new Map();
33
52
  for (const step of draft.steps) {
34
- const previous = firstSeenLine.get(step.id);
35
- if (previous !== undefined) {
53
+ if (step.instructions && utf8Bytes(step.instructions.text) > WORKFLOW_MAX_INSTRUCTION_BYTES) {
54
+ errors.push({
55
+ line: step.instructions.source.start,
56
+ message: `Step "${step.id}" instructions exceed the 256 KiB resource limit.`,
57
+ });
58
+ }
59
+ if (step.gateRubric && utf8Bytes(step.gateRubric.text) > WORKFLOW_MAX_INSTRUCTION_BYTES) {
36
60
  errors.push({
37
- line: step.source.start,
38
- message: `Step ID "${step.id}" is already used on line ${previous}. Step IDs must be unique within a workflow.`,
61
+ line: step.gateRubric.source.start,
62
+ message: `Step "${step.id}" gate rubric exceeds the 256 KiB resource limit.`,
39
63
  });
40
- continue;
41
64
  }
42
- firstSeenLine.set(step.id, step.source.start);
43
65
  }
44
66
  }