akm-cli 0.9.0-rc.8 → 0.9.0

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 (450) hide show
  1. package/CHANGELOG.md +1063 -44
  2. package/README.md +51 -25
  3. package/SECURITY.md +14 -1
  4. package/STABILITY.md +497 -0
  5. package/dist/akm +148 -35
  6. package/dist/{akm-migrate-storage → akm-migrate} +6 -9
  7. package/dist/assets/hints/cli-hints-full.md +223 -95
  8. package/dist/assets/hints/cli-hints-short.md +85 -22
  9. package/dist/assets/improve-strategies/default.json +1 -1
  10. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  11. package/dist/assets/prompts/memory-infer-user.md +2 -3
  12. package/dist/assets/stash-skeleton/README.md +6 -5
  13. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
  14. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
  15. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
  17. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
  18. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
  19. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
  21. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
  22. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
  23. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
  24. package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
  25. package/dist/assets/tasks/core/extract.yml +1 -1
  26. package/dist/assets/tasks/core/version-check.yml +1 -1
  27. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  28. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  29. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  30. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  31. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  32. package/dist/assets/templates/html/health.html +1 -3
  33. package/dist/assets/workflows/workflow-template.md +32 -15
  34. package/dist/cli/invocation.js +40 -15
  35. package/dist/cli/parse-args.js +0 -22
  36. package/dist/cli/retired-commands.js +121 -0
  37. package/dist/cli/shared.js +154 -22
  38. package/dist/cli/unknown-flags.js +236 -0
  39. package/dist/cli-node.mjs +2 -1
  40. package/dist/cli.js +696 -258
  41. package/dist/commands/agent/agent-dispatch.js +14 -3
  42. package/dist/commands/agent/contribute-cli.js +73 -88
  43. package/dist/commands/completions.js +79 -22
  44. package/dist/commands/config-cli.js +17 -150
  45. package/dist/commands/env/env-cli.js +59 -143
  46. package/dist/commands/env/env.js +12 -163
  47. package/dist/commands/env/marker-path.js +6 -0
  48. package/dist/commands/env/secret-cli.js +36 -66
  49. package/dist/commands/env/secret.js +24 -57
  50. package/dist/commands/feedback-cli.js +141 -87
  51. package/dist/commands/health/accept-rate.js +58 -0
  52. package/dist/commands/health/advisories.js +3 -4
  53. package/dist/commands/health/checks.js +85 -23
  54. package/dist/commands/health/html-report.js +7 -10
  55. package/dist/commands/health/improve-metrics.js +25 -83
  56. package/dist/commands/health/md-report.js +5 -9
  57. package/dist/commands/health/metrics.js +62 -20
  58. package/dist/commands/health/renderers.js +47 -0
  59. package/dist/commands/health/report-view-model.js +4 -5
  60. package/dist/commands/health/stash-exposure.js +1 -1
  61. package/dist/commands/health/surfaces.js +3 -48
  62. package/dist/commands/health/task-runs.js +3 -67
  63. package/dist/commands/health/types-improve.js +7 -0
  64. package/dist/commands/health.js +99 -28
  65. package/dist/commands/improve/anti-collapse.js +2 -2
  66. package/dist/commands/improve/autonomy-gate.js +68 -0
  67. package/dist/commands/improve/collapse-detector.js +41 -40
  68. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  69. package/dist/commands/improve/consolidate/merge.js +4 -0
  70. package/dist/commands/improve/consolidate.js +140 -1000
  71. package/dist/commands/improve/distill/promote-memory.js +12 -12
  72. package/dist/commands/improve/distill/quality-gate.js +6 -6
  73. package/dist/commands/improve/distill.js +58 -69
  74. package/dist/commands/improve/eligibility.js +105 -57
  75. package/dist/commands/improve/extract-cli.js +14 -133
  76. package/dist/commands/improve/improve-cli.js +98 -114
  77. package/dist/commands/improve/improve-result-file.js +1 -28
  78. package/dist/commands/improve/improve-strategies.js +8 -5
  79. package/dist/commands/improve/improve.js +128 -91
  80. package/dist/commands/improve/loop-stages.js +182 -20
  81. package/dist/commands/improve/memory/derived-ref.js +45 -43
  82. package/dist/commands/improve/memory/memory-belief.js +1 -1
  83. package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
  84. package/dist/commands/improve/memory/memory-improve.js +6 -5
  85. package/dist/commands/improve/outcome-loop.js +22 -65
  86. package/dist/commands/improve/preparation.js +114 -123
  87. package/dist/commands/improve/proactive-maintenance.js +2 -5
  88. package/dist/commands/improve/reflect.js +56 -160
  89. package/dist/commands/improve/salience.js +11 -122
  90. package/dist/commands/improve/source-identity.js +10 -38
  91. package/dist/commands/lint/base-linter.js +20 -124
  92. package/dist/commands/lint/env-key-rules.js +31 -47
  93. package/dist/commands/lint/index.js +249 -43
  94. package/dist/commands/{events.js → log.js} +33 -38
  95. package/dist/commands/migrate-cli.js +92 -12
  96. package/dist/commands/migration-tool.js +46 -0
  97. package/dist/commands/observability-cli.js +70 -209
  98. package/dist/commands/proposal/drain.js +101 -29
  99. package/dist/commands/proposal/proposal-cli.js +76 -48
  100. package/dist/commands/proposal/proposal.js +54 -18
  101. package/dist/commands/proposal/propose-cli.js +88 -0
  102. package/dist/commands/proposal/propose.js +23 -15
  103. package/dist/commands/proposal/repository.js +701 -278
  104. package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
  105. package/dist/commands/proposal/validators/proposal-validators.js +55 -7
  106. package/dist/commands/proposal/validators/proposals.js +4 -7
  107. package/dist/commands/read/curate.js +34 -53
  108. package/dist/commands/read/knowledge.js +150 -95
  109. package/dist/commands/read/registry-search.js +2 -2
  110. package/dist/commands/read/remember-cli.js +42 -15
  111. package/dist/commands/read/search-cli.js +180 -78
  112. package/dist/commands/read/search.js +58 -43
  113. package/dist/commands/read/show.js +197 -141
  114. package/dist/commands/registry-cli.js +12 -51
  115. package/dist/commands/remember.js +14 -57
  116. package/dist/commands/sources/add-cli.js +100 -31
  117. package/dist/commands/sources/bundle-cli.js +166 -0
  118. package/dist/commands/sources/bundle-config-ops.js +7 -2
  119. package/dist/commands/sources/info.js +18 -5
  120. package/dist/commands/sources/init.js +12 -12
  121. package/dist/commands/sources/installed-stashes.js +382 -98
  122. package/dist/commands/sources/schema-repair.js +3 -2
  123. package/dist/commands/sources/self-update.js +131 -38
  124. package/dist/commands/sources/source-add.js +72 -17
  125. package/dist/commands/sources/source-clone.js +129 -45
  126. package/dist/commands/sources/source-manage.js +43 -23
  127. package/dist/commands/sources/sources-cli.js +57 -208
  128. package/dist/commands/sources/stash-cli.js +46 -53
  129. package/dist/commands/tasks/tasks-cli.js +91 -97
  130. package/dist/commands/tasks/tasks.js +276 -421
  131. package/dist/commands/workflow-cli.js +175 -450
  132. package/dist/core/adapter/adapters/akm-adapter.js +47 -28
  133. package/dist/core/adapter/adapters/akm-lint.js +42 -27
  134. package/dist/core/adapter/adapters/akm-metadata.js +15 -44
  135. package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
  136. package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
  137. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
  138. package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
  139. package/dist/core/adapter/adapters/index.js +6 -6
  140. package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
  141. package/dist/core/adapter/adapters/okf-adapter.js +187 -19
  142. package/dist/core/adapter/adapters/shared.js +3 -19
  143. package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
  144. package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
  145. package/dist/core/adapter/detect-adapter.js +17 -0
  146. package/dist/core/adapter/recognize-match.js +6 -4
  147. package/dist/core/adapter/validate-context.js +214 -0
  148. package/dist/core/asset/akm-markdown.js +63 -0
  149. package/dist/core/asset/asset-placement.js +20 -6
  150. package/dist/core/asset/asset-ref.js +11 -9
  151. package/dist/core/asset/frontmatter-lint.js +30 -0
  152. package/dist/core/asset/frontmatter.js +37 -9
  153. package/dist/core/asset/markdown.js +40 -51
  154. package/dist/core/asset/resolve-ref.js +89 -18
  155. package/dist/core/asset/stash-meta.js +1 -1
  156. package/dist/core/bundle-id.js +51 -0
  157. package/dist/core/common.js +152 -38
  158. package/dist/core/config/config-io.js +12 -1
  159. package/dist/core/config/config-schema.js +35 -8
  160. package/dist/core/config/config-sources.js +55 -11
  161. package/dist/core/config/config-walker.js +25 -9
  162. package/dist/core/config/config.js +9 -48
  163. package/dist/core/config/experimental.js +21 -0
  164. package/dist/core/config/schema/embedding.js +5 -1
  165. package/dist/core/config/schema/experimental.js +30 -0
  166. package/dist/core/config/schema/improve-processes.js +0 -6
  167. package/dist/core/config/schema/improve.js +21 -3
  168. package/dist/core/config/schema/index-config.js +8 -15
  169. package/dist/core/config/schema/output.js +4 -1
  170. package/dist/core/config/schema/setup.js +9 -18
  171. package/dist/core/config/schema/sources-bundles.js +49 -33
  172. package/dist/core/config/schema/workflow.js +3 -3
  173. package/dist/core/env-secret-ref.js +76 -46
  174. package/dist/core/errors.js +18 -12
  175. package/dist/core/events.js +46 -128
  176. package/dist/core/file-change.js +6 -5
  177. package/dist/core/fs-txn.js +83 -7
  178. package/dist/core/git-message.js +2 -2
  179. package/dist/core/improve-result.js +1 -100
  180. package/dist/core/lesson-lint.js +1 -17
  181. package/dist/core/logs-db.js +2 -1
  182. package/dist/core/migration-operation.js +16 -0
  183. package/dist/core/mutation-target.js +78 -0
  184. package/dist/core/parse.js +4 -1
  185. package/dist/core/paths.js +17 -20
  186. package/dist/core/recognition-util.js +12 -14
  187. package/dist/core/redaction.js +34 -0
  188. package/dist/core/standards/resolve-standards-context.js +2 -14
  189. package/dist/core/standards/resolve-stash-standards.js +2 -2
  190. package/dist/core/standards/resolve-type-conventions.js +2 -2
  191. package/dist/core/state/migrations.js +41 -18
  192. package/dist/core/state-db.js +5 -14
  193. package/dist/core/structured.js +1 -1
  194. package/dist/core/subprocess.js +6 -4
  195. package/dist/core/text-truncation.js +9 -5
  196. package/dist/core/type-presentation.js +3 -3
  197. package/dist/core/warn.js +0 -3
  198. package/dist/core/write-source.js +771 -95
  199. package/dist/indexer/bundle-identity-guard.js +3 -2
  200. package/dist/indexer/db/graph-db.js +0 -24
  201. package/dist/indexer/ensure-index.js +1 -0
  202. package/dist/indexer/graph/graph-boost.js +9 -34
  203. package/dist/indexer/graph/graph-extraction.js +8 -5
  204. package/dist/indexer/index-writer-lock.js +53 -17
  205. package/dist/indexer/index-written-assets.js +16 -22
  206. package/dist/indexer/indexer.js +497 -239
  207. package/dist/indexer/installations.js +14 -96
  208. package/dist/indexer/passes/dir-staleness.js +16 -9
  209. package/dist/indexer/passes/memory-inference.js +11 -9
  210. package/dist/indexer/passes/metadata.js +113 -47
  211. package/dist/indexer/scan/doc-to-entry.js +38 -1
  212. package/dist/indexer/scan/drain-dir.js +13 -23
  213. package/dist/indexer/search/db-search.js +99 -54
  214. package/dist/indexer/search/fts-query.js +47 -24
  215. package/dist/indexer/search/ranking-contributors.js +42 -20
  216. package/dist/indexer/search/ranking.js +18 -99
  217. package/dist/indexer/search/search-fields.js +7 -2
  218. package/dist/indexer/search/search-source.js +82 -93
  219. package/dist/indexer/usage/usage-events.js +0 -89
  220. package/dist/indexer/walk/file-context.js +2 -1
  221. package/dist/indexer/walk/matchers.js +30 -43
  222. package/dist/indexer/walk/path-resolver.js +7 -2
  223. package/dist/indexer/walk/walker.js +38 -12
  224. package/dist/integrations/agent/builders.js +0 -6
  225. package/dist/integrations/agent/config.js +2 -2
  226. package/dist/integrations/agent/detect.js +49 -19
  227. package/dist/integrations/agent/engine-fallback.js +76 -0
  228. package/dist/integrations/agent/profiles.js +14 -0
  229. package/dist/integrations/agent/prompts.js +12 -8
  230. package/dist/integrations/agent/runner-dispatch.js +4 -2
  231. package/dist/integrations/agent/runner.js +0 -1
  232. package/dist/integrations/agent/spawn.js +5 -6
  233. package/dist/integrations/github.js +1 -1
  234. package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
  235. package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
  236. package/dist/integrations/harnesses/claude/session-log.js +0 -10
  237. package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
  238. package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
  239. package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
  240. package/dist/integrations/harnesses/index.js +3 -7
  241. package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
  242. package/dist/integrations/harnesses/opencode/session-log.js +0 -15
  243. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
  244. package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
  245. package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
  246. package/dist/integrations/lockfile.js +101 -6
  247. package/dist/integrations/session-logs/index.js +3 -28
  248. package/dist/llm/client.js +136 -100
  249. package/dist/llm/embedders/remote.js +13 -5
  250. package/dist/llm/feature-gate.js +4 -12
  251. package/dist/llm/graph-extract.js +5 -11
  252. package/dist/llm/memory-infer.js +144 -1
  253. package/dist/llm/metadata-enhance.js +5 -7
  254. package/dist/llm/structured-call.js +1 -1
  255. package/dist/llm/usage-persist.js +26 -5
  256. package/dist/llm/usage-telemetry.js +25 -2
  257. package/dist/output/cli-hints.js +1 -2
  258. package/dist/output/context.js +22 -7
  259. package/dist/output/format-exempt.js +80 -0
  260. package/dist/output/generic-render.js +259 -0
  261. package/dist/output/render-registry.js +57 -0
  262. package/dist/output/renderers.js +14 -36
  263. package/dist/output/shapes/curate.js +10 -1
  264. package/dist/output/shapes/events.js +12 -7
  265. package/dist/output/shapes/helpers.js +56 -83
  266. package/dist/output/shapes/migrate.js +8 -0
  267. package/dist/output/shapes/passthrough.js +7 -41
  268. package/dist/output/shapes/proposal/producer.js +15 -7
  269. package/dist/output/shapes.js +2 -9
  270. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  271. package/dist/output/text/bundle-show.js +7 -0
  272. package/dist/output/text/command-format.js +164 -96
  273. package/dist/output/text/env.js +1 -3
  274. package/dist/output/text/events.js +8 -7
  275. package/dist/output/text/health-format.js +103 -0
  276. package/dist/output/text/health.js +7 -0
  277. package/dist/output/text/helpers.js +10 -8
  278. package/dist/output/text/lint-format.js +43 -0
  279. package/dist/output/text/{save.js → lint.js} +2 -2
  280. package/dist/output/text/migrate.js +88 -0
  281. package/dist/output/text/proposal/producer.js +4 -2
  282. package/dist/output/text/proposal-format.js +44 -72
  283. package/dist/output/text/registry-commands.js +1 -2
  284. package/dist/output/text/show-directives.js +15 -7
  285. package/dist/output/text/status-list.js +32 -0
  286. package/dist/output/text/sync.js +5 -0
  287. package/dist/output/text/workflow-format.js +24 -203
  288. package/dist/output/text/workflow.js +1 -7
  289. package/dist/output/text.js +16 -17
  290. package/dist/registry/factory.js +4 -6
  291. package/dist/registry/origin-resolve.js +16 -27
  292. package/dist/registry/providers/skills-sh.js +3 -3
  293. package/dist/registry/providers/static-index.js +13 -23
  294. package/dist/registry/resolve.js +42 -7
  295. package/dist/registry/semver.js +34 -84
  296. package/dist/runtime.js +2 -23
  297. package/dist/scripts/akm-migrate-node.js +60290 -0
  298. package/dist/scripts/akm-migrate.js +59628 -0
  299. package/dist/setup/detect.js +42 -15
  300. package/dist/setup/registry-stash-loader.js +2 -2
  301. package/dist/setup/setup.js +236 -136
  302. package/dist/setup/steps/connection.js +7 -9
  303. package/dist/setup/steps/platforms.js +9 -9
  304. package/dist/setup/steps/semantic.js +15 -3
  305. package/dist/setup/steps/sources.js +12 -13
  306. package/dist/setup/steps/stashdir.js +2 -3
  307. package/dist/setup/steps/tasks.js +237 -120
  308. package/dist/sources/freshness.js +1 -1
  309. package/dist/sources/provider-factory.js +11 -17
  310. package/dist/sources/providers/filesystem.js +2 -3
  311. package/dist/sources/providers/git-install.js +278 -34
  312. package/dist/sources/providers/git-provider.js +25 -23
  313. package/dist/sources/providers/git-stash.js +395 -106
  314. package/dist/sources/providers/git.js +2 -2
  315. package/dist/sources/providers/npm.js +16 -19
  316. package/dist/sources/providers/provider-utils.js +7 -4
  317. package/dist/sources/providers/sync-from-ref.js +3 -9
  318. package/dist/sources/providers/website.js +6 -1
  319. package/dist/sources/resolve.js +6 -5
  320. package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
  321. package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
  322. package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
  323. package/dist/sources/snapshot-fetchers/github.js +100 -0
  324. package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
  325. package/dist/sources/snapshot-fetchers/registry.js +17 -1
  326. package/dist/sources/snapshot-fetchers/robots.js +348 -0
  327. package/dist/sources/snapshot-fetchers/rss.js +282 -0
  328. package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
  329. package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
  330. package/dist/sources/snapshot-fetchers/x.js +910 -0
  331. package/dist/storage/database.js +7 -0
  332. package/dist/storage/engines/sqlite-migrations.js +23 -111
  333. package/dist/storage/managed-db.js +2 -2
  334. package/dist/storage/repositories/canaries-repository.js +1 -1
  335. package/dist/storage/repositories/events-repository.js +27 -11
  336. package/dist/storage/repositories/improve-runs-repository.js +6 -12
  337. package/dist/storage/repositories/index-connection.js +17 -6
  338. package/dist/storage/repositories/index-entries-repository.js +151 -240
  339. package/dist/storage/repositories/index-entry-mapper.js +15 -11
  340. package/dist/storage/repositories/index-fts-repository.js +5 -2
  341. package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
  342. package/dist/storage/repositories/index-meta-repository.js +2 -3
  343. package/dist/storage/repositories/index-schema.js +10 -25
  344. package/dist/storage/repositories/index-utility-repository.js +15 -28
  345. package/dist/storage/repositories/index-vec-repository.js +6 -1
  346. package/dist/storage/repositories/outcome-repository.js +119 -0
  347. package/dist/storage/repositories/proposals-repository.js +296 -59
  348. package/dist/storage/repositories/registry-cache.js +19 -0
  349. package/dist/storage/repositories/salience-repository.js +172 -0
  350. package/dist/storage/repositories/task-history-repository.js +15 -13
  351. package/dist/storage/repositories/workflow-runs-repository.js +52 -40
  352. package/dist/tasks/backends/cron.js +105 -15
  353. package/dist/tasks/backends/index.js +1 -1
  354. package/dist/tasks/backends/launchd.js +85 -38
  355. package/dist/tasks/backends/schtasks.js +135 -15
  356. package/dist/tasks/embedded.js +56 -40
  357. package/dist/tasks/parser.js +7 -157
  358. package/dist/tasks/resolve-akm-bin.js +137 -59
  359. package/dist/tasks/runner.js +79 -42
  360. package/dist/tasks/scheduler-invocation.js +220 -10
  361. package/dist/tasks/schema.js +24 -1
  362. package/dist/tasks/task-id.js +1 -3
  363. package/dist/tasks/validator.js +20 -6
  364. package/dist/workflows/authoring/authoring.js +94 -143
  365. package/dist/workflows/authoring/scope-key.js +1 -1
  366. package/dist/workflows/exec/frozen-judge.js +28 -2
  367. package/dist/workflows/exec/native-executor.js +77 -57
  368. package/dist/workflows/exec/param-secrets.js +9 -9
  369. package/dist/workflows/exec/run-workflow.js +133 -79
  370. package/dist/workflows/exec/step-work.js +219 -346
  371. package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
  372. package/dist/workflows/ir/compile.js +141 -270
  373. package/dist/workflows/ir/freeze.js +40 -30
  374. package/dist/workflows/ir/params.js +135 -11
  375. package/dist/workflows/ir/plan-hash.js +1 -1
  376. package/dist/workflows/ir/schema.js +25 -26
  377. package/dist/workflows/parser.js +872 -307
  378. package/dist/workflows/program/expressions.js +20 -208
  379. package/dist/workflows/program/schema.js +7 -10
  380. package/dist/workflows/renderer.js +95 -68
  381. package/dist/workflows/resource-limits.js +2 -0
  382. package/dist/workflows/runtime/checkin.js +3 -3
  383. package/dist/workflows/runtime/plan-classifier.js +16 -75
  384. package/dist/workflows/runtime/runs.js +186 -127
  385. package/dist/workflows/runtime/unit-checkin.js +1 -1
  386. package/dist/workflows/runtime/unit-phases.js +2 -2
  387. package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
  388. package/dist/workflows/schema.js +1 -11
  389. package/dist/workflows/validate-summary.js +30 -36
  390. package/dist/workflows/validator.js +21 -62
  391. package/docs/README.md +68 -0
  392. package/docs/migration/README.md +8 -0
  393. package/docs/migration/release-notes/0.7.0.md +11 -11
  394. package/docs/migration/release-notes/0.9.0.md +208 -27
  395. package/docs/migration/v0.7-to-v0.8.md +46 -47
  396. package/docs/migration/v0.8-to-v0.9.md +564 -208
  397. package/docs/migration/v0.9.0-troubleshooting.md +561 -0
  398. package/docs/reference/README.md +12 -0
  399. package/docs/reference/cli.md +2253 -0
  400. package/docs/reference/configuration.md +358 -0
  401. package/docs/reference/data-and-telemetry.md +105 -42
  402. package/docs/reference/workflows.md +647 -0
  403. package/package.json +22 -11
  404. package/schemas/akm-asset-envelope.json +93 -0
  405. package/schemas/akm-config.json +81 -128
  406. package/schemas/akm-workflow.json +74 -73
  407. package/dist/assets/tasks/core/backup.yml +0 -5
  408. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  409. package/dist/cli/config-migrate.js +0 -1806
  410. package/dist/cli/config-validate.js +0 -41
  411. package/dist/commands/backup-cli.js +0 -56
  412. package/dist/commands/bundle/bundle-cli.js +0 -68
  413. package/dist/commands/bundle/bundle.js +0 -219
  414. package/dist/commands/graph/graph-cli.js +0 -124
  415. package/dist/commands/graph/graph.js +0 -489
  416. package/dist/commands/improve/extract-watch.js +0 -140
  417. package/dist/commands/mv-cli.js +0 -1221
  418. package/dist/commands/sources/history.js +0 -201
  419. package/dist/commands/tasks/default-tasks.js +0 -186
  420. package/dist/core/migration-backup.js +0 -1234
  421. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
  422. package/dist/llm/memory-infer-impl.js +0 -138
  423. package/dist/migrate/legacy/config-source-migration.js +0 -223
  424. package/dist/migrate/legacy/content-migration.js +0 -305
  425. package/dist/migrate/legacy/legacy-layout.js +0 -779
  426. package/dist/migrate/legacy/legacy-paths.js +0 -25
  427. package/dist/migrate/legacy/legacy-stash-json.js +0 -72
  428. package/dist/migrate/legacy/proposal-fs-import.js +0 -168
  429. package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
  430. package/dist/migrate/legacy/three-db-cutover.js +0 -841
  431. package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
  432. package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
  433. package/dist/migrate/legacy-ref-grammar.js +0 -214
  434. package/dist/output/shapes/distill.js +0 -14
  435. package/dist/output/shapes/history.js +0 -11
  436. package/dist/output/text/distill.js +0 -6
  437. package/dist/output/text/enable-disable.js +0 -8
  438. package/dist/output/text/history.js +0 -6
  439. package/dist/registry/build-index.js +0 -382
  440. package/dist/schemas/akm-config.json +0 -4704
  441. package/dist/schemas/akm-task.json +0 -87
  442. package/dist/schemas/akm-workflow.json +0 -372
  443. package/dist/scripts/migrate-storage.js +0 -3816
  444. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  445. package/dist/workflows/cli.js +0 -53
  446. package/dist/workflows/exec/brief.js +0 -481
  447. package/dist/workflows/exec/report.js +0 -1460
  448. package/dist/workflows/exec/watch.js +0 -116
  449. package/dist/workflows/program/parser.js +0 -813
  450. package/dist/workflows/program/project.js +0 -104
