akm-cli 0.9.0-rc.0 → 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 (598) hide show
  1. package/CHANGELOG.md +1283 -22
  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/prompts/workflow-unit-preamble.md +26 -0
  26. package/dist/assets/stash-skeleton/README.md +38 -10
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  38. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  39. package/dist/assets/tasks/core/extract.yml +3 -2
  40. package/dist/assets/tasks/core/improve.yml +2 -1
  41. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  42. package/dist/assets/tasks/core/sync.yml +1 -0
  43. package/dist/assets/tasks/core/version-check.yml +2 -1
  44. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  45. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  46. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  48. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  49. package/dist/assets/templates/html/health.html +5 -4
  50. package/dist/assets/workflows/workflow-template.md +31 -15
  51. package/dist/cli/invocation.js +279 -0
  52. package/dist/cli/parse-args.js +5 -90
  53. package/dist/cli/retired-commands.js +78 -0
  54. package/dist/cli/shared.js +158 -48
  55. package/dist/cli-node.mjs +2 -1
  56. package/dist/cli.js +747 -293
  57. package/dist/commands/agent/agent-dispatch.js +19 -18
  58. package/dist/commands/agent/agent-support.js +0 -24
  59. package/dist/commands/agent/contribute-cli.js +43 -97
  60. package/dist/commands/completions.js +80 -23
  61. package/dist/commands/config-cli.js +44 -281
  62. package/dist/commands/env/env-binding.js +99 -0
  63. package/dist/commands/env/env-cli.js +84 -224
  64. package/dist/commands/env/env.js +12 -163
  65. package/dist/commands/env/marker-path.js +6 -0
  66. package/dist/commands/env/secret-cli.js +45 -61
  67. package/dist/commands/env/secret.js +32 -62
  68. package/dist/commands/feedback-cli.js +179 -85
  69. package/dist/commands/health/accept-rate.js +58 -0
  70. package/dist/commands/health/advisories.js +7 -8
  71. package/dist/commands/health/checks.js +279 -94
  72. package/dist/commands/health/html-report.js +197 -578
  73. package/dist/commands/health/improve-metrics.js +277 -246
  74. package/dist/commands/health/llm-usage.js +19 -19
  75. package/dist/commands/health/md-report.js +16 -7
  76. package/dist/commands/health/metrics.js +67 -32
  77. package/dist/commands/health/renderers.js +47 -0
  78. package/dist/commands/health/report-view-model.js +508 -0
  79. package/dist/commands/health/stash-exposure.js +1 -1
  80. package/dist/commands/health/surfaces.js +16 -56
  81. package/dist/commands/health/task-runs.js +3 -67
  82. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  83. package/dist/commands/health/types-improve.js +29 -0
  84. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  85. package/dist/commands/health/types-result.js +7 -0
  86. package/dist/commands/health/types-runs.js +4 -0
  87. package/dist/commands/health/types-session-log.js +4 -0
  88. package/dist/commands/health/types-windows.js +4 -0
  89. package/dist/commands/health/types.js +26 -21
  90. package/dist/commands/health/windows.js +2 -3
  91. package/dist/commands/health.js +296 -167
  92. package/dist/commands/improve/anti-collapse.js +5 -5
  93. package/dist/commands/improve/autonomy-gate.js +68 -0
  94. package/dist/commands/improve/collapse-detector.js +65 -52
  95. package/dist/commands/improve/consolidate/chunking.js +9 -7
  96. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  97. package/dist/commands/improve/consolidate/merge.js +4 -0
  98. package/dist/commands/improve/consolidate.js +454 -1354
  99. package/dist/commands/improve/content-hash.js +39 -0
  100. package/dist/commands/improve/distill/content-repair.js +4 -10
  101. package/dist/commands/improve/distill/promote-memory.js +89 -64
  102. package/dist/commands/improve/distill/quality-gate.js +118 -42
  103. package/dist/commands/improve/distill-guards.js +1 -1
  104. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  105. package/dist/commands/improve/distill.js +607 -363
  106. package/dist/commands/improve/eligibility.js +165 -79
  107. package/dist/commands/improve/extract-cli.js +35 -126
  108. package/dist/commands/improve/extract-prompt.js +6 -35
  109. package/dist/commands/improve/extract.js +640 -391
  110. package/dist/commands/improve/feedback-valence.js +2 -12
  111. package/dist/commands/improve/improve-cli.js +134 -135
  112. package/dist/commands/improve/improve-result-file.js +30 -50
  113. package/dist/commands/improve/improve-run-types.js +4 -0
  114. package/dist/commands/improve/improve-strategies.js +135 -0
  115. package/dist/commands/improve/improve.js +904 -701
  116. package/dist/commands/improve/locks.js +64 -111
  117. package/dist/commands/improve/loop-stages.js +1110 -923
  118. package/dist/commands/improve/memory/derived-ref.js +124 -0
  119. package/dist/commands/improve/memory/memory-belief.js +79 -7
  120. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  121. package/dist/commands/improve/memory/memory-improve.js +25 -37
  122. package/dist/commands/improve/outcome-loop.js +25 -88
  123. package/dist/commands/improve/preparation.js +1034 -813
  124. package/dist/commands/improve/proactive-maintenance.js +34 -9
  125. package/dist/commands/improve/proposal-envelope.js +31 -0
  126. package/dist/commands/improve/reflect.js +983 -794
  127. package/dist/commands/improve/run-context.js +119 -0
  128. package/dist/commands/improve/salience.js +24 -127
  129. package/dist/commands/improve/session-asset.js +7 -3
  130. package/dist/commands/improve/shared.js +14 -34
  131. package/dist/commands/improve/source-identity.js +28 -0
  132. package/dist/commands/improve/triage.js +20 -17
  133. package/dist/commands/lint/base-linter.js +340 -313
  134. package/dist/commands/lint/env-key-rules.js +31 -47
  135. package/dist/commands/lint/index.js +185 -30
  136. package/dist/commands/{events.js → log.js} +28 -38
  137. package/dist/commands/migrate-cli.js +54 -0
  138. package/dist/commands/migration-tool.js +55 -0
  139. package/dist/commands/observability-cli.js +70 -208
  140. package/dist/commands/proposal/diff-format.js +50 -0
  141. package/dist/commands/proposal/drain-policies.js +0 -6
  142. package/dist/commands/proposal/drain.js +91 -40
  143. package/dist/commands/proposal/proposal-cli.js +134 -132
  144. package/dist/commands/proposal/proposal-types.js +56 -0
  145. package/dist/commands/proposal/proposal.js +83 -65
  146. package/dist/commands/proposal/propose-cli.js +88 -0
  147. package/dist/commands/proposal/propose.js +105 -88
  148. package/dist/commands/proposal/repository.js +1303 -278
  149. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  150. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  151. package/dist/commands/proposal/validators/proposals.js +6 -8
  152. package/dist/commands/read/curate.js +78 -73
  153. package/dist/commands/read/knowledge.js +510 -13
  154. package/dist/commands/read/registry-search.js +2 -2
  155. package/dist/commands/read/remember-cli.js +84 -15
  156. package/dist/commands/read/search-cli.js +203 -96
  157. package/dist/commands/read/search.js +126 -94
  158. package/dist/commands/read/show.js +226 -250
  159. package/dist/commands/registry-cli.js +34 -60
  160. package/dist/commands/remember.js +18 -57
  161. package/dist/commands/sources/add-cli.js +104 -49
  162. package/dist/commands/sources/bundle-cli.js +166 -0
  163. package/dist/commands/sources/bundle-config-ops.js +63 -0
  164. package/dist/commands/sources/info.js +27 -15
  165. package/dist/commands/sources/init.js +30 -40
  166. package/dist/commands/sources/installed-stashes.js +469 -172
  167. package/dist/commands/sources/migration-help.js +7 -4
  168. package/dist/commands/sources/schema-repair.js +10 -9
  169. package/dist/commands/sources/self-update.js +182 -121
  170. package/dist/commands/sources/source-add.js +169 -178
  171. package/dist/commands/sources/source-clone.js +144 -41
  172. package/dist/commands/sources/source-manage.js +94 -59
  173. package/dist/commands/sources/sources-cli.js +64 -205
  174. package/dist/commands/sources/stash-cli.js +91 -54
  175. package/dist/commands/sources/stash-skeleton.js +1 -1
  176. package/dist/commands/tasks/tasks-cli.js +106 -104
  177. package/dist/commands/tasks/tasks.js +445 -262
  178. package/dist/commands/workflow-cli.js +232 -121
  179. package/dist/core/action-contributors.js +1 -1
  180. package/dist/core/activation-policy.js +49 -0
  181. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  182. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  183. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  184. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  185. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  186. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  187. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  188. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  189. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  190. package/dist/core/adapter/adapters/index.js +80 -0
  191. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  192. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  193. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  194. package/dist/core/adapter/adapters/shared.js +286 -0
  195. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  196. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  197. package/dist/core/adapter/bundle-adapter.js +4 -0
  198. package/dist/core/adapter/detect-adapter.js +17 -0
  199. package/dist/core/adapter/recognize-match.js +44 -0
  200. package/dist/core/adapter/registry.js +56 -0
  201. package/dist/core/adapter/types.js +4 -0
  202. package/dist/core/asset/akm-markdown.js +30 -0
  203. package/dist/core/asset/asset-placement.js +243 -0
  204. package/dist/core/asset/asset-ref.js +110 -79
  205. package/dist/core/asset/asset-serialize.js +20 -0
  206. package/dist/core/asset/frontmatter.js +28 -12
  207. package/dist/core/asset/markdown.js +40 -51
  208. package/dist/core/asset/resolve-ref.js +274 -0
  209. package/dist/core/asset/stash-meta.js +2 -2
  210. package/dist/core/bundle-id.js +51 -0
  211. package/dist/core/common.js +281 -86
  212. package/dist/core/config/config-io.js +42 -128
  213. package/dist/core/config/config-schema.js +233 -834
  214. package/dist/core/config/config-sources.js +162 -39
  215. package/dist/core/config/config-types.js +16 -11
  216. package/dist/core/config/config-version.js +29 -0
  217. package/dist/core/config/config-walker.js +126 -37
  218. package/dist/core/config/config.js +154 -331
  219. package/dist/core/config/deep-merge.js +41 -0
  220. package/dist/core/config/engine-semantics.js +28 -0
  221. package/dist/core/config/experimental.js +21 -0
  222. package/dist/core/config/schema/embedding.js +38 -0
  223. package/dist/core/config/schema/engines.js +116 -0
  224. package/dist/core/config/schema/experimental.js +47 -0
  225. package/dist/core/config/schema/feedback.js +31 -0
  226. package/dist/core/config/schema/improve-processes.js +389 -0
  227. package/dist/core/config/schema/improve.js +94 -0
  228. package/dist/core/config/schema/index-config.js +176 -0
  229. package/dist/core/config/schema/output.js +18 -0
  230. package/dist/core/config/schema/primitives.js +94 -0
  231. package/dist/core/config/schema/search.js +30 -0
  232. package/dist/core/config/schema/setup.js +18 -0
  233. package/dist/core/config/schema/sources-bundles.js +169 -0
  234. package/dist/core/config/schema/workflow.js +29 -0
  235. package/dist/core/env-secret-ref.js +155 -20
  236. package/dist/core/errors.js +17 -15
  237. package/dist/core/events-types.js +4 -0
  238. package/dist/core/events.js +46 -128
  239. package/dist/core/extra-params.js +62 -0
  240. package/dist/core/file-change.js +17 -0
  241. package/dist/core/file-lock.js +202 -57
  242. package/dist/core/fs-txn.js +392 -0
  243. package/dist/core/git-message.js +59 -0
  244. package/dist/core/improve-result.js +167 -0
  245. package/dist/core/json-schema.js +142 -0
  246. package/dist/core/lesson-lint.js +1 -17
  247. package/dist/core/logs-db.js +1 -1
  248. package/dist/core/maintenance-barrier.js +135 -0
  249. package/dist/core/migration-operation.js +44 -0
  250. package/dist/core/mutation-target.js +78 -0
  251. package/dist/core/paths.js +22 -25
  252. package/dist/core/platform.js +10 -0
  253. package/dist/core/recognition-util.js +128 -0
  254. package/dist/core/redaction.js +392 -0
  255. package/dist/core/standards/resolve-standards-context.js +36 -65
  256. package/dist/core/standards/resolve-stash-standards.js +2 -2
  257. package/dist/core/standards/resolve-type-conventions.js +5 -5
  258. package/dist/core/state/migrations.js +242 -11
  259. package/dist/core/state-db.js +98 -10
  260. package/dist/core/structured.js +1 -1
  261. package/dist/core/subprocess.js +303 -0
  262. package/dist/core/text-truncation.js +9 -5
  263. package/dist/core/time.js +20 -0
  264. package/dist/core/type-presentation.js +130 -0
  265. package/dist/core/warn.js +0 -3
  266. package/dist/core/write-source.js +834 -118
  267. package/dist/indexer/bundle-identity-guard.js +92 -0
  268. package/dist/indexer/db/graph-db.js +1 -25
  269. package/dist/indexer/db/llm-cache.js +1 -1
  270. package/dist/indexer/ensure-index.js +30 -9
  271. package/dist/indexer/graph/graph-boost.js +9 -30
  272. package/dist/indexer/graph/graph-extraction.js +41 -27
  273. package/dist/indexer/graph/graph-types.js +4 -0
  274. package/dist/indexer/index-writer-lock.js +93 -49
  275. package/dist/indexer/index-written-assets.js +100 -53
  276. package/dist/indexer/indexer.js +746 -329
  277. package/dist/indexer/init.js +18 -25
  278. package/dist/indexer/installations.js +142 -0
  279. package/dist/indexer/passes/dir-staleness.js +18 -10
  280. package/dist/indexer/passes/memory-inference.js +25 -15
  281. package/dist/indexer/passes/metadata.js +412 -243
  282. package/dist/indexer/scan/doc-to-entry.js +160 -0
  283. package/dist/indexer/scan/drain-dir.js +134 -0
  284. package/dist/indexer/search/db-search.js +292 -108
  285. package/dist/indexer/search/fts-query.js +64 -0
  286. package/dist/indexer/search/ranking-contributors.js +145 -25
  287. package/dist/indexer/search/ranking-types.js +4 -0
  288. package/dist/indexer/search/ranking.js +28 -71
  289. package/dist/indexer/search/search-attribution.js +67 -0
  290. package/dist/indexer/search/search-fields.js +18 -3
  291. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  292. package/dist/indexer/search/search-source.js +157 -111
  293. package/dist/indexer/search/semantic-status.js +4 -1
  294. package/dist/indexer/usage/usage-events.js +10 -30
  295. package/dist/indexer/walk/file-context.js +3 -45
  296. package/dist/indexer/walk/matchers.js +42 -34
  297. package/dist/indexer/walk/path-resolver.js +11 -5
  298. package/dist/indexer/walk/walker.js +42 -14
  299. package/dist/integrations/agent/builder-shared.js +7 -0
  300. package/dist/integrations/agent/builders.js +5 -56
  301. package/dist/integrations/agent/config.js +3 -143
  302. package/dist/integrations/agent/detect.js +17 -2
  303. package/dist/integrations/agent/engine-resolution.js +231 -0
  304. package/dist/integrations/agent/index.js +1 -2
  305. package/dist/integrations/agent/model-aliases.js +16 -2
  306. package/dist/integrations/agent/profiles.js +36 -62
  307. package/dist/integrations/agent/prompts.js +46 -18
  308. package/dist/integrations/agent/runner-dispatch.js +93 -4
  309. package/dist/integrations/agent/runner.js +76 -208
  310. package/dist/integrations/agent/spawn.js +88 -196
  311. package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
  312. package/dist/integrations/harnesses/aider/index.js +48 -0
  313. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  314. package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
  315. package/dist/integrations/harnesses/amazonq/index.js +45 -0
  316. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  317. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  318. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  319. package/dist/integrations/harnesses/claude/index.js +24 -35
  320. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  321. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  322. package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
  323. package/dist/integrations/harnesses/codex/index.js +52 -0
  324. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  325. package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
  326. package/dist/integrations/harnesses/copilot/index.js +48 -0
  327. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  328. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  329. package/dist/integrations/harnesses/gemini/index.js +48 -0
  330. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  331. package/dist/integrations/harnesses/ids.js +24 -0
  332. package/dist/integrations/harnesses/index.js +54 -34
  333. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  334. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  335. package/dist/integrations/harnesses/opencode/index.js +14 -32
  336. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  337. package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
  338. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  339. package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
  340. package/dist/integrations/harnesses/openhands/index.js +48 -0
  341. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  342. package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
  343. package/dist/integrations/harnesses/pi/index.js +45 -0
  344. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  345. package/dist/integrations/harnesses/shared.js +17 -0
  346. package/dist/integrations/harnesses/types.js +43 -32
  347. package/dist/integrations/lockfile.js +211 -24
  348. package/dist/integrations/session-logs/index.js +36 -39
  349. package/dist/integrations/session-logs/provider-base.js +113 -0
  350. package/dist/llm/client.js +182 -110
  351. package/dist/llm/embedders/deterministic.js +2 -2
  352. package/dist/llm/embedders/remote.js +21 -9
  353. package/dist/llm/feature-gate.js +17 -57
  354. package/dist/llm/graph-extract.js +12 -13
  355. package/dist/llm/index-passes.js +8 -42
  356. package/dist/llm/memory-infer.js +144 -1
  357. package/dist/llm/metadata-enhance.js +45 -30
  358. package/dist/llm/structured-call.js +16 -8
  359. package/dist/llm/usage-persist.js +30 -5
  360. package/dist/llm/usage-telemetry.js +59 -6
  361. package/dist/output/cli-hints.js +1 -2
  362. package/dist/output/command-registry.js +27 -0
  363. package/dist/output/context.js +22 -7
  364. package/dist/output/format-exempt.js +80 -0
  365. package/dist/output/generic-render.js +251 -0
  366. package/dist/output/html-render.js +11 -16
  367. package/dist/output/render-registry.js +57 -0
  368. package/dist/output/renderers.js +14 -279
  369. package/dist/output/shapes/curate.js +10 -1
  370. package/dist/output/shapes/events.js +12 -7
  371. package/dist/output/shapes/helpers.js +58 -84
  372. package/dist/output/shapes/passthrough.js +11 -39
  373. package/dist/output/shapes/proposal/producer.js +15 -7
  374. package/dist/output/shapes/registry.js +12 -6
  375. package/dist/output/shapes.js +0 -9
  376. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  377. package/dist/output/text/bundle-show.js +7 -0
  378. package/dist/output/text/command-format.js +562 -0
  379. package/dist/output/text/env.js +1 -3
  380. package/dist/output/text/events.js +8 -7
  381. package/dist/output/text/helpers.js +15 -1164
  382. package/dist/output/text/proposal/producer.js +4 -2
  383. package/dist/output/text/proposal-format.js +202 -0
  384. package/dist/output/text/registry-commands.js +1 -2
  385. package/dist/output/text/registry.js +12 -6
  386. package/dist/output/text/show-directives.js +117 -0
  387. package/dist/output/text/show-format.js +103 -0
  388. package/dist/output/text/sync.js +5 -0
  389. package/dist/output/text/workflow-format.js +332 -0
  390. package/dist/output/text/workflow.js +3 -2
  391. package/dist/output/text.js +10 -19
  392. package/dist/registry/factory.js +4 -6
  393. package/dist/registry/origin-resolve.js +16 -27
  394. package/dist/registry/providers/skills-sh.js +3 -3
  395. package/dist/registry/providers/static-index.js +15 -25
  396. package/dist/registry/resolve.js +43 -94
  397. package/dist/registry/semver.js +43 -0
  398. package/dist/runtime.js +81 -12
  399. package/dist/scripts/akm-migrate.js +35529 -0
  400. package/dist/setup/detect.js +5 -7
  401. package/dist/setup/detected-engines.js +136 -0
  402. package/dist/setup/engine-config.js +100 -0
  403. package/dist/setup/registry-stash-loader.js +3 -3
  404. package/dist/setup/semantic-assets.js +12 -9
  405. package/dist/setup/setup.js +444 -208
  406. package/dist/setup/steps/connection-shared.js +120 -0
  407. package/dist/setup/steps/connection.js +108 -305
  408. package/dist/setup/steps/platforms.js +13 -12
  409. package/dist/setup/steps/semantic.js +15 -3
  410. package/dist/setup/steps/sources.js +21 -15
  411. package/dist/setup/steps/stashdir.js +6 -4
  412. package/dist/setup/steps/tasks.js +236 -119
  413. package/dist/setup/steps.js +3 -2
  414. package/dist/sources/freshness.js +39 -0
  415. package/dist/sources/provider-factory.js +11 -17
  416. package/dist/sources/providers/filesystem.js +2 -3
  417. package/dist/sources/providers/git-install.js +278 -34
  418. package/dist/sources/providers/git-provider.js +54 -56
  419. package/dist/sources/providers/git-stash.js +420 -91
  420. package/dist/sources/providers/git.js +2 -2
  421. package/dist/sources/providers/npm.js +16 -19
  422. package/dist/sources/providers/provider-utils.js +47 -22
  423. package/dist/sources/providers/sync-from-ref.js +3 -9
  424. package/dist/sources/providers/website.js +2 -2
  425. package/dist/sources/resolve.js +11 -10
  426. package/dist/sources/snapshot-fetchers/types.js +4 -0
  427. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  428. package/dist/storage/database.js +60 -4
  429. package/dist/storage/engines/sqlite-migrations.js +156 -5
  430. package/dist/storage/locations.js +1 -2
  431. package/dist/storage/repositories/canaries-repository.js +1 -1
  432. package/dist/storage/repositories/events-repository.js +51 -11
  433. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  434. package/dist/storage/repositories/index-connection.js +79 -0
  435. package/dist/storage/repositories/index-db.js +4 -3
  436. package/dist/storage/repositories/index-entries-repository.js +863 -0
  437. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  438. package/dist/storage/repositories/index-entry-types.js +4 -0
  439. package/dist/storage/repositories/index-fts-repository.js +167 -0
  440. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  441. package/dist/storage/repositories/index-meta-repository.js +49 -0
  442. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  443. package/dist/storage/repositories/index-sql.js +12 -0
  444. package/dist/storage/repositories/index-utility-repository.js +356 -0
  445. package/dist/storage/repositories/index-vec-repository.js +250 -0
  446. package/dist/storage/repositories/outcome-repository.js +119 -0
  447. package/dist/storage/repositories/proposals-repository.js +317 -75
  448. package/dist/storage/repositories/registry-cache.js +1 -1
  449. package/dist/storage/repositories/salience-repository.js +172 -0
  450. package/dist/storage/repositories/task-history-repository.js +110 -3
  451. package/dist/storage/repositories/workflow-runs-repository.js +240 -19
  452. package/dist/tasks/backends/cron.js +169 -46
  453. package/dist/tasks/backends/exec-utils.js +76 -3
  454. package/dist/tasks/backends/index.js +6 -9
  455. package/dist/tasks/backends/launchd.js +292 -55
  456. package/dist/tasks/backends/schtasks.js +557 -70
  457. package/dist/tasks/backends/types.js +4 -0
  458. package/dist/tasks/command-executable.js +93 -0
  459. package/dist/tasks/embedded.js +56 -38
  460. package/dist/tasks/parser.js +156 -64
  461. package/dist/tasks/resolve-akm-bin.js +144 -51
  462. package/dist/tasks/runner.js +377 -209
  463. package/dist/tasks/schedule.js +108 -19
  464. package/dist/tasks/scheduler-invocation.js +296 -0
  465. package/dist/tasks/schema.js +1 -1
  466. package/dist/tasks/task-id.js +35 -0
  467. package/dist/tasks/validator.js +30 -16
  468. package/dist/text-import-hook.mjs +1 -1
  469. package/dist/workflows/authoring/authoring.js +104 -43
  470. package/dist/workflows/authoring/scope-key.js +1 -1
  471. package/dist/workflows/cli.js +0 -16
  472. package/dist/workflows/concurrency-policy.js +15 -0
  473. package/dist/workflows/exec/brief.js +450 -0
  474. package/dist/workflows/exec/frozen-judge.js +47 -0
  475. package/dist/workflows/exec/native-executor.js +1038 -0
  476. package/dist/workflows/exec/param-secrets.js +115 -0
  477. package/dist/workflows/exec/report.js +1460 -0
  478. package/dist/workflows/exec/run-workflow.js +602 -0
  479. package/dist/workflows/exec/scheduler.js +71 -0
  480. package/dist/workflows/exec/step-work.js +1190 -0
  481. package/dist/workflows/exec/unit-writer.js +23 -0
  482. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  483. package/dist/workflows/exec/worktree.js +171 -0
  484. package/dist/workflows/ir/compile.js +246 -0
  485. package/dist/workflows/ir/freeze.js +233 -0
  486. package/dist/workflows/ir/params.js +54 -0
  487. package/dist/workflows/ir/plan-hash.js +68 -0
  488. package/dist/workflows/ir/schema.js +540 -0
  489. package/dist/workflows/parser.js +878 -304
  490. package/dist/workflows/program/expressions.js +181 -0
  491. package/dist/workflows/program/schema.js +51 -0
  492. package/dist/workflows/renderer.js +100 -45
  493. package/dist/workflows/resource-limits.js +22 -0
  494. package/dist/workflows/runtime/agent-identity.js +59 -14
  495. package/dist/workflows/runtime/checkin.js +1 -1
  496. package/dist/workflows/runtime/plan-classifier.js +131 -0
  497. package/dist/workflows/runtime/runs.js +376 -119
  498. package/dist/workflows/runtime/unit-checkin.js +45 -0
  499. package/dist/workflows/runtime/unit-phases.js +20 -0
  500. package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
  501. package/dist/workflows/schema.js +1 -11
  502. package/dist/workflows/validate-summary.js +2 -3
  503. package/dist/workflows/validator.js +52 -30
  504. package/docs/README.md +42 -78
  505. package/docs/migration/README.md +8 -0
  506. package/docs/migration/release-notes/0.6.0.md +1 -1
  507. package/docs/migration/release-notes/0.7.0.md +9 -8
  508. package/docs/migration/release-notes/0.9.0.md +158 -14
  509. package/docs/migration/v0.7-to-v0.8.md +46 -47
  510. package/docs/migration/v0.8-to-v0.9.md +844 -0
  511. package/docs/reference/README.md +12 -0
  512. package/docs/reference/data-and-telemetry.md +333 -0
  513. package/package.json +21 -17
  514. package/schemas/akm-asset-envelope.json +93 -0
  515. package/schemas/akm-config.json +4636 -0
  516. package/schemas/akm-task.json +87 -0
  517. package/schemas/akm-workflow.json +373 -0
  518. package/dist/akm-migrate-storage +0 -38
  519. package/dist/assets/help/help-accept.md +0 -12
  520. package/dist/assets/help/help-improve.md +0 -84
  521. package/dist/assets/help/help-proposals.md +0 -17
  522. package/dist/assets/help/help-propose.md +0 -17
  523. package/dist/assets/help/help-reject.md +0 -11
  524. package/dist/assets/profiles/frequent.json +0 -13
  525. package/dist/assets/profiles/recombine-only.json +0 -21
  526. package/dist/assets/profiles/reflect-distill.json +0 -30
  527. package/dist/assets/profiles/synthesize.json +0 -15
  528. package/dist/assets/prompts/procedural-system.md +0 -44
  529. package/dist/assets/prompts/recombine-system.md +0 -40
  530. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  531. package/dist/assets/tasks/core/backup.yml +0 -4
  532. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  533. package/dist/assets/templates/html/default.html +0 -78
  534. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  535. package/dist/assets/wiki/index-template.md +0 -12
  536. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  537. package/dist/assets/wiki/log-template.md +0 -8
  538. package/dist/assets/wiki/schema-template.md +0 -61
  539. package/dist/cli/config-migrate.js +0 -150
  540. package/dist/cli/config-validate.js +0 -39
  541. package/dist/commands/graph/graph-cli.js +0 -124
  542. package/dist/commands/graph/graph.js +0 -487
  543. package/dist/commands/improve/calibration.js +0 -161
  544. package/dist/commands/improve/dedup.js +0 -482
  545. package/dist/commands/improve/extract-watch.js +0 -140
  546. package/dist/commands/improve/hot-probation.js +0 -45
  547. package/dist/commands/improve/improve-auto-accept.js +0 -276
  548. package/dist/commands/improve/improve-profiles.js +0 -168
  549. package/dist/commands/improve/procedural.js +0 -398
  550. package/dist/commands/improve/recombine.js +0 -818
  551. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  552. package/dist/commands/lint/agent-linter.js +0 -44
  553. package/dist/commands/lint/command-linter.js +0 -44
  554. package/dist/commands/lint/default-linter.js +0 -16
  555. package/dist/commands/lint/fact-linter.js +0 -39
  556. package/dist/commands/lint/knowledge-linter.js +0 -16
  557. package/dist/commands/lint/memory-linter.js +0 -61
  558. package/dist/commands/lint/registry.js +0 -41
  559. package/dist/commands/lint/skill-linter.js +0 -45
  560. package/dist/commands/lint/task-linter.js +0 -50
  561. package/dist/commands/lint/workflow-linter.js +0 -81
  562. package/dist/commands/proposal/legacy-import.js +0 -115
  563. package/dist/commands/sources/history.js +0 -196
  564. package/dist/commands/tasks/default-tasks.js +0 -186
  565. package/dist/commands/wiki-cli.js +0 -292
  566. package/dist/core/asset/asset-registry.js +0 -76
  567. package/dist/core/asset/asset-spec.js +0 -259
  568. package/dist/core/config/config-migration.js +0 -602
  569. package/dist/core/deep-merge.js +0 -38
  570. package/dist/core/eval/rank-metrics.js +0 -113
  571. package/dist/core/ripgrep/install.js +0 -163
  572. package/dist/core/ripgrep/resolve.js +0 -81
  573. package/dist/indexer/db/db.js +0 -1413
  574. package/dist/indexer/manifest.js +0 -170
  575. package/dist/indexer/passes/metadata-contributors.js +0 -31
  576. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  577. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
  578. package/dist/llm/call-ai.js +0 -62
  579. package/dist/llm/memory-infer-impl.js +0 -138
  580. package/dist/output/shapes/distill.js +0 -14
  581. package/dist/output/shapes/history.js +0 -11
  582. package/dist/output/text/distill.js +0 -6
  583. package/dist/output/text/enable-disable.js +0 -8
  584. package/dist/output/text/history.js +0 -6
  585. package/dist/output/text/wiki.js +0 -16
  586. package/dist/registry/build-index.js +0 -386
  587. package/dist/scripts/migrate-storage.js +0 -19108
  588. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
  589. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  590. package/dist/setup/legacy-config.js +0 -106
  591. package/dist/storage/repositories/consolidation-repository.js +0 -38
  592. package/dist/storage/repositories/recombine-repository.js +0 -213
  593. package/dist/wiki/wiki-templates.js +0 -15
  594. package/dist/wiki/wiki.js +0 -1012
  595. package/dist/workflows/db.js +0 -215
  596. package/docs/data-and-telemetry.md +0 -226
  597. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  598. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -0,0 +1,450 @@
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
+ * `akm workflow brief <run>` — the read-only half of the harness-neutral driver
6
+ * protocol (redesign addendum R3). It tells ANY agent session (Claude Code,
7
+ * opencode, Codex, a human at a shell) exactly what units the native engine
8
+ * would dispatch for a run's active step, and how to report the results back
9
+ * through `akm workflow report` (the mutating half, R3 step 3).
10
+ *
11
+ * ## Read-only, no lease, no dispatch, no mutation
12
+ *
13
+ * `brief` computes; it never writes. It takes no engine lease, dispatches no
14
+ * units, and never advances the gate spine. The only database access is
15
+ * SELECTs (`getNextWorkflowStep` + the run row + the unit journal). A test
16
+ * proves the workflow.db file is byte-identical before and after a `brief`.
17
+ *
18
+ * ## No duplicated semantics (the cardinal rule)
19
+ *
20
+ * The expected work-list is computed by the SAME shared functions the engine
21
+ * uses (`step-work.ts`): {@link computeStepWorkList} for item resolution +
22
+ * content-derived unit ids + input hashes + prompt assembly,
23
+ * {@link activeGateLoop} / {@link recoverGateFeedback} to recover the gate-loop
24
+ * number and the judge feedback the engine threads into loop-N prompts (so a
25
+ * loop-2 brief's unit ids/hashes equal what the engine would compute),
26
+ * {@link stepOutputsFromEvidence} for the expression scope, and
27
+ * {@link evaluateRoute} for the deterministic route decision. Because both
28
+ * surfaces call one implementation, an engine-driven run and a brief/report
29
+ * driven run of the same frozen plan produce byte-identical unit graphs — the
30
+ * invariant R4 asserts.
31
+ */
32
+ import { UsageError } from "../../core/errors.js";
33
+ import { assertRunParamsSatisfyPlan } from "../ir/params.js";
34
+ import { frozenStepRows, requireExecutableWorkflowPlan } from "../runtime/plan-classifier.js";
35
+ import { resolveExistingWorkflowRunId, snapshotRunForDriver } from "../runtime/runs.js";
36
+ import { evaluateStaleUnits } from "../runtime/unit-checkin.js";
37
+ import { GATE_EVALUATION_PHASE } from "../runtime/unit-phases.js";
38
+ import { detectSecretShapedParams } from "./param-secrets.js";
39
+ import { activeGateLoop, assertJournaledRouteSelectionsValid, computeStepWorkList, evaluateRoute, isWorkListFullyTerminal, recoverGateFeedback, selectUnitAttemptRow, stepOutputsFromEvidence, } from "./step-work.js";
40
+ const EMPTY_WORK_LIST = { isFanOut: false, reducer: null, itemCount: 0, units: [] };
41
+ // ── Entry point ──────────────────────────────────────────────────────────────
42
+ /**
43
+ * Build the read-only brief for a run. `target` is a run id (preferred) or a
44
+ * workflow ref that ALREADY has an active run in the current scope — brief
45
+ * never auto-starts a run (that would mutate), so a ref with no active run is a
46
+ * NotFoundError, not a silent start.
47
+ */
48
+ export async function buildWorkflowBrief(target) {
49
+ const runId = await resolveRunId(target);
50
+ // Read-only spine walk. #14: read the run row, its steps, AND its unit journal
51
+ // in ONE transaction so a concurrent report/run/manual completion cannot change
52
+ // the active step between the spine read and the unit-journal read. A bare run
53
+ // id never auto-starts (we resolved to a concrete id above).
54
+ const { next, run: runRow, units } = await snapshotRunForDriver(runId);
55
+ const leaseHolder = runRow.engine_lease_holder;
56
+ const leaseUntil = runRow.engine_lease_until;
57
+ const run = {
58
+ id: next.run.id,
59
+ workflowRef: next.run.workflowRef,
60
+ workflowTitle: next.run.workflowTitle,
61
+ status: next.run.status,
62
+ currentStepId: next.run.currentStepId ?? null,
63
+ params: next.run.params ?? {},
64
+ };
65
+ const warnings = [];
66
+ // #13: params are declared NON-SECRET. They are interpolated into every unit
67
+ // prompt AND hashed into the unit identity, so `brief` cannot redact them
68
+ // without breaking the byte-identical-prompt contract a driver executes
69
+ // against. Surface the standing advisory (whenever the run carries params) plus
70
+ // any best-effort secret-shaped-value hits, so an author moves credentials to
71
+ // an env binding (which `brief` only ever names).
72
+ if (Object.keys(run.params).length > 0) {
73
+ warnings.push("Workflow params are copied verbatim into every unit prompt shown to any driver and are hashed into the unit " +
74
+ "identity — they are NOT secret. Never put credentials in params; put secrets in env bindings (`env:` refs), " +
75
+ "which `brief` surfaces by name only and never resolves.");
76
+ }
77
+ warnings.push(...detectSecretShapedParams(run.params));
78
+ const lease = buildLease(leaseHolder, leaseUntil);
79
+ if (lease?.live) {
80
+ warnings.push(`Engine ${lease.holder} holds a LIVE run lease (expires ${lease.until}). This run is being driven by the ` +
81
+ `native engine right now — \`akm workflow report\` is REFUSED while the lease is live. Do NOT execute these ` +
82
+ `units; wait for the engine to finish or for the lease to expire.`);
83
+ }
84
+ // Stale claimed units (pure timestamp evaluation): a driver claimed these via
85
+ // `report --status running` but has not heartbeated within the window — flag
86
+ // them so another driver can reclaim the abandoned work.
87
+ const staleUnits = evaluateStaleUnits(units);
88
+ if (staleUnits.length > 0) {
89
+ warnings.push(`${staleUnits.length} unit(s) were claimed with \`report --status running\` but have gone silent past the ` +
90
+ `check-in window (${staleUnits.map((u) => u.unitId).join(", ")}). Their driver may have died — you can ` +
91
+ `reclaim and re-execute them.`);
92
+ }
93
+ const reportGuidance = {
94
+ checkin: `akm workflow report ${run.id} --unit <unit_id> --status running --note "<short progress note>"`,
95
+ failure: `akm workflow report ${run.id} --unit <unit_id> --status failed --failure-reason <vocab>`,
96
+ note: "Run each unit, then report its result. A unit belongs to the active step's work-list; its unit_id is content-derived — copy it verbatim.",
97
+ };
98
+ // Spine watermark (#14): run-mutation counter shared by every return below.
99
+ // The active branch re-stamps it with the real gate loop + active step id.
100
+ const watermark = `${runRow.updated_at}:u${units.length}`;
101
+ const base = {
102
+ ok: true,
103
+ run,
104
+ spineToken: makeSpineToken(run.id, run.currentStepId, 1, watermark),
105
+ ...(lease ? { engineLease: lease } : {}),
106
+ reportGuidance,
107
+ staleUnits,
108
+ warnings,
109
+ };
110
+ // Completed run: nothing to do.
111
+ if (next.done || run.status === "completed") {
112
+ return {
113
+ ...base,
114
+ done: true,
115
+ active: false,
116
+ workList: EMPTY_WORK_LIST,
117
+ message: "Workflow run is completed — no work remains.",
118
+ };
119
+ }
120
+ // Blocked / failed: not active, so the engine dispatches nothing. Point the
121
+ // driver at `resume` rather than inventing a work-list for a dead run.
122
+ if (run.status !== "active") {
123
+ warnings.push(`Workflow run is ${run.status}, not active — no work-list. Reopen it first: \`akm workflow resume ${run.id}\`.`);
124
+ return {
125
+ ...base,
126
+ active: false,
127
+ workList: EMPTY_WORK_LIST,
128
+ message: `Workflow run is ${run.status} — resume it to continue.`,
129
+ };
130
+ }
131
+ const stepState = next.step;
132
+ if (!stepState) {
133
+ return {
134
+ ...base,
135
+ active: false,
136
+ workList: EMPTY_WORK_LIST,
137
+ message: "Workflow run is active but has no current step.",
138
+ };
139
+ }
140
+ // Load the same frozen plan the engine executes.
141
+ const plan = requireExecutableWorkflowPlan(runRow);
142
+ // Reviewer #12: the journaled params row must still satisfy the frozen param
143
+ // schemas — a violation is post-start corruption, loud on the brief surface
144
+ // too (mirrors the frozen-plan hash check and the tampered-params divergence).
145
+ assertRunParamsSatisfyPlan(run.id, plan, next.run.params ?? {});
146
+ // Reviewer #7: a completed route step whose journaled decision names a target
147
+ // the route never declared is tampered evidence — fail loudly on the read-only
148
+ // brief surface too, not just on the resume/report surfaces that replay it.
149
+ assertJournaledRouteSelectionsValid(plan, next);
150
+ const stepPlan = plan.steps.find((s) => s.stepId === stepState.id);
151
+ if (!stepPlan) {
152
+ throw new UsageError(`Step "${stepState.id}" of run ${run.id} is not present in the run's frozen plan. The plan and the step ` +
153
+ `journal disagree — this run cannot be described; drive it manually with \`akm workflow complete\`.`);
154
+ }
155
+ // Expression scope: prior steps' promoted artifacts + run params, projected
156
+ // exactly as the engine does (stepOutputsFromEvidence). The current (pending)
157
+ // step contributes no output yet.
158
+ const evidence = {};
159
+ for (const s of next.workflow.steps)
160
+ evidence[s.id] = s.evidence;
161
+ const stepOutputs = stepOutputsFromEvidence(evidence);
162
+ // Gate loop + recovered feedback — the journal-derived state that makes a
163
+ // loop-N brief predict the engine's loop-N dispatch (unit ids + hashes).
164
+ const gateLoop = activeGateLoop(units, stepState.id);
165
+ const gateFeedback = recoverGateFeedback(units, stepState.id, gateLoop);
166
+ const isRouteOnly = !!stepPlan.route && !stepPlan.root;
167
+ const kind = isRouteOnly ? "route" : stepPlan.route ? "execute-and-route" : "execute";
168
+ const criteria = stepPlan.gate.criteria;
169
+ const instructions = frozenStepRows(plan).find((step) => step.stepId === stepState.id)?.instructions;
170
+ if (instructions === undefined)
171
+ throw new UsageError(`Step "${stepState.id}" has no frozen instructions.`);
172
+ const step = {
173
+ stepId: stepState.id,
174
+ title: stepPlan.title,
175
+ sequenceIndex: stepPlan.sequenceIndex,
176
+ kind,
177
+ instructions,
178
+ gate: {
179
+ criteria,
180
+ maxLoops: Math.max(1, stepPlan.gate.maxLoops ?? 1),
181
+ currentLoop: gateLoop,
182
+ judgesArtifact: !isRouteOnly && criteria.length > 0,
183
+ },
184
+ ...(stepPlan.outputSchema ? { outputSchema: stepPlan.outputSchema } : {}),
185
+ };
186
+ // Journaled dispatch rows for THIS step, keyed by unit id (exclude gate rows).
187
+ const journaledByUnit = new Map();
188
+ for (const row of units) {
189
+ if (row.step_id === stepState.id && row.phase !== GATE_EVALUATION_PHASE) {
190
+ journaledByUnit.set(row.unit_id, row);
191
+ }
192
+ }
193
+ // #15 action derivation inputs: the stale-claim set (by unit id) and whether a
194
+ // live engine lease means the whole work-list is `do_not_run` right now.
195
+ const staleIds = new Set(staleUnits.map((u) => u.unitId));
196
+ const leaseLive = lease?.live === true;
197
+ // The work-list — the SAME computation the engine runs (no drift).
198
+ let workList = EMPTY_WORK_LIST;
199
+ // True when every resolvable unit ran to a terminal state but the step never
200
+ // finalized (a required-gate block that was resumed, or a crash between the
201
+ // last unit write and completion) — the fully-terminal recovery state.
202
+ let fullyTerminal = false;
203
+ if (!isRouteOnly) {
204
+ const computed = computeStepWorkList(stepPlan, {
205
+ runId: run.id,
206
+ params: run.params,
207
+ stepOutputs,
208
+ engines: plan.execution.engines,
209
+ gateLoop,
210
+ ...(gateFeedback ? { gateFeedback } : {}),
211
+ });
212
+ if (!computed.ok) {
213
+ workList = { ...EMPTY_WORK_LIST, error: computed.error };
214
+ }
215
+ else {
216
+ const list = computed.list;
217
+ fullyTerminal = !leaseLive && isWorkListFullyTerminal(list, journaledByUnit);
218
+ // #21: a worktree-isolated unit runs in a throwaway git worktree that is
219
+ // auto-removed when clean. Files it writes to a `.gitignore`d path are
220
+ // treated as disposable and discarded — warn any driver so collectible
221
+ // artifacts go to a non-ignored path or come back as a reported result.
222
+ if (list.units.some((u) => u.isolation === "worktree")) {
223
+ warnings.push("This step runs unit(s) in an isolated git worktree (`isolation: worktree`). Outputs matched by the " +
224
+ "repository's `.gitignore` are treated as DISPOSABLE — a clean worktree is auto-removed, discarding them. " +
225
+ "Write any artifact that must survive to a NON-ignored path (a tracked or untracked-unignored file), or " +
226
+ "report it as the unit's result. Do not leave collectible work under `node_modules`/`dist`/build/cache paths.");
227
+ }
228
+ workList = {
229
+ isFanOut: list.isFanOut,
230
+ reducer: list.reducer,
231
+ ...(list.concurrency !== undefined ? { concurrency: list.concurrency } : {}),
232
+ itemCount: list.items.length,
233
+ units: list.units.map((u) =>
234
+ // Resolve the unit's journaled state by its BEST terminal attempt
235
+ // (base + `~r<n>` retries), the SAME reuse the engine and report
236
+ // surfaces apply (shared selectUnitAttemptRow, finding C): a unit whose
237
+ // base attempt failed but whose retry completed surfaces as `done`, not
238
+ // `failed`, so brief never advertises re-running work a prior retry
239
+ // already finished — keeping the read-only surface consistent with what
240
+ // report/resume would reduce.
241
+ toBriefUnit(run.id, u, stepState.id, selectUnitAttemptRow(u, journaledByUnit), {
242
+ stale: staleIds.has(u.journalBaseId),
243
+ leaseLive,
244
+ })),
245
+ };
246
+ }
247
+ }
248
+ // Route contract. A route-only step's decision depends solely on prior step
249
+ // outputs, so brief evaluates it deterministically NOW. An execute-and-route
250
+ // step's decision needs the current step's fresh output, which does not exist
251
+ // until the units run — so brief surfaces the contract without a decision.
252
+ let route;
253
+ if (stepPlan.route) {
254
+ route = {
255
+ input: stepPlan.route.input,
256
+ when: stepPlan.route.when,
257
+ ...(stepPlan.route.defaultStepId ? { defaultStepId: stepPlan.route.defaultStepId } : {}),
258
+ evaluatedNow: isRouteOnly,
259
+ };
260
+ if (isRouteOnly) {
261
+ const scope = { params: run.params, stepOutputs };
262
+ const decision = evaluateRoute(stepPlan.route, scope);
263
+ if (decision.ok)
264
+ route.decision = { value: decision.value, selected: decision.selected };
265
+ else
266
+ route.decisionError = decision.error;
267
+ }
268
+ }
269
+ // A step the driver cannot advance with a per-unit `report --unit` gets the
270
+ // `--settle` verb instead. TWO cases:
271
+ // - NON-DISPATCHING (finding D): a route-only step, an empty fan-out, an
272
+ // all-unresolvable work-list, or a whole-list failure — nothing was ever
273
+ // dispatchable.
274
+ // - FULLY TERMINAL (owner manual-validation finding 3): every resolvable
275
+ // unit already ran to a terminal state, but the step never finalized (a
276
+ // required-gate block that was resumed, or a crash before completion). The
277
+ // units show `done`/`failed` with no report command, so without this the
278
+ // driver is stranded — `--settle` runs the shared completion path.
279
+ // Never while a live engine lease owns the spine (a report/settle is refused
280
+ // then anyway). `--expect-step` guards a stale copy once the spine moves.
281
+ const hasReportableWork = !isRouteOnly && !workList.error && workList.units.some((u) => u.resolved.ok);
282
+ const nonDispatching = !hasReportableWork;
283
+ const settleable = !leaseLive && (nonDispatching || fullyTerminal);
284
+ const settleCommand = settleable ? `akm workflow report ${run.id} --settle --expect-step ${stepState.id}` : undefined;
285
+ const settleState = !settleable
286
+ ? "none"
287
+ : fullyTerminal
288
+ ? "finalize"
289
+ : "non-dispatching";
290
+ const message = buildMessage(step, workList, route, gateLoop, settleState);
291
+ return {
292
+ ...base,
293
+ // Re-stamp the spine token with the resolved active step + real gate loop.
294
+ spineToken: makeSpineToken(run.id, stepState.id, gateLoop, watermark),
295
+ active: true,
296
+ step,
297
+ ...(gateFeedback ? { gateFeedback } : {}),
298
+ workList,
299
+ ...(route ? { route } : {}),
300
+ ...(settleCommand ? { settleCommand } : {}),
301
+ message,
302
+ };
303
+ }
304
+ /**
305
+ * The spine watermark stamped on every brief (#14): run id, active step id,
306
+ * gate loop, and a run-mutation watermark (`updated_at` + journal row count). A
307
+ * driver diffs it across polls to notice the spine moved; `report --expect-step`
308
+ * enforces the step half server-side.
309
+ */
310
+ function makeSpineToken(runId, stepId, gateLoop, watermark) {
311
+ return `${runId}#${stepId ?? "-"}#l${gateLoop}#${watermark}`;
312
+ }
313
+ // ── Helpers ──────────────────────────────────────────────────────────────────
314
+ function toBriefUnit(runId, unit, stepId, journaled, ctx) {
315
+ if (!unit.engine || !unit.invocation) {
316
+ throw new UsageError(`Unit "${unit.unitId}" has no complete frozen engine attribution.`);
317
+ }
318
+ const action = deriveUnitAction(unit, journaled, ctx);
319
+ const report = reportCommandForAction(runId, unit, stepId, action, journaled?.claim_holder ?? null);
320
+ return {
321
+ unitId: unit.unitId,
322
+ nodeId: unit.nodeId,
323
+ index: unit.index,
324
+ engine: unit.invocation.engine,
325
+ runtimeKind: unit.runner,
326
+ platform: unit.engine.kind === "agent" ? unit.engine.platform : null,
327
+ model: unit.invocation.model,
328
+ timeoutMs: unit.timeoutMs,
329
+ ...(unit.schema ? { outputSchema: unit.schema } : {}),
330
+ // Env asset REF names only — brief never resolves bindings, so no secret
331
+ // value can ever reach this output.
332
+ ...(unit.env ? { env: unit.env } : {}),
333
+ ...(unit.retry ? { retry: unit.retry } : {}),
334
+ onError: unit.onError,
335
+ ...(unit.isFanOut ? { item: unit.item } : {}),
336
+ resolved: unit.resolved.ok
337
+ ? { ok: true, instructions: unit.resolved.prompt, inputHash: unit.resolved.inputHash }
338
+ : { ok: false, error: unit.resolved.error },
339
+ ...(journaled ? { journaled: toBriefJournaled(journaled) } : {}),
340
+ action,
341
+ ...(report ? { report } : {}),
342
+ };
343
+ }
344
+ /**
345
+ * Fold the journaled row + engine lease + resolvability into ONE driver-facing
346
+ * action (#15). A live engine lease or an unresolvable unit is `do_not_run`; a
347
+ * terminal row is `done`/`failed`; a live claim is `claimed` (or `stale` once
348
+ * silent); no row is `pending`.
349
+ */
350
+ function deriveUnitAction(unit, journaled, ctx) {
351
+ if (!unit.resolved.ok)
352
+ return "do_not_run";
353
+ if (ctx.leaseLive)
354
+ return "do_not_run";
355
+ if (!journaled)
356
+ return "pending";
357
+ if (journaled.status === "completed")
358
+ return "done";
359
+ if (journaled.status === "failed")
360
+ return "failed";
361
+ if (journaled.status === "running")
362
+ return ctx.stale ? "stale" : "claimed";
363
+ return "pending";
364
+ }
365
+ function toBriefJournaled(row) {
366
+ // Claim state is meaningful only while the unit is still running; a terminal
367
+ // row keeps its claim columns but they are no longer actionable.
368
+ const claim = row.status === "running"
369
+ ? {
370
+ ...(row.claim_holder ? { claimedBy: row.claim_holder } : {}),
371
+ ...(row.claim_expires_at ? { claimExpiresAt: row.claim_expires_at } : {}),
372
+ }
373
+ : {};
374
+ return {
375
+ unitId: row.unit_id,
376
+ status: row.status,
377
+ ...(row.failure_reason ? { failureReason: row.failure_reason } : {}),
378
+ ...(row.tokens !== null ? { tokens: row.tokens } : {}),
379
+ ...(row.started_at ? { startedAt: row.started_at } : {}),
380
+ ...(row.finished_at ? { finishedAt: row.finished_at } : {}),
381
+ ...claim,
382
+ };
383
+ }
384
+ /**
385
+ * The `report` command line for a unit, tailored to its action (#15). Terminal
386
+ * `done` and `do_not_run` units get NO command; a `failed` unit gets the
387
+ * `--rerun` form (records a fresh attempt, per #25); `pending`/`stale`/`claimed`
388
+ * get the completed form. Every command carries `--expect-step` (#14) so a
389
+ * copy-pasted command from a stale brief is refused once the spine moves on.
390
+ *
391
+ * A `claimed` unit is held by a LIVE `--status running` claim (`claimHolder`):
392
+ * ONLY that holder can finish it — the report path's claim compare-and-set
393
+ * refuses any other `--session-id`. So its command carries `--session-id
394
+ * <holder>`, which (a) is the exact form the holding driver must use to finish
395
+ * its OWN claim, and (b) makes it unmistakable to a SECOND driver that the unit
396
+ * is spoken for rather than free, runnable work (owner manual-validation
397
+ * finding 2: two drivers must not both treat a live-claimed unit as free). A
398
+ * `stale` unit's claim has expired and is freely reclaimable/finishable by
399
+ * anyone, so it keeps the plain completed form (no `--session-id`).
400
+ */
401
+ function reportCommandForAction(runId, unit, stepId, action, claimHolder) {
402
+ if (action === "done" || action === "do_not_run")
403
+ return undefined;
404
+ const resultHint = unit.schema
405
+ ? "--result-file <result.json> # JSON matching the unit's outputSchema"
406
+ : "--result-file <result.txt> # or --result '<text>' / pipe via stdin";
407
+ const rerun = action === "failed" ? " --rerun" : "";
408
+ // A live claim requires its holder's --session-id to finish; surface it so the
409
+ // holder's command is correct and other drivers see the unit is claimed.
410
+ const session = action === "claimed" && claimHolder ? ` --session-id ${claimHolder}` : "";
411
+ return `akm workflow report ${runId} --unit ${unit.unitId} --expect-step ${stepId} --status completed${rerun}${session} ${resultHint}`;
412
+ }
413
+ export function buildLease(holder, until) {
414
+ if (!holder || !until)
415
+ return undefined;
416
+ return { holder, until, live: until >= new Date().toISOString() };
417
+ }
418
+ function buildMessage(step, workList, route, gateLoop, settleState) {
419
+ const loopNote = gateLoop > 1 ? ` (gate loop ${gateLoop}, addressing prior rejection feedback)` : "";
420
+ const settleNote = settleState !== "none" ? " Advance it with `akm workflow report --settle` (see settleCommand)." : "";
421
+ if (step.kind === "route") {
422
+ const decided = route?.decision ? ` → selects step "${route.decision.selected}"` : "";
423
+ return `Active step "${step.stepId}" is a route step — no units to execute${decided}.${settleNote || " Advances deterministically."}`;
424
+ }
425
+ if (workList.error) {
426
+ return `Active step "${step.stepId}" could not compute a work-list: ${workList.error}${settleNote}`;
427
+ }
428
+ const n = workList.units.length;
429
+ if (settleState === "finalize") {
430
+ // Fully-terminal work-list on a still-active step: everything ran, nothing
431
+ // remains to execute — the step only needs finalization (the run was
432
+ // gate-rejected then resumed, or a crash interrupted completion).
433
+ return (`Active step "${step.stepId}" has run all ${n} unit(s) to a terminal state${loopNote} — nothing remains to ` +
434
+ `execute or report. Finalize it with \`akm workflow report --settle\` (see settleCommand): the gate is judged ` +
435
+ "and the step advances.");
436
+ }
437
+ if (settleState === "non-dispatching") {
438
+ return `Active step "${step.stepId}" dispatches no reportable units${loopNote}.${settleNote}`;
439
+ }
440
+ return `Active step "${step.stepId}" expects ${n} unit(s)${loopNote}. Execute them, then report each result.`;
441
+ }
442
+ /**
443
+ * Resolve `target` to a concrete run id WITHOUT starting anything. A run id
444
+ * resolves directly; a workflow ref resolves to its active run in the current
445
+ * scope, and NO active run is a NotFoundError (brief never auto-starts — that
446
+ * would mutate).
447
+ */
448
+ export async function resolveRunId(target) {
449
+ return resolveExistingWorkflowRunId(target);
450
+ }
@@ -0,0 +1,47 @@
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 { deepMergeConfig } from "../../core/config/deep-merge.js";
5
+ import { ConfigError } from "../../core/errors.js";
6
+ /** Build a gate judge from a v3 catalog entry without consulting live config. */
7
+ export function frozenSummaryJudge(plan, invocation) {
8
+ if (!invocation)
9
+ return null;
10
+ const engine = plan.execution?.engines[invocation.engine];
11
+ if (!engine || engine.kind !== "llm")
12
+ throw new ConfigError(`Frozen gate engine "${invocation.engine}" is unavailable.`, "INVALID_CONFIG_FILE");
13
+ return async ({ system, user }) => {
14
+ const { chatCompletion } = await import("../../llm/client.js");
15
+ return chatCompletion(materialize(engine, invocation), [
16
+ { role: "system", content: system },
17
+ { role: "user", content: user },
18
+ ], {
19
+ timeoutMs: invocation.timeoutMs,
20
+ });
21
+ };
22
+ }
23
+ function materialize(engine, invocation) {
24
+ let apiKey;
25
+ for (const name of engine.credential?.names ?? []) {
26
+ const value = process.env[name]?.trim();
27
+ if (value) {
28
+ apiKey = value;
29
+ break;
30
+ }
31
+ }
32
+ if (engine.credential?.required && !apiKey)
33
+ throw new ConfigError(`Required engine credential ${engine.credential.names[0]} is not set.`, "INVALID_CONFIG_FILE");
34
+ const base = {
35
+ provider: engine.provider,
36
+ endpoint: engine.endpoint,
37
+ model: invocation.model ?? engine.model,
38
+ ...(engine.temperature !== undefined ? { temperature: engine.temperature } : {}),
39
+ ...(engine.maxTokens !== undefined ? { maxTokens: engine.maxTokens } : {}),
40
+ ...(engine.supportsJsonSchema !== undefined ? { supportsJsonSchema: engine.supportsJsonSchema } : {}),
41
+ ...(engine.extraParams ? { extraParams: engine.extraParams } : {}),
42
+ ...(engine.contextLength !== undefined ? { contextLength: engine.contextLength } : {}),
43
+ ...(engine.enableThinking !== undefined ? { enableThinking: engine.enableThinking } : {}),
44
+ ...(apiKey ? { apiKey } : {}),
45
+ };
46
+ return (invocation.llm ? deepMergeConfig(base, invocation.llm) : base);
47
+ }