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
@@ -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";
@@ -18,11 +19,11 @@ import { collectImproveAdvisories } from "./health/advisories.js";
18
19
  import { HEALTH_CHECKS } from "./health/checks.js";
19
20
  import { buildImproveSkipSummary, computeWallTimeStats, parseTaskMetadata, roundRate, summarizeImproveCompleted, summarizeImproveRuns, } from "./health/improve-metrics.js";
20
21
  import { readLlmUsageAggregate } from "./health/llm-usage.js";
21
- import { computeDegradationMetrics, computeDenominatorFixedCoverage, computeEnrichmentMintingRollup, probeStateDbRoundTrip, readCalibration, } from "./health/metrics.js";
22
+ import { computeDegradationMetrics, computeDenominatorFixedCoverage, computeEnrichmentMintingRollup, probeStateDbRoundTrip, } from "./health/metrics.js";
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,273 @@ 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
+ }
110
+ /** Table presence, the state.db round-trip probe, and task_history-derived rates. */
111
+ function gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now) {
112
+ const tables = listExistingTableNames(db, ["events", "task_history", "proposals", "schema_migrations"]);
113
+ const tableNames = tables.map((row) => row.name).sort();
114
+ const requiredTables = ["events", "proposals", "schema_migrations", "task_history"];
115
+ const missingTables = requiredTables.filter((name) => !tableNames.includes(name));
116
+ const probe = probeStateDbRoundTrip(stateDbPath);
117
+ const taskRows = queryTaskHistory(db, { since });
118
+ const { withLogs: taskRowsWithLogs, backed: existingLogRows } = partitionLogBackedRows(taskRows, logsDb);
119
+ const failedTaskRows = taskRows.filter((row) => row.status === "failed");
120
+ const activeRows = taskRows.filter((row) => row.status === "active" && row.completed_at === null);
121
+ const stuckActiveRows = activeRows.filter((row) => now() - new Date(row.started_at).getTime() > ACTIVE_RUN_WARN_MS);
122
+ const promptRows = taskRows.filter((row) => row.target_kind === "prompt");
123
+ const promptFailures = promptRows.filter((row) => {
124
+ const detail = parseTaskMetadata(row).detail;
125
+ return typeof detail?.reason === "string" && detail.reason.length > 0;
126
+ });
127
+ const logBackingRate = taskRowsWithLogs.length === 0 ? 1 : existingLogRows.length / taskRowsWithLogs.length;
128
+ const taskFailRate = taskRows.length === 0 ? 0 : failedTaskRows.length / taskRows.length;
129
+ const agentFailureRate = promptRows.length === 0 ? 0 : promptFailures.length / promptRows.length;
130
+ return {
131
+ tableNames,
132
+ missingTables,
133
+ probe,
134
+ taskRowCount: taskRows.length,
135
+ taskRowsWithLogsCount: taskRowsWithLogs.length,
136
+ existingLogRowsCount: existingLogRows.length,
137
+ stuckActiveRuns: stuckActiveRows.length,
138
+ stuckActiveTasks: dedupeStuckActiveTasks(stuckActiveRows, now),
139
+ logBackingRate,
140
+ taskFailRate,
141
+ worstTaskFailRate: computeWorstTaskFailRate(taskRows),
142
+ agentFailureRate,
143
+ };
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
+ }
176
+ /**
177
+ * Semantic-search status + the config fields the embedding-endpoint and
178
+ * surfaces advisories need. Best-effort: an unloadable config leaves the
179
+ * config-derived fields undefined and callers fall back to generic messages.
180
+ */
181
+ function gatherSemanticConfigPhase() {
182
+ const semanticStatus = readSemanticStatus();
183
+ let semanticSearchMode;
184
+ let embeddingEndpoint;
185
+ let egressConfigView;
186
+ try {
187
+ const config = loadConfig();
188
+ semanticSearchMode = config.semanticSearchMode;
189
+ embeddingEndpoint = config.embedding?.endpoint;
190
+ egressConfigView = config;
191
+ }
192
+ catch {
193
+ // fall through with undefined
194
+ }
195
+ return { semanticStatus, semanticSearchMode, embeddingEndpoint, egressConfigView };
196
+ }
197
+ /**
198
+ * Assemble the window's improve-pipeline summary: invoked/completed/skipped
199
+ * counts from events, the per-run result_json aggregate, wall-time stats, and
200
+ * the WS-5 coverage/degradation/enrichment-minting rollups.
201
+ */
202
+ function gatherImproveSummaryPhase(db, stateDbPath, since, now) {
203
+ const improveInvoked = readEvents({ since, type: "improve_invoked" }, { dbPath: stateDbPath }).events.length;
204
+ const improveCompletedEvents = readEvents({ since, type: IMPROVE_COMPLETED_EVENT }, { dbPath: stateDbPath }).events;
205
+ const improveSkippedEvents = readEvents({ since, type: "improve_skipped" }, { dbPath: stateDbPath }).events;
206
+ const eventsMetrics = summarizeImproveCompleted(improveCompletedEvents);
207
+ const { metrics: improveSummary } = summarizeImproveRuns(db, since);
208
+ improveSummary.invoked = improveInvoked;
209
+ improveSummary.completed = eventsMetrics.completed;
210
+ const skipSummary = buildImproveSkipSummary(improveSkippedEvents);
211
+ improveSummary.skipped = skipSummary.skipped;
212
+ improveSummary.skipReasons = skipSummary.skipReasons;
213
+ const perRunSummaries = buildPerRunSummaries(db, since);
214
+ const wallTimes = perRunSummaries.map((run) => run.wallTimeMs).filter((ms) => Number.isFinite(ms) && ms > 0);
215
+ improveSummary.wallTime = computeWallTimeStats(wallTimes, improveSummary.wallTime.byPhase);
216
+ // WS-5: Compute denominator-fixed coverage and per-run degradation metrics
217
+ // for the main health path (not just window-compare mode).
218
+ const until = new Date(now()).toISOString();
219
+ const totalAssetsMain = improveSummary.memorySummary.eligible + improveSummary.memorySummary.derived;
220
+ improveSummary.coverage = computeDenominatorFixedCoverage(db, totalAssetsMain, improveSummary.memorySummary.eligible, since, until);
221
+ const degradationMain = computeDegradationMetrics(db, since, until);
222
+ if (degradationMain) {
223
+ improveSummary.degradation = degradationMain;
224
+ }
225
+ improveSummary.enrichmentMinting = computeEnrichmentMintingRollup(db, since, until);
226
+ return { improveSummary, perRunSummaries };
227
+ }
228
+ /**
229
+ * The three best-effort advisory groups beyond the health-check registry:
230
+ * improve advisories, the `stash-git-exposure` probe, and the 08 surfaces
231
+ * group (secret-file-perms, binary-config-skew, egress-endpoints). Order
232
+ * matches emission order in the returned array. A
233
+ * probe/filesystem failure in either try/catch must not abort the health
234
+ * report — each group degrades to "no advisory" independently.
235
+ */
236
+ function gatherAncillaryAdvisories(db, stateDbPath, since, improveSummary, options, egressConfigView) {
237
+ const advisories = [...collectImproveAdvisories(db, stateDbPath, since, improveSummary)];
238
+ // 08-F1: surface a `stash-git-exposure` advisory when env/secret assets are
239
+ // git-tracked AND a remote is configured (the leak moment). Best-effort.
240
+ // Cheap guard: only shell out to git when the stash has its OWN `.git` (or a
241
+ // test injected a fake seam), so the hot path never spawns for a non-git
242
+ // stash — the common unit-test case. Trade-off: a stash manually pointed at a
243
+ // bare subdirectory of a parent git repo (no `.git` of its own) is not
244
+ // checked. akm-init always creates `.git` at the stash root, so any
245
+ // akm-initialised stash is covered; this only skips hand-pointed nested ones.
246
+ try {
247
+ const exposureStashDir = options.stashDir ?? resolveStashDir();
248
+ if (options.stashExposureGit || fs.existsSync(path.join(exposureStashDir, ".git"))) {
249
+ const stashExposure = collectStashExposureAdvisory(exposureStashDir, options.stashExposureGit);
250
+ if (stashExposure)
251
+ advisories.push(stashExposure);
252
+ }
253
+ }
254
+ catch {
255
+ // Non-fatal — a git/probe failure must not abort the health report.
256
+ }
257
+ // 08 surfaces: the remaining read-only advisory group (secret-file-perms,
258
+ // binary-config-skew, egress-endpoints). Best-effort — a
259
+ // filesystem probe failure must not abort the health report.
260
+ try {
261
+ advisories.push(...collectSurfacesAdvisories({
262
+ stashDir: options.stashDir ?? resolveStashDir(),
263
+ cacheDir: getCacheDir(),
264
+ configPath: getConfigPath(),
265
+ config: egressConfigView,
266
+ }));
267
+ }
268
+ catch {
269
+ // Non-fatal.
270
+ }
271
+ return advisories;
272
+ }
273
+ /** Execution-log-derived session advisories. Best-effort: any failure yields an empty list. */
274
+ function gatherSessionLogAdvisories(since, now, getExecutionLogCandidatesFn) {
275
+ try {
276
+ const sinceDays = Math.max(0, Math.ceil((now() - new Date(since).getTime()) / (24 * 60 * 60 * 1000)));
277
+ return getExecutionLogCandidatesFn(sinceDays).map((entry) => ({
278
+ topic: entry.topic,
279
+ frequency: entry.frequency,
280
+ source: entry.source,
281
+ isFailurePattern: entry.isFailurePattern,
282
+ }));
283
+ }
284
+ catch {
285
+ return [];
286
+ }
287
+ }
288
+ /**
289
+ * Phase 3 — window-compare mode. Resolves `--window-compare`/`--windows` into
290
+ * per-window bundles and computes deltas between the earliest and latest
291
+ * window. Top-level metrics retain the primary `--since` query.
292
+ */
293
+ function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb) {
294
+ let windowSpecs;
295
+ if (options.windowCompare) {
296
+ windowSpecs = resolveWindowCompare(options.windowCompare, now);
297
+ }
298
+ else if (options.windows && options.windows.length > 0) {
299
+ windowSpecs = options.windows;
300
+ }
301
+ let windowResults;
302
+ let deltas;
303
+ if (windowSpecs) {
304
+ windowResults = windowSpecs.map((spec) => {
305
+ const winSince = parseHealthSince(spec.since);
306
+ const winUntil = spec.until ? parseHealthSince(spec.until) : new Date(now()).toISOString();
307
+ const bundle = buildWindowMetrics(db, stateDbPath, winSince, winUntil, now, logsDb);
308
+ return {
309
+ name: spec.name,
310
+ since: winSince,
311
+ until: winUntil,
312
+ runs: bundle.runs,
313
+ improve: bundle.improve,
314
+ metrics: bundle.metrics,
315
+ };
316
+ });
317
+ if (windowResults.length >= 2) {
318
+ // Deltas always read chronologically: `from` = earliest window,
319
+ // `to` = latest. Positive pctChange on a failure metric (e.g.
320
+ // distill.llmFailed) means things got WORSE going forward in
321
+ // time; negative means improvement. Window 0 in the output
322
+ // array is whatever the user specified first (typically
323
+ // `current` for --window-compare), but the delta direction is
324
+ // independent of that array order.
325
+ const sorted = [...windowResults].sort((a, b) => new Date(a.since).getTime() - new Date(b.since).getTime());
326
+ deltas = computeDeltas(sorted[0], sorted[sorted.length - 1]);
327
+ }
328
+ }
329
+ return { windowResults, deltas };
330
+ }
63
331
  export function akmHealth(options = {}) {
64
332
  validateAkmHealthOptions(options);
65
333
  const now = options.now ?? (() => Date.now());
@@ -86,112 +354,13 @@ export function akmHealth(options = {}) {
86
354
  logsDb = undefined;
87
355
  }
88
356
  try {
89
- const tables = listExistingTableNames(db, ["events", "task_history", "proposals", "schema_migrations"]);
90
- const tableNames = tables.map((row) => row.name).sort();
91
- const requiredTables = ["events", "proposals", "schema_migrations", "task_history"];
92
- const missingTables = requiredTables.filter((name) => !tableNames.includes(name));
93
- const probe = probeStateDbRoundTrip(stateDbPath);
94
- const taskRows = queryTaskHistory(db, { since });
95
- const { withLogs: taskRowsWithLogs, backed: existingLogRows } = partitionLogBackedRows(taskRows, logsDb);
96
- const failedTaskRows = taskRows.filter((row) => row.status === "failed");
97
- const activeRows = taskRows.filter((row) => row.status === "active");
98
- const stuckActiveRuns = activeRows.filter((row) => now() - new Date(row.started_at).getTime() > ACTIVE_RUN_WARN_MS).length;
99
- const promptRows = taskRows.filter((row) => row.target_kind === "prompt");
100
- const promptFailures = promptRows.filter((row) => {
101
- const detail = parseTaskMetadata(row).detail;
102
- return typeof detail?.reason === "string" && detail.reason.length > 0;
103
- });
104
- const logBackingRate = taskRowsWithLogs.length === 0 ? 1 : existingLogRows.length / taskRowsWithLogs.length;
105
- const taskFailRate = taskRows.length === 0 ? 0 : failedTaskRows.length / taskRows.length;
106
- const agentFailureRate = promptRows.length === 0 ? 0 : promptFailures.length / promptRows.length;
107
- const semanticStatus = readSemanticStatus();
108
- // For the embedding-endpoint advisory. Best-effort: an unloadable config
109
- // leaves both undefined and the check falls back to its generic message.
110
- let semanticSearchMode;
111
- let embeddingEndpoint;
112
- let egressConfigView;
113
- try {
114
- const config = loadConfig();
115
- semanticSearchMode = config.semanticSearchMode;
116
- embeddingEndpoint = config.embedding?.endpoint;
117
- egressConfigView = config;
118
- }
119
- catch {
120
- // fall through with undefined
121
- }
122
- const improveInvoked = readEvents({ since, type: "improve_invoked" }, { dbPath: stateDbPath }).events.length;
123
- const improveCompletedEvents = readEvents({ since, type: IMPROVE_COMPLETED_EVENT }, { dbPath: stateDbPath }).events;
124
- const improveSkippedEvents = readEvents({ since, type: "improve_skipped" }, { dbPath: stateDbPath }).events;
125
- const eventsMetrics = summarizeImproveCompleted(improveCompletedEvents);
126
- const { metrics: improveSummary } = summarizeImproveRuns(db, since);
127
- improveSummary.invoked = improveInvoked;
128
- improveSummary.completed = eventsMetrics.completed;
129
- const skipSummary = buildImproveSkipSummary(improveSkippedEvents);
130
- improveSummary.skipped = skipSummary.skipped;
131
- improveSummary.skipReasons = skipSummary.skipReasons;
132
- const perRunSummaries = buildPerRunSummaries(db, since);
133
- const wallTimes = perRunSummaries.map((run) => run.wallTimeMs).filter((ms) => Number.isFinite(ms) && ms > 0);
134
- improveSummary.wallTime = computeWallTimeStats(wallTimes, improveSummary.wallTime.byPhase);
135
- improveSummary.calibration = readCalibration(db, since);
136
- // WS-5: Compute denominator-fixed coverage and per-run degradation metrics
137
- // for the main health path (not just window-compare mode).
138
- const until = new Date(now()).toISOString();
139
- const totalAssetsMain = improveSummary.memorySummary.eligible + improveSummary.memorySummary.derived;
140
- improveSummary.coverage = computeDenominatorFixedCoverage(db, totalAssetsMain, improveSummary.memorySummary.eligible, since, until);
141
- const degradationMain = computeDegradationMetrics(db, since, until);
142
- if (degradationMain) {
143
- improveSummary.degradation = degradationMain;
144
- }
145
- improveSummary.enrichmentMinting = computeEnrichmentMintingRollup(db, since, until);
146
- advisories.push(...collectImproveAdvisories(db, stateDbPath, since, improveSummary));
147
- // 08-F1: surface a `stash-git-exposure` advisory when env/secret assets are
148
- // git-tracked AND a remote is configured (the leak moment). Best-effort.
149
- // Cheap guard: only shell out to git when the stash has its OWN `.git` (or a
150
- // test injected a fake seam), so the hot path never spawns for a non-git
151
- // stash — the common unit-test case. Trade-off: a stash manually pointed at a
152
- // bare subdirectory of a parent git repo (no `.git` of its own) is not
153
- // checked. akm-init always creates `.git` at the stash root, so any
154
- // akm-initialised stash is covered; this only skips hand-pointed nested ones.
155
- try {
156
- const exposureStashDir = options.stashDir ?? resolveStashDir();
157
- if (options.stashExposureGit || fs.existsSync(path.join(exposureStashDir, ".git"))) {
158
- const stashExposure = collectStashExposureAdvisory(exposureStashDir, options.stashExposureGit);
159
- if (stashExposure)
160
- advisories.push(stashExposure);
161
- }
162
- }
163
- catch {
164
- // Non-fatal — a git/probe failure must not abort the health report.
165
- }
166
- // 08 surfaces: the remaining read-only advisory group (secret-file-perms,
167
- // binary-config-skew, orphan-stores, egress-endpoints). Best-effort — a
168
- // filesystem probe failure must not abort the health report.
169
- try {
170
- advisories.push(...collectSurfacesAdvisories({
171
- stashDir: options.stashDir ?? resolveStashDir(),
172
- cacheDir: getCacheDir(),
173
- dataDir: getDataDir(),
174
- configDir: getConfigDir(),
175
- configPath: getConfigPath(),
176
- config: egressConfigView,
177
- }));
178
- }
179
- catch {
180
- // Non-fatal.
181
- }
182
- let sessionLogEntries = [];
183
- try {
184
- const sinceDays = Math.max(0, Math.ceil((now() - new Date(since).getTime()) / (24 * 60 * 60 * 1000)));
185
- sessionLogEntries = getExecutionLogCandidatesFn(sinceDays).map((entry) => ({
186
- topic: entry.topic,
187
- frequency: entry.frequency,
188
- source: entry.source,
189
- isFailurePattern: entry.isFailurePattern,
190
- }));
191
- }
192
- catch {
193
- sessionLogEntries = [];
194
- }
357
+ const taskHistory = gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now);
358
+ const { tableNames, missingTables, probe } = taskHistory;
359
+ const staleTxnJournals = gatherStaleTxnJournalsPhase(now);
360
+ const { semanticStatus, semanticSearchMode, embeddingEndpoint, egressConfigView } = gatherSemanticConfigPhase();
361
+ const { improveSummary } = gatherImproveSummaryPhase(db, stateDbPath, since, now);
362
+ advisories.push(...gatherAncillaryAdvisories(db, stateDbPath, since, improveSummary, options, egressConfigView));
363
+ const sessionLogEntries = gatherSessionLogAdvisories(since, now, getExecutionLogCandidatesFn);
195
364
  // Run the ordered health-check registry. Each check projects the shared
196
365
  // context computed above into one HealthCheckResult; `channel` routes it to
197
366
  // hardChecks or advisories. Declaration order in HEALTH_CHECKS is the
@@ -202,12 +371,15 @@ export function akmHealth(options = {}) {
202
371
  tableNames,
203
372
  missingTables,
204
373
  probe,
205
- taskRowCount: taskRows.length,
206
- taskFailRate,
207
- taskRowsWithLogsCount: taskRowsWithLogs.length,
208
- existingLogRowsCount: existingLogRows.length,
209
- logBackingRate,
210
- stuckActiveRuns,
374
+ taskRowCount: taskHistory.taskRowCount,
375
+ taskFailRate: taskHistory.taskFailRate,
376
+ taskRowsWithLogsCount: taskHistory.taskRowsWithLogsCount,
377
+ existingLogRowsCount: taskHistory.existingLogRowsCount,
378
+ logBackingRate: taskHistory.logBackingRate,
379
+ stuckActiveRuns: taskHistory.stuckActiveRuns,
380
+ stuckActiveTasks: taskHistory.stuckActiveTasks,
381
+ worstTaskFailRate: taskHistory.worstTaskFailRate,
382
+ staleTxnJournals,
211
383
  semanticStatus,
212
384
  semanticSearchMode,
213
385
  embeddingEndpoint,
@@ -223,10 +395,10 @@ export function akmHealth(options = {}) {
223
395
  advisories.push(result);
224
396
  }
225
397
  const metrics = {
226
- taskFailRate: roundRate(taskFailRate),
227
- agentFailureRate: roundRate(agentFailureRate),
228
- stuckActiveRuns,
229
- logBackingRate: roundRate(logBackingRate),
398
+ taskFailRate: roundRate(taskHistory.taskFailRate),
399
+ agentFailureRate: roundRate(taskHistory.agentFailureRate),
400
+ stuckActiveRuns: taskHistory.stuckActiveRuns,
401
+ logBackingRate: roundRate(taskHistory.logBackingRate),
230
402
  probeRoundTripMs: probe.durationMs,
231
403
  llmUsage: readLlmUsageAggregate(stateDbPath, since),
232
404
  };
@@ -234,64 +406,21 @@ export function akmHealth(options = {}) {
234
406
  const deterministicWarnings = [...hardChecks, ...advisories].some((check) => check.status === "warn" && check.kind === "deterministic");
235
407
  const status = hardFailure ? "fail" : deterministicWarnings ? "warn" : "pass";
236
408
  // ── Window-compare mode (Phase 3) ─────────────────────────────────────
237
- let windowSpecs;
238
- if (options.windowCompare) {
239
- windowSpecs = resolveWindowCompare(options.windowCompare, now);
240
- }
241
- else if (options.windows && options.windows.length > 0) {
242
- windowSpecs = options.windows;
243
- }
244
- let windowResults;
245
- let deltas;
246
- let topLevelImprove = improveSummary;
247
- let topLevelMetrics = metrics;
248
- let topLevelSince = since;
249
- if (windowSpecs && db) {
250
- windowResults = windowSpecs.map((spec) => {
251
- const winSince = parseHealthSince(spec.since);
252
- const winUntil = spec.until ? parseHealthSince(spec.until) : new Date(now()).toISOString();
253
- const bundle = buildWindowMetrics(db, stateDbPath, winSince, winUntil, now, logsDb);
254
- return {
255
- name: spec.name,
256
- since: winSince,
257
- until: winUntil,
258
- runs: bundle.runs,
259
- improve: bundle.improve,
260
- metrics: bundle.metrics,
261
- };
262
- });
263
- // Preserve backward compat: top-level improve/metrics reflect window 0.
264
- if (windowResults.length > 0) {
265
- topLevelImprove = windowResults[0].improve;
266
- topLevelMetrics = { ...windowResults[0].metrics, probeRoundTripMs: probe.durationMs };
267
- topLevelSince = windowResults[0].since;
268
- }
269
- if (windowResults.length >= 2) {
270
- // Deltas always read chronologically: `from` = earliest window,
271
- // `to` = latest. Positive pctChange on a failure metric (e.g.
272
- // distill.llmFailed) means things got WORSE going forward in
273
- // time; negative means improvement. Window 0 in the output
274
- // array is whatever the user specified first (typically
275
- // `current` for --window-compare), but the delta direction is
276
- // independent of that array order.
277
- const sorted = [...windowResults].sort((a, b) => new Date(a.since).getTime() - new Date(b.since).getTime());
278
- deltas = computeDeltas(sorted[0], sorted[sorted.length - 1]);
279
- }
280
- }
409
+ const { windowResults, deltas } = resolveWindowComparePhase(options, db, stateDbPath, now, logsDb);
281
410
  // ── Per-run mode (Phase 2) ────────────────────────────────────────────
282
411
  let runs;
283
412
  if (options.groupBy === "run") {
284
413
  runs = buildPerRunSummaries(db, since);
285
414
  }
286
415
  return {
287
- schemaVersion: 2,
416
+ schemaVersion: 3,
288
417
  ok: !hardFailure,
289
418
  status,
290
- since: topLevelSince,
419
+ since,
291
420
  hardChecks,
292
421
  advisories,
293
- metrics: topLevelMetrics,
294
- improve: topLevelImprove,
422
+ metrics,
423
+ improve: improveSummary,
295
424
  sessionLogAdvisories: sessionLogEntries,
296
425
  ...(runs ? { runs } : {}),
297
426
  ...(windowResults ? { windows: windowResults } : {}),
@@ -72,8 +72,8 @@ function distinctTokens(text) {
72
72
  }
73
73
  /**
74
74
  * A merge must strictly increase information (R5 §4.2):
75
- * 1. Provenance: the merged asset's `source_refs` must be a superset of the
76
- * union of all participants' `source_refs` plus the participant refs
75
+ * 1. Provenance: the merged asset's `xrefs` must be a superset of the union of
76
+ * all participants' `xrefs` plus the participant refs
77
77
  * themselves — provenance never shrinks through a merge.
78
78
  * 2. Specificity: distinctTokens(mergedBody) ≥ minSpecificityRetention ×
79
79
  * |union(distinctTokens(participant bodies))| — a merge that only
@@ -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));
@@ -111,7 +111,7 @@ export function checkMergeInformationFloor(mergedBody, mergedSourceRefs, partici
111
111
  const specificityOk = specificityRetention >= minRetention;
112
112
  const reasons = [];
113
113
  if (!provenanceOk) {
114
- reasons.push(`provenance shrank: merged source_refs missing ${missing.length} ref(s) (e.g. ${missing[0]})`);
114
+ reasons.push(`provenance shrank: merged xrefs missing ${missing.length} ref(s) (e.g. ${missing[0]})`);
115
115
  }
116
116
  if (!specificityOk) {
117
117
  reasons.push(`specificity retention ${specificityRetention.toFixed(2)} < ${minRetention} (merge genericized/shortened)`);
@@ -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
+ }