@@ -4,11 +4,10 @@
4
4
  /**
5
5
  * The remaining `surfaces` advisory group for `akm health` (meta-review 08).
6
6
  * `stash-git-exposure` (08-F1) shipped first in ./stash-exposure.ts; this
7
- * module adds the other four read-only checks the adjudication approved:
7
+ * module adds the other three read-only checks the adjudication approved:
8
8
  *
9
9
  * - `secret-file-perms` — env/secret/backup files not 0600, dirs not 0700 (F4)
10
10
  * - `binary-config-skew` — config.json written by a NEWER akm than this binary (F3)
11
- * - `orphan-stores` — legacy config-backups dirs + 0-byte stash state.db decoy (F4/F7)
12
11
  * - `egress-endpoints` — the remote-destination list, for eyeball diff (surfaces 3/9)
13
12
  *
14
13
  * Every collector is a pure projection over injected paths/config (no
@@ -120,49 +119,6 @@ export function collectConfigSkewAdvisory(configPath) {
120
119
  evidence: { onDiskConfigVersion: onDisk, binaryConfigVersion: CURRENT_CONFIG_VERSION },
121
120
  };
122
121
  }
123
- /**
124
- * `orphan-stores` (08-F4/F7): stores that look load-bearing but are dead —
125
- * legacy `config-backups/` dirs in $DATA/$CONFIG (only `$CACHE/config-backups`
126
- * is written and pruned today) and a 0-byte `<stash>/.akm/state.db` decoy that
127
- * misleads debugging (the live state.db lives in the data dir). Read-only:
128
- * this advisory NAMES them; removal stays an owner-approved per-path action.
129
- */
130
- export function collectOrphanStoresAdvisory(input) {
131
- const orphans = [];
132
- for (const [label, dir] of [
133
- ["legacy data-dir backup location", path.join(input.dataDir, "config-backups")],
134
- ["legacy config-dir backup location", path.join(input.configDir, "config-backups")],
135
- ]) {
136
- try {
137
- if (fs.statSync(dir).isDirectory())
138
- orphans.push(`${dir}/ (${label}; live backups are in $CACHE/config-backups)`);
139
- }
140
- catch {
141
- // absent — fine
142
- }
143
- }
144
- const decoy = path.join(input.stashDir, ".akm", "state.db");
145
- try {
146
- const stat = fs.statSync(decoy);
147
- if (stat.isFile() && stat.size === 0) {
148
- orphans.push(`${decoy} (0-byte decoy; the live state.db is in the data dir)`);
149
- }
150
- }
151
- catch {
152
- // absent — fine
153
- }
154
- if (orphans.length === 0)
155
- return undefined;
156
- return {
157
- name: "orphan-stores",
158
- kind: "deterministic",
159
- status: "warn",
160
- confidence: "high",
161
- message: `${orphans.length} orphan store(s) found: ${orphans.join("; ")}. ` +
162
- "These are dead locations that mislead debugging/recovery — review and remove them (owner-approved, per-path).",
163
- evidence: { orphans },
164
- };
165
- }
166
122
  /**
167
123
  * `egress-endpoints` (08 surfaces 3/9): the full list of remote destinations
168
124
  * akm can talk to under the effective config — registries, remote sources,
@@ -207,14 +163,13 @@ export function collectEgressAdvisory(config) {
207
163
  };
208
164
  }
209
165
  /**
210
- * Aggregate the four collectors into the advisories array shape `akmHealth`
211
- * consumes. Order is fixed: perms → skew → orphans → egress.
166
+ * Aggregate the three collectors into the advisories array shape `akmHealth`
167
+ * consumes. Order is fixed: perms → skew → egress.
212
168
  */
213
169
  export function collectSurfacesAdvisories(input) {
214
170
  const results = [
215
171
  collectSecretPermsAdvisory({ stashDir: input.stashDir, cacheDir: input.cacheDir }, input.platform ?? process.platform),
216
172
  collectConfigSkewAdvisory(input.configPath),
217
- collectOrphanStoresAdvisory({ dataDir: input.dataDir, configDir: input.configDir, stashDir: input.stashDir }),
218
173
  collectEgressAdvisory(input.config),
219
174
  ];
220
175
  return results.filter((r) => r !== undefined);
@@ -2,57 +2,8 @@
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 { queryImproveRuns } from "../../storage/repositories/improve-runs-repository.js";
5
- import { queryCompletedTaskIntervals, queryTaskHistory } from "../../storage/repositories/task-history-repository.js";
5
+ import { queryTaskHistory } from "../../storage/repositories/task-history-repository.js";
6
6
  import { projectImproveRunSummary } from "./improve-metrics.js";
7
- /**
8
- * Load task_history intervals for `task_id='akm-improve'` in the window.
9
- * Returned sorted by startMs ascending so containment lookups can use a
10
- * linear scan (typical N is ~24/day; not worth a tree).
11
- *
12
- * The window filter is widened by 5 minutes on each side because the cron
13
- * task wraps `akm improve` — the task `started_at` fires at e.g. :07:01
14
- * while `recordImproveRun` writes the matching `improve_runs.started_at`
15
- * later (after config load, planning, etc.), so the improve_runs row can
16
- * be inside the window even when its enclosing task_history row started
17
- * just before the window opened.
18
- */
19
- function loadTaskIntervals(db, since, until) {
20
- const sinceMs = new Date(since).getTime();
21
- const untilMs = until ? new Date(until).getTime() : Number.POSITIVE_INFINITY;
22
- const widenedSince = new Date(sinceMs - 5 * 60 * 1000).toISOString();
23
- const widenedUntil = Number.isFinite(untilMs) ? new Date(untilMs + 5 * 60 * 1000).toISOString() : undefined;
24
- const rows = queryCompletedTaskIntervals(db, widenedSince, widenedUntil);
25
- const intervals = [];
26
- for (const row of rows) {
27
- const startMs = new Date(row.started_at).getTime();
28
- const endMs = new Date(row.completed_at).getTime();
29
- if (!Number.isFinite(startMs) || !Number.isFinite(endMs) || endMs < startMs)
30
- continue;
31
- intervals.push({ startMs, endMs, durationMs: endMs - startMs });
32
- }
33
- return intervals;
34
- }
35
- /**
36
- * Find the task_history interval that contains the given timestamp. The
37
- * task wraps `akm improve`, so `improve_runs.started_at` (when
38
- * `recordImproveRun` writes) always falls inside the enclosing task's
39
- * [started_at, completed_at]. Returns undefined when no interval
40
- * contains the timestamp (which happens for manually-invoked improve
41
- * runs not driven by the `akm-improve` task).
42
- *
43
- * Linear scan because N is small. We tolerate a 1s slop on the upper
44
- * bound to handle clock skew between the wrapper's `completed_at` write
45
- * and recordImproveRun's `started_at` write.
46
- */
47
- function findContainingTaskInterval(timestampMs, intervals) {
48
- const SLOP_MS = 1000;
49
- for (const interval of intervals) {
50
- if (timestampMs >= interval.startMs && timestampMs <= interval.endMs + SLOP_MS) {
51
- return interval;
52
- }
53
- }
54
- return undefined;
55
- }
56
7
  /**
57
8
  * Load `task_history` rows whose `task_id` begins `akm-improve` (the scheduled
58
9
  * improve tasks: `akm-improve-frequent`, `akm-improve-proactive-weekly`, …) in
@@ -88,7 +39,7 @@ export function matchImproveTaskId(startedAt, completedAt, taskRuns) {
88
39
  const startMs = new Date(startedAt).getTime();
89
40
  if (!Number.isFinite(startMs))
90
41
  return "manual";
91
- const endMs = completedAt ? new Date(completedAt).getTime() : Number.NaN;
42
+ const endMs = new Date(completedAt).getTime();
92
43
  let best;
93
44
  let bestScore = Number.POSITIVE_INFINITY;
94
45
  for (const task of taskRuns) {
@@ -107,27 +58,12 @@ export function matchImproveTaskId(startedAt, completedAt, taskRuns) {
107
58
  }
108
59
  export function buildPerRunSummaries(db, since, until) {
109
60
  const rows = queryImproveRuns(db, since, until);
110
- const taskIntervals = loadTaskIntervals(db, since, until);
111
61
  const improveTaskRuns = loadImproveTaskRuns(db, since, until);
112
62
  const summaries = [];
113
63
  for (const row of rows) {
114
64
  const startMs = new Date(row.started_at).getTime();
115
65
  const endMs = new Date(row.completed_at).getTime();
116
- // Prefer the improve_runs row's own (completed_at - started_at) delta:
117
- // recordImproveRun now persists distinct start/end timestamps, so the
118
- // row's own delta is the authoritative per-run wall time even for
119
- // manually-invoked `akm improve` runs with no enclosing task_history.
120
- // Only fall back to the task_history containing-interval join for legacy/
121
- // backfill rows where started_at == completed_at (row delta is 0).
122
- const hasRowDelta = Number.isFinite(startMs) && Number.isFinite(endMs) && endMs > startMs;
123
- let wallTimeMs;
124
- if (hasRowDelta) {
125
- wallTimeMs = endMs - startMs;
126
- }
127
- else {
128
- const interval = Number.isFinite(startMs) ? findContainingTaskInterval(startMs, taskIntervals) : undefined;
129
- wallTimeMs = interval?.durationMs ?? 0;
130
- }
66
+ const wallTimeMs = Number.isFinite(startMs) && Number.isFinite(endMs) && endMs >= startMs ? endMs - startMs : 0;
131
67
  const taskId = matchImproveTaskId(row.started_at, row.completed_at, improveTaskRuns);
132
68
  summaries.push(projectImproveRunSummary(row, wallTimeMs, taskId));
133
69
  }
@@ -20,3 +20,10 @@ export const ENRICHMENT_MINTED_FAIL_SHARE = 0.15;
20
20
  * source so the advisory and the rendered badge cannot drift.
21
21
  */
22
22
  export const TASK_FAIL_RATE_WARN = 0.05;
23
+ /**
24
+ * Minimum task_history rows a single task_id needs in the window before its
25
+ * per-task fail rate feeds the `task-fail-rate` advisory's "worst single
26
+ * task" signal. Guards against a rarely-run task (e.g. 1 failure out of 1
27
+ * run) reading as a 100% fail rate off a single noisy sample.
28
+ */
29
+ export const MIN_ROWS_FOR_WORST_TASK_FAIL_RATE = 5;
@@ -7,8 +7,9 @@ import { resolveStashDir } from "../core/common.js";
7
7
  import { loadConfig } from "../core/config/config.js";
8
8
  import { ConfigError, UsageError } from "../core/errors.js";
9
9
  import { readEvents } from "../core/events.js";
10
+ import { listTxnJournalsTolerant, TXN_SWEEP_GRACE_MS } from "../core/fs-txn.js";
10
11
  import { openLogsDatabase } from "../core/logs-db.js";
11
- import { getCacheDir, getConfigDir, getConfigPath, getDataDir, getStateDbPathInDataDir } from "../core/paths.js";
12
+ import { getCacheDir, getConfigPath, getDataDir, getStateDbPathInDataDir } from "../core/paths.js";
12
13
  import { listExistingTableNames, openStateDatabase } from "../core/state-db.js";
13
14
  import { DURATION_UNITS, parseDuration, parseSinceToIso } from "../core/time.js";
14
15
  import { readSemanticStatus } from "../indexer/search/semantic-status.js";
@@ -22,7 +23,7 @@ import { computeDegradationMetrics, computeDenominatorFixedCoverage, computeEnri
22
23
  import { collectStashExposureAdvisory } from "./health/stash-exposure.js";
23
24
  import { collectSurfacesAdvisories } from "./health/surfaces.js";
24
25
  import { buildPerRunSummaries } from "./health/task-runs.js";
25
- import { ACTIVE_RUN_WARN_MS, IMPROVE_COMPLETED_EVENT, } from "./health/types.js";
26
+ import { ACTIVE_RUN_WARN_MS, IMPROVE_COMPLETED_EVENT, MIN_ROWS_FOR_WORST_TASK_FAIL_RATE, } from "./health/types.js";
26
27
  import { buildWindowMetrics, computeDeltas, partitionLogBackedRows, resolveWindowCompare } from "./health/windows.js";
27
28
  const DEFAULT_SINCE_MS = 24 * 60 * 60 * 1000;
28
29
  export function parseHealthSince(since) {
@@ -60,6 +61,52 @@ function validateAkmHealthOptions(options) {
60
61
  }
61
62
  }
62
63
  }
64
+ /**
65
+ * Item 7: dedupe stuck-active rows by task_id (keeping the oldest/largest age
66
+ * per id) so the `active-runs` check can name WHICH tasks are stuck instead of
67
+ * just a count. No pid/liveness probing — purely a projection of the rows
68
+ * already read.
69
+ */
70
+ function dedupeStuckActiveTasks(rows, now) {
71
+ const byTask = new Map();
72
+ for (const row of rows) {
73
+ const ageMs = now() - new Date(row.started_at).getTime();
74
+ const existing = byTask.get(row.task_id);
75
+ if (existing === undefined || ageMs > existing)
76
+ byTask.set(row.task_id, ageMs);
77
+ }
78
+ return [...byTask.entries()].map(([taskId, ageMs]) => ({ taskId, ageMs }));
79
+ }
80
+ /**
81
+ * Item 6: group task_history rows by task_id and return the one with the
82
+ * highest fail rate among tasks with at least MIN_ROWS_FOR_WORST_TASK_FAIL_RATE
83
+ * rows in the window — surfaces a consistently-failing task that a large,
84
+ * mostly-healthy population would otherwise hide behind the aggregate rate.
85
+ * `null` when no task_id meets the row-count floor. Ties break toward the
86
+ * task with more rows (a stronger signal), then by task_id for determinism.
87
+ */
88
+ function computeWorstTaskFailRate(rows) {
89
+ const byTask = new Map();
90
+ for (const row of rows) {
91
+ const entry = byTask.get(row.task_id) ?? { total: 0, failed: 0 };
92
+ entry.total += 1;
93
+ if (row.status === "failed")
94
+ entry.failed += 1;
95
+ byTask.set(row.task_id, entry);
96
+ }
97
+ let worst = null;
98
+ for (const [taskId, { total, failed }] of byTask) {
99
+ if (total < MIN_ROWS_FOR_WORST_TASK_FAIL_RATE)
100
+ continue;
101
+ const rate = failed / total;
102
+ if (worst === null ||
103
+ rate > worst.rate ||
104
+ (rate === worst.rate && (total > worst.rows || (total === worst.rows && taskId < worst.taskId)))) {
105
+ worst = { taskId, rate, rows: total };
106
+ }
107
+ }
108
+ return worst;
109
+ }
63
110
  /** Table presence, the state.db round-trip probe, and task_history-derived rates. */
64
111
  function gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now) {
65
112
  const tables = listExistingTableNames(db, ["events", "task_history", "proposals", "schema_migrations"]);
@@ -71,7 +118,7 @@ function gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now) {
71
118
  const { withLogs: taskRowsWithLogs, backed: existingLogRows } = partitionLogBackedRows(taskRows, logsDb);
72
119
  const failedTaskRows = taskRows.filter((row) => row.status === "failed");
73
120
  const activeRows = taskRows.filter((row) => row.status === "active" && row.completed_at === null);
74
- const stuckActiveRuns = activeRows.filter((row) => now() - new Date(row.started_at).getTime() > ACTIVE_RUN_WARN_MS).length;
121
+ const stuckActiveRows = activeRows.filter((row) => now() - new Date(row.started_at).getTime() > ACTIVE_RUN_WARN_MS);
75
122
  const promptRows = taskRows.filter((row) => row.target_kind === "prompt");
76
123
  const promptFailures = promptRows.filter((row) => {
77
124
  const detail = parseTaskMetadata(row).detail;
@@ -87,12 +134,45 @@ function gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now) {
87
134
  taskRowCount: taskRows.length,
88
135
  taskRowsWithLogsCount: taskRowsWithLogs.length,
89
136
  existingLogRowsCount: existingLogRows.length,
90
- stuckActiveRuns,
137
+ stuckActiveRuns: stuckActiveRows.length,
138
+ stuckActiveTasks: dedupeStuckActiveTasks(stuckActiveRows, now),
91
139
  logBackingRate,
92
140
  taskFailRate,
141
+ worstTaskFailRate: computeWorstTaskFailRate(taskRows),
93
142
  agentFailureRate,
94
143
  };
95
144
  }
145
+ /**
146
+ * Item 4: leftover durable-transaction journals under `$DATA/txn` (stranded
147
+ * recovery state seen twice in a real 0.9 migration) had zero health
148
+ * visibility. Uses the tolerant scan variant so one corrupt journal.json is
149
+ * counted rather than aborting the whole gather; a journal younger than
150
+ * {@link TXN_SWEEP_GRACE_MS} is presumed to belong to a currently-running
151
+ * operation and is not counted as stale. Best-effort: any unexpected error
152
+ * (e.g. a permissions issue under `$DATA/txn`) degrades to "no signal" rather
153
+ * than aborting the health report.
154
+ */
155
+ function gatherStaleTxnJournalsPhase(now) {
156
+ const dir = path.join(getDataDir(), "txn");
157
+ try {
158
+ const { matches, unreadableMtimes } = listTxnJournalsTolerant(() => true);
159
+ const nowMs = now();
160
+ const staleAges = [
161
+ ...matches.map((m) => nowMs - m.mtimeMs),
162
+ ...unreadableMtimes.map((mtimeMs) => nowMs - mtimeMs),
163
+ ].filter((ageMs) => ageMs >= TXN_SWEEP_GRACE_MS);
164
+ const staleUnreadableCount = unreadableMtimes.filter((mtimeMs) => nowMs - mtimeMs >= TXN_SWEEP_GRACE_MS).length;
165
+ return {
166
+ dir,
167
+ count: staleAges.length,
168
+ oldestAgeMs: staleAges.length > 0 ? Math.max(...staleAges) : null,
169
+ unreadable: staleUnreadableCount,
170
+ };
171
+ }
172
+ catch {
173
+ return { dir, count: 0, oldestAgeMs: null, unreadable: 0 };
174
+ }
175
+ }
96
176
  /**
97
177
  * Semantic-search status + the config fields the embedding-endpoint and
98
178
  * surfaces advisories need. Best-effort: an unloadable config leaves the
@@ -148,8 +228,8 @@ function gatherImproveSummaryPhase(db, stateDbPath, since, now) {
148
228
  /**
149
229
  * The three best-effort advisory groups beyond the health-check registry:
150
230
  * improve advisories, the `stash-git-exposure` probe, and the 08 surfaces
151
- * group (secret-file-perms, binary-config-skew, orphan-stores,
152
- * egress-endpoints). Order matches emission order in the returned array. A
231
+ * group (secret-file-perms, binary-config-skew, egress-endpoints). Order
232
+ * matches emission order in the returned array. A
153
233
  * probe/filesystem failure in either try/catch must not abort the health
154
234
  * report — each group degrades to "no advisory" independently.
155
235
  */
@@ -175,14 +255,12 @@ function gatherAncillaryAdvisories(db, stateDbPath, since, improveSummary, optio
175
255
  // Non-fatal — a git/probe failure must not abort the health report.
176
256
  }
177
257
  // 08 surfaces: the remaining read-only advisory group (secret-file-perms,
178
- // binary-config-skew, orphan-stores, egress-endpoints). Best-effort — a
258
+ // binary-config-skew, egress-endpoints). Best-effort — a
179
259
  // filesystem probe failure must not abort the health report.
180
260
  try {
181
261
  advisories.push(...collectSurfacesAdvisories({
182
262
  stashDir: options.stashDir ?? resolveStashDir(),
183
263
  cacheDir: getCacheDir(),
184
- dataDir: getDataDir(),
185
- configDir: getConfigDir(),
186
264
  configPath: getConfigPath(),
187
265
  config: egressConfigView,
188
266
  }));
@@ -209,11 +287,10 @@ function gatherSessionLogAdvisories(since, now, getExecutionLogCandidatesFn) {
209
287
  }
210
288
  /**
211
289
  * Phase 3 — window-compare mode. Resolves `--window-compare`/`--windows` into
212
- * per-window bundles, then folds window 0 back onto the top-level
213
- * improve/metrics/since fields (backward compat with the non-window-compare
214
- * shape) and computes deltas between the earliest and latest window.
290
+ * per-window bundles and computes deltas between the earliest and latest
291
+ * window. Top-level metrics retain the primary `--since` query.
215
292
  */
216
- function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb, probe, improveSummary, metrics, since) {
293
+ function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb) {
217
294
  let windowSpecs;
218
295
  if (options.windowCompare) {
219
296
  windowSpecs = resolveWindowCompare(options.windowCompare, now);
@@ -223,9 +300,6 @@ function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb, probe,
223
300
  }
224
301
  let windowResults;
225
302
  let deltas;
226
- let topLevelImprove = improveSummary;
227
- let topLevelMetrics = metrics;
228
- let topLevelSince = since;
229
303
  if (windowSpecs) {
230
304
  windowResults = windowSpecs.map((spec) => {
231
305
  const winSince = parseHealthSince(spec.since);
@@ -240,13 +314,6 @@ function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb, probe,
240
314
  metrics: bundle.metrics,
241
315
  };
242
316
  });
243
- // Preserve backward compat: top-level improve/metrics reflect window 0.
244
- if (windowResults.length > 0) {
245
- const firstWindow = windowResults[0];
246
- topLevelImprove = firstWindow.improve;
247
- topLevelMetrics = { ...firstWindow.metrics, probeRoundTripMs: probe.durationMs };
248
- topLevelSince = firstWindow.since;
249
- }
250
317
  if (windowResults.length >= 2) {
251
318
  // Deltas always read chronologically: `from` = earliest window,
252
319
  // `to` = latest. Positive pctChange on a failure metric (e.g.
@@ -259,7 +326,7 @@ function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb, probe,
259
326
  deltas = computeDeltas(sorted[0], sorted[sorted.length - 1]);
260
327
  }
261
328
  }
262
- return { windowResults, deltas, topLevelImprove, topLevelMetrics, topLevelSince };
329
+ return { windowResults, deltas };
263
330
  }
264
331
  export function akmHealth(options = {}) {
265
332
  validateAkmHealthOptions(options);
@@ -289,6 +356,7 @@ export function akmHealth(options = {}) {
289
356
  try {
290
357
  const taskHistory = gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now);
291
358
  const { tableNames, missingTables, probe } = taskHistory;
359
+ const staleTxnJournals = gatherStaleTxnJournalsPhase(now);
292
360
  const { semanticStatus, semanticSearchMode, embeddingEndpoint, egressConfigView } = gatherSemanticConfigPhase();
293
361
  const { improveSummary } = gatherImproveSummaryPhase(db, stateDbPath, since, now);
294
362
  advisories.push(...gatherAncillaryAdvisories(db, stateDbPath, since, improveSummary, options, egressConfigView));
@@ -309,6 +377,9 @@ export function akmHealth(options = {}) {
309
377
  existingLogRowsCount: taskHistory.existingLogRowsCount,
310
378
  logBackingRate: taskHistory.logBackingRate,
311
379
  stuckActiveRuns: taskHistory.stuckActiveRuns,
380
+ stuckActiveTasks: taskHistory.stuckActiveTasks,
381
+ worstTaskFailRate: taskHistory.worstTaskFailRate,
382
+ staleTxnJournals,
312
383
  semanticStatus,
313
384
  semanticSearchMode,
314
385
  embeddingEndpoint,
@@ -335,7 +406,7 @@ export function akmHealth(options = {}) {
335
406
  const deterministicWarnings = [...hardChecks, ...advisories].some((check) => check.status === "warn" && check.kind === "deterministic");
336
407
  const status = hardFailure ? "fail" : deterministicWarnings ? "warn" : "pass";
337
408
  // ── Window-compare mode (Phase 3) ─────────────────────────────────────
338
- const { windowResults, deltas, topLevelImprove, topLevelMetrics, topLevelSince } = resolveWindowComparePhase(options, db, stateDbPath, now, logsDb, probe, improveSummary, metrics, since);
409
+ const { windowResults, deltas } = resolveWindowComparePhase(options, db, stateDbPath, now, logsDb);
339
410
  // ── Per-run mode (Phase 2) ────────────────────────────────────────────
340
411
  let runs;
341
412
  if (options.groupBy === "run") {
@@ -345,11 +416,11 @@ export function akmHealth(options = {}) {
345
416
  schemaVersion: 3,
346
417
  ok: !hardFailure,
347
418
  status,
348
- since: topLevelSince,
419
+ since,
349
420
  hardChecks,
350
421
  advisories,
351
- metrics: topLevelMetrics,
352
- improve: topLevelImprove,
422
+ metrics,
423
+ improve: improveSummary,
353
424
  sessionLogAdvisories: sessionLogEntries,
354
425
  ...(runs ? { runs } : {}),
355
426
  ...(windowResults ? { windows: windowResults } : {}),
@@ -91,8 +91,8 @@ export function checkMergeInformationFloor(mergedBody, mergedSourceRefs, partici
91
91
  const required = new Set();
92
92
  for (const p of participants) {
93
93
  required.add(p.ref);
94
- for (const sr of p.sourceRefs)
95
- required.add(sr);
94
+ for (const xref of p.xrefs)
95
+ required.add(xref);
96
96
  }
97
97
  const after = new Set(mergedSourceRefs);
98
98
  const missing = [...required].filter((r) => !after.has(r));
@@ -0,0 +1,68 @@
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 { IMPROVE_AUTONOMY_CONFIG_KEY, isImproveAutonomyEnabled, } from "../../core/config/experimental.js";
5
+ /** The lanes `experimental.improveAutonomy` gates. */
6
+ export const AUTONOMY_LANES = ["memoryInference", "triagePromote", "memoryCleanup"];
7
+ const LANE_REASONS = {
8
+ memoryInference: "writes derived memory children and rewrites parent frontmatter",
9
+ triagePromote: "auto-accepts queued proposals into the stash (downgraded to queue)",
10
+ memoryCleanup: "rewrites belief-state frontmatter and moves files into the cleanup archive",
11
+ };
12
+ /**
13
+ * The lanes that bypass the strategy config and ask the gate at their own call
14
+ * site. They have no `processes.<name>.enabled` flag to downgrade, so
15
+ * {@link applyAutonomyGate} cannot see them — anything reporting the full gated
16
+ * set has to add these.
17
+ */
18
+ export const DIRECT_AUTONOMY_LANES = ["memoryCleanup"];
19
+ function gatedLane(lane) {
20
+ return { lane, configKey: IMPROVE_AUTONOMY_CONFIG_KEY, reason: LANE_REASONS[lane] };
21
+ }
22
+ /**
23
+ * Describe lanes for reporting — the warning line, the `improve_skipped` event,
24
+ * and `akm task doctor` all render the same {@link GatedLane} shape, so the
25
+ * lane name, config key, and reason cannot drift between the three surfaces.
26
+ */
27
+ export function describeGatedLanes(lanes) {
28
+ return lanes.map(gatedLane);
29
+ }
30
+ /** Configured capabilities that tasks doctor reports behind the autonomy gate. */
31
+ export function configuredDirectAutonomyLanes() {
32
+ return ["memoryCleanup"];
33
+ }
34
+ /**
35
+ * True when a lane may mutate. Used by the lane that bypasses the strategy
36
+ * config; the other three are handled by {@link applyAutonomyGate}.
37
+ */
38
+ export function isAutonomyLaneAllowed(_lane, config) {
39
+ // Every lane shares one opt-in today. The parameter is kept so a call site
40
+ // names the lane it is asking about — that name is what reaches the operator
41
+ // in the skip event — and so a future per-lane split does not have to revisit
42
+ // every caller.
43
+ return isImproveAutonomyEnabled(config);
44
+ }
45
+ /**
46
+ * Downgrade a strategy config to review-first unless autonomy is opted into.
47
+ *
48
+ * Returns the config to actually run plus every downgrade made. With autonomy on
49
+ * the input is returned untouched and `gated` is empty.
50
+ */
51
+ export function applyAutonomyGate(strategy, config) {
52
+ if (isImproveAutonomyEnabled(config))
53
+ return { config: strategy, gated: [] };
54
+ const gated = [];
55
+ const processes = { ...(strategy.processes ?? {}) };
56
+ if (processes.memoryInference?.enabled === true) {
57
+ processes.memoryInference = { ...processes.memoryInference, enabled: false };
58
+ gated.push(gatedLane("memoryInference"));
59
+ }
60
+ // Triage stays ENABLED — queued proposals are still triaged, they just are not
61
+ // auto-accepted. Disabling it would remove review work the user asked for,
62
+ // which is the opposite of what a review-first default should do.
63
+ if (processes.triage?.applyMode === "promote") {
64
+ processes.triage = { ...processes.triage, applyMode: "queue" };
65
+ gated.push(gatedLane("triagePromote"));
66
+ }
67
+ return { config: { ...strategy, processes }, gated };
68
+ }