akm-cli 0.9.16 → 0.9.17-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (403) hide show
  1. package/CHANGELOG.md +2101 -0
  2. package/STABILITY.md +11 -10
  3. package/dist/akm +124 -193
  4. package/dist/akm-migrate +38 -19
  5. package/dist/assets/hints/cli-hints-full.md +6 -7
  6. package/dist/assets/improve-strategies/catchup.json +0 -3
  7. package/dist/assets/improve-strategies/consolidate.json +0 -1
  8. package/dist/assets/improve-strategies/default.json +1 -2
  9. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
  10. package/dist/assets/improve-strategies/quick.json +1 -2
  11. package/dist/assets/improve-strategies/reflect-distill.json +1 -2
  12. package/dist/assets/improve-strategies/thorough.json +0 -3
  13. package/dist/assets/prompts/consolidate-pair.md +20 -0
  14. package/dist/assets/prompts/consolidate-system.md +4 -11
  15. package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
  17. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
  18. package/dist/assets/templates/html/health.html +3 -5
  19. package/dist/cli/retired-commands.js +1 -1
  20. package/dist/cli/shared.js +6 -2
  21. package/dist/cli/unknown-flags.js +24 -1
  22. package/dist/cli.js +68 -10
  23. package/dist/commands/agent/agent-dispatch.js +1 -1
  24. package/dist/commands/command/command-execution.js +24 -62
  25. package/dist/commands/feedback-cli.js +0 -1
  26. package/dist/commands/health/accept-rate.js +6 -0
  27. package/dist/commands/health/archive-usage.js +92 -0
  28. package/dist/commands/health/checks.js +83 -74
  29. package/dist/commands/health/config-skew.js +38 -0
  30. package/dist/commands/health/data-dir-usage.js +25 -13
  31. package/dist/commands/health/egress.js +54 -0
  32. package/dist/commands/health/html-report.js +1 -42
  33. package/dist/commands/health/improve-metrics.js +136 -591
  34. package/dist/commands/health/md-report.js +1 -6
  35. package/dist/commands/health/plugin-staleness.js +53 -3
  36. package/dist/commands/health/renderers.js +12 -4
  37. package/dist/commands/health/report-view-model.js +14 -120
  38. package/dist/commands/health/types-improve.js +4 -19
  39. package/dist/commands/health/windows.js +64 -74
  40. package/dist/commands/health.js +145 -143
  41. package/dist/commands/improve/consolidate/chunking.js +26 -117
  42. package/dist/commands/improve/consolidate/continuity-check.js +137 -0
  43. package/dist/commands/improve/consolidate/pair-pass.js +791 -0
  44. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  45. package/dist/commands/improve/consolidate.js +589 -1127
  46. package/dist/commands/improve/content-hash.js +16 -24
  47. package/dist/commands/improve/distill/content-repair.js +18 -100
  48. package/dist/commands/improve/distill-guards.js +20 -81
  49. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  50. package/dist/commands/improve/distill.js +608 -1041
  51. package/dist/commands/improve/eligibility.js +126 -390
  52. package/dist/commands/improve/execution.js +8 -10
  53. package/dist/commands/improve/extract-prompt.js +1 -2
  54. package/dist/commands/improve/extract.js +487 -1046
  55. package/dist/commands/improve/feedback-valence.js +0 -25
  56. package/dist/commands/improve/improve-cli.js +75 -169
  57. package/dist/commands/improve/improve-result-file.js +10 -66
  58. package/dist/commands/improve/improve-strategies.js +52 -4
  59. package/dist/commands/improve/improve-usage-report.js +18 -64
  60. package/dist/commands/improve/improve.js +480 -1074
  61. package/dist/commands/improve/ledger.js +119 -0
  62. package/dist/commands/improve/locks.js +2 -8
  63. package/dist/commands/improve/loop-stages.js +415 -1073
  64. package/dist/commands/improve/memory/derived-ref.js +12 -77
  65. package/dist/commands/improve/memory/memory-belief.js +16 -118
  66. package/dist/commands/improve/memory/memory-improve.js +266 -14
  67. package/dist/commands/improve/outcome-loop.js +28 -156
  68. package/dist/commands/improve/planner.js +5 -15
  69. package/dist/commands/improve/preparation.js +779 -2319
  70. package/dist/commands/improve/proactive-maintenance.js +34 -101
  71. package/dist/commands/improve/reflect-noise.js +104 -280
  72. package/dist/commands/improve/reflect.js +642 -1353
  73. package/dist/commands/improve/retrieval-gate.js +127 -0
  74. package/dist/commands/improve/retrieval-scope.js +92 -0
  75. package/dist/commands/improve/salience.js +41 -240
  76. package/dist/commands/improve/session-asset.js +19 -100
  77. package/dist/commands/improve/stage.js +322 -0
  78. package/dist/commands/lint/base-linter.js +37 -15
  79. package/dist/commands/proposal/drain.js +261 -578
  80. package/dist/commands/proposal/proposal-cli.js +19 -20
  81. package/dist/commands/proposal/proposal-types.js +31 -24
  82. package/dist/commands/proposal/proposal.js +38 -8
  83. package/dist/commands/proposal/propose.js +134 -160
  84. package/dist/commands/proposal/repository.js +1097 -1394
  85. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  86. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  87. package/dist/commands/proposal/validators/proposals.js +22 -89
  88. package/dist/commands/read/curate.js +105 -462
  89. package/dist/commands/read/knowledge.js +3 -2
  90. package/dist/commands/read/search-cli.js +16 -33
  91. package/dist/commands/read/search.js +17 -23
  92. package/dist/commands/read/show.js +57 -108
  93. package/dist/commands/sources/bundle-cli.js +25 -2
  94. package/dist/commands/sources/bundle-config-ops.js +4 -0
  95. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  96. package/dist/commands/sources/info.js +127 -29
  97. package/dist/commands/sources/installed-stashes.js +197 -746
  98. package/dist/commands/sources/schema-repair.js +98 -129
  99. package/dist/commands/sources/source-add.js +62 -12
  100. package/dist/commands/sources/source-manage.js +9 -2
  101. package/dist/commands/sources/stash-cli.js +24 -4
  102. package/dist/commands/tasks/explain.js +10 -13
  103. package/dist/commands/tasks/tasks-cli.js +12 -13
  104. package/dist/commands/tasks/tasks.js +350 -936
  105. package/dist/commands/tasks/validate.js +26 -24
  106. package/dist/commands/workflow/plan.js +22 -29
  107. package/dist/commands/workflow-cli.js +4 -4
  108. package/dist/core/adapter/adapters/akm-adapter.js +2 -1
  109. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  110. package/dist/core/adapter/adapters/akm-metadata.js +42 -12
  111. package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
  112. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  113. package/dist/core/adapter/execution-source.js +17 -29
  114. package/dist/core/asset/asset-placement.js +4 -13
  115. package/dist/core/asset/frontmatter.js +106 -1
  116. package/dist/core/asset/resolve-ref.js +1 -1
  117. package/dist/core/bundle-id.js +42 -5
  118. package/dist/core/bundle-rename.js +285 -0
  119. package/dist/core/config/config-io.js +1 -2
  120. package/dist/core/config/config-schema.js +9 -34
  121. package/dist/core/config/config-walker.js +1 -1
  122. package/dist/core/config/config.js +184 -111
  123. package/dist/core/config/engine-semantics.js +0 -2
  124. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  125. package/dist/core/config/schema/embedding.js +20 -5
  126. package/dist/core/config/schema/engines.js +5 -0
  127. package/dist/core/config/schema/execution.js +1 -1
  128. package/dist/core/config/schema/experimental.js +1 -1
  129. package/dist/core/config/schema/improve-processes.js +54 -125
  130. package/dist/core/config/schema/improve.js +4 -42
  131. package/dist/core/config/schema/index-config.js +9 -48
  132. package/dist/core/config/schema/scheduler.js +12 -12
  133. package/dist/core/config/schema/search.js +6 -22
  134. package/dist/core/env-secret-ref.js +0 -1
  135. package/dist/core/errors.js +8 -9
  136. package/dist/core/file-change.js +13 -5
  137. package/dist/core/file-lock.js +76 -173
  138. package/dist/core/improve-result.js +35 -7
  139. package/dist/core/improve-types.js +0 -1
  140. package/dist/core/logs-db.js +2 -2
  141. package/dist/core/loopback.js +7 -12
  142. package/dist/core/non-task-input.js +20 -0
  143. package/dist/core/parse.js +13 -16
  144. package/dist/core/paths.js +0 -24
  145. package/dist/core/redaction.js +109 -2
  146. package/dist/core/run-lock.js +2 -5
  147. package/dist/core/spawn-env.js +1 -1
  148. package/dist/core/state/migrations.js +123 -61
  149. package/dist/core/state-db-scope.js +2 -4
  150. package/dist/core/state-db.js +126 -692
  151. package/dist/core/time.js +0 -20
  152. package/dist/core/type-presentation.js +1 -9
  153. package/dist/core/write-source.js +294 -1005
  154. package/dist/execution/input-contract.js +1 -1
  155. package/dist/execution/resolved-request.js +135 -689
  156. package/dist/execution/source.js +63 -257
  157. package/dist/execution/target-ref.js +1 -1
  158. package/dist/indexer/bundle-identity-guard.js +2 -2
  159. package/dist/indexer/db/llm-cache.js +2 -2
  160. package/dist/indexer/ensure-index.js +77 -73
  161. package/dist/indexer/index-rebuild-lock.js +3 -11
  162. package/dist/indexer/index-writer-lock.js +8 -17
  163. package/dist/indexer/index-written-assets.js +141 -154
  164. package/dist/indexer/indexer.js +400 -1124
  165. package/dist/indexer/links/declared-links.js +90 -0
  166. package/dist/indexer/materialize-embeddings.js +60 -397
  167. package/dist/indexer/passes/memory-inference.js +96 -90
  168. package/dist/indexer/passes/metadata.js +132 -219
  169. package/dist/indexer/read-preflight.js +0 -7
  170. package/dist/indexer/scan/doc-to-entry.js +2 -3
  171. package/dist/indexer/scan/drain-dir.js +1 -1
  172. package/dist/indexer/search/db-search.js +190 -590
  173. package/dist/indexer/search/fts-query.js +30 -41
  174. package/dist/indexer/search/ranking.js +28 -154
  175. package/dist/indexer/search/search-attribution.js +12 -32
  176. package/dist/indexer/search/search-fields.js +11 -15
  177. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  178. package/dist/indexer/search/search-source.js +1 -4
  179. package/dist/indexer/usage/usage-events.js +36 -7
  180. package/dist/indexer/walk/walker.js +3 -4
  181. package/dist/integrations/agent/engine-fallback.js +23 -40
  182. package/dist/integrations/agent/engine-resolution.js +93 -183
  183. package/dist/integrations/agent/execution.js +507 -0
  184. package/dist/integrations/agent/model-map.js +28 -156
  185. package/dist/integrations/agent/request-lowering.js +66 -141
  186. package/dist/integrations/agent/runner-dispatch.js +143 -321
  187. package/dist/integrations/agent/runner.js +54 -14
  188. package/dist/integrations/lockfile.js +53 -101
  189. package/dist/llm/client.js +18 -6
  190. package/dist/llm/embedders/deterministic.js +2 -3
  191. package/dist/llm/embedders/profile.js +71 -0
  192. package/dist/llm/embedders/remote.js +11 -17
  193. package/dist/llm/feature-gate.js +0 -8
  194. package/dist/llm/index-passes.js +3 -5
  195. package/dist/llm/memory-infer.js +1 -2
  196. package/dist/llm/structured-call.js +5 -24
  197. package/dist/output/generic-render.js +23 -11
  198. package/dist/output/html-render.js +13 -10
  199. package/dist/output/render-registry.js +3 -32
  200. package/dist/output/shapes/helpers.js +25 -38
  201. package/dist/output/shapes/passthrough.js +1 -9
  202. package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
  203. package/dist/output/text/command-format.js +69 -31
  204. package/dist/output/text/helpers.js +1 -1
  205. package/dist/output/text/migrate.js +5 -14
  206. package/dist/output/text/proposal-format.js +48 -3
  207. package/dist/output/text/show-format.js +13 -17
  208. package/dist/output/text/workflow-format.js +0 -32
  209. package/dist/output/text.js +2 -0
  210. package/dist/registry/factory.js +4 -19
  211. package/dist/registry/network.js +66 -220
  212. package/dist/registry/providers/index.js +0 -2
  213. package/dist/registry/providers/skills-sh.js +3 -14
  214. package/dist/registry/providers/static-index.js +24 -26
  215. package/dist/registry/resolve.js +55 -131
  216. package/dist/scripts/akm-migrate-node.js +42948 -92369
  217. package/dist/scripts/akm-migrate.js +42935 -92354
  218. package/dist/setup/registry-stash-loader.js +4 -13
  219. package/dist/setup/semantic-assets.js +3 -44
  220. package/dist/setup/setup.js +1 -1
  221. package/dist/setup/steps/connection.js +5 -6
  222. package/dist/setup/steps/platforms.js +2 -2
  223. package/dist/setup/steps/tasks.js +25 -15
  224. package/dist/sources/provider-factory.js +17 -18
  225. package/dist/sources/providers/filesystem.js +2 -3
  226. package/dist/sources/providers/git-install.js +7 -1
  227. package/dist/sources/providers/git-provider.js +0 -3
  228. package/dist/sources/providers/git-stash.js +83 -21
  229. package/dist/sources/providers/npm.js +2 -4
  230. package/dist/sources/providers/provider-utils.js +5 -10
  231. package/dist/sources/providers/website.js +0 -2
  232. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  233. package/dist/sources/website-url.js +2 -2
  234. package/dist/storage/database.js +9 -35
  235. package/dist/storage/repositories/improve-ledger-repository.js +209 -0
  236. package/dist/storage/repositories/index-connection.js +39 -72
  237. package/dist/storage/repositories/index-entries-repository.js +131 -129
  238. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  239. package/dist/storage/repositories/index-entry-schema.js +101 -268
  240. package/dist/storage/repositories/index-fts-repository.js +86 -256
  241. package/dist/storage/repositories/index-links-repository.js +143 -0
  242. package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
  243. package/dist/storage/repositories/index-meta-repository.js +6 -4
  244. package/dist/storage/repositories/index-schema.js +257 -325
  245. package/dist/storage/repositories/index-utility-repository.js +8 -29
  246. package/dist/storage/repositories/index-vec-repository.js +133 -414
  247. package/dist/storage/repositories/outcome-repository.js +2 -1
  248. package/dist/storage/repositories/proposals-repository.js +104 -1
  249. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  250. package/dist/storage/repositories/salience-repository.js +1 -19
  251. package/dist/storage/repositories/task-history-repository.js +26 -4
  252. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  253. package/dist/storage/sqlite-migrations.js +136 -0
  254. package/dist/storage/sqlite-pragmas.js +11 -9
  255. package/dist/storage/sqlite-transaction.js +170 -0
  256. package/dist/storage/state-db-integrity.js +130 -0
  257. package/dist/tasks/activation-config.js +134 -62
  258. package/dist/tasks/backends/cron.js +191 -302
  259. package/dist/tasks/backends/exec-utils.js +2 -5
  260. package/dist/tasks/backends/launchd.js +141 -748
  261. package/dist/tasks/backends/schtasks.js +119 -623
  262. package/dist/tasks/prepare/prepare-support.js +5 -15
  263. package/dist/tasks/prepare/prepare.js +0 -2
  264. package/dist/tasks/resolve-akm-bin.js +20 -79
  265. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  266. package/dist/tasks/run/load-task.js +1 -1
  267. package/dist/tasks/scheduler-binding.js +20 -238
  268. package/dist/tasks/scheduler-invocation.js +136 -244
  269. package/dist/tasks/scheduler-lock.js +53 -0
  270. package/dist/tasks/scheduler-sync.js +368 -679
  271. package/dist/tasks/source/parse-task-source.js +55 -9
  272. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  273. package/dist/tasks/source/task-to-v4.js +464 -88
  274. package/dist/workflows/authoring/authoring.js +3 -12
  275. package/dist/workflows/compile.js +211 -0
  276. package/dist/workflows/concurrency-policy.js +13 -74
  277. package/dist/workflows/exec/child-invocation.js +3 -17
  278. package/dist/workflows/exec/child-workflow.js +32 -141
  279. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  280. package/dist/workflows/exec/environment.js +98 -0
  281. package/dist/workflows/exec/exec-unit.js +33 -140
  282. package/dist/workflows/exec/frozen-judge.js +7 -59
  283. package/dist/workflows/exec/native-executor.js +82 -341
  284. package/dist/workflows/exec/param-secrets.js +29 -47
  285. package/dist/workflows/exec/run-workflow.js +154 -387
  286. package/dist/workflows/exec/scheduler.js +9 -36
  287. package/dist/workflows/exec/step-work.js +127 -430
  288. package/dist/workflows/exec/unit-dispatch.js +11 -63
  289. package/dist/workflows/exec/unit-writer.js +8 -52
  290. package/dist/workflows/exec/worktree.js +39 -273
  291. package/dist/workflows/freeze/child-output-references.js +4 -15
  292. package/dist/workflows/freeze/environment.js +99 -92
  293. package/dist/workflows/freeze/freeze.js +172 -0
  294. package/dist/workflows/freeze/step-values.js +19 -21
  295. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  296. package/dist/workflows/freeze/targets/command.js +10 -33
  297. package/dist/workflows/freeze/targets/script.js +5 -12
  298. package/dist/workflows/freeze/targets/shell.js +3 -6
  299. package/dist/workflows/freeze/targets/task.js +25 -80
  300. package/dist/workflows/freeze/task-bindings.js +20 -67
  301. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  302. package/dist/workflows/ir/params.js +6 -51
  303. package/dist/workflows/ir/plan-hash.js +2 -34
  304. package/dist/workflows/parser.js +140 -43
  305. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  306. package/dist/workflows/renderer.js +36 -69
  307. package/dist/workflows/resource-limits.js +12 -120
  308. package/dist/workflows/runtime/agent-identity.js +8 -40
  309. package/dist/workflows/runtime/run-outputs.js +3 -6
  310. package/dist/workflows/runtime/run-plan.js +316 -0
  311. package/dist/workflows/runtime/runs.js +48 -200
  312. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  313. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  314. package/dist/workflows/validate-summary.js +2 -7
  315. package/docs/integration/bundling-akm.md +49 -42
  316. package/docs/migration/README.md +1 -0
  317. package/docs/migration/release-notes/0.9.17.md +43 -0
  318. package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
  319. package/docs/reference/cli.md +232 -135
  320. package/docs/reference/configuration.md +71 -57
  321. package/docs/reference/data-and-telemetry.md +20 -21
  322. package/docs/reference/tasks.md +105 -39
  323. package/docs/reference/workflow-schema.md +14 -18
  324. package/docs/reference/workflows.md +6 -9
  325. package/package.json +1 -1
  326. package/schemas/akm-config.json +115 -738
  327. package/schemas/akm-workflow.json +1 -0
  328. package/dist/assets/improve-strategies/graph-refresh.json +0 -15
  329. package/dist/assets/prompts/contradiction-judge.md +0 -33
  330. package/dist/assets/prompts/graph-extract-system.md +0 -1
  331. package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
  332. package/dist/assets/prompts/metadata-enhance-system.md +0 -1
  333. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
  334. package/dist/commands/health/advisories.js +0 -150
  335. package/dist/commands/health/metrics.js +0 -329
  336. package/dist/commands/health/surfaces.js +0 -102
  337. package/dist/commands/improve/anti-collapse.js +0 -83
  338. package/dist/commands/improve/collapse-detector.js +0 -432
  339. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  340. package/dist/commands/improve/consolidate/merge.js +0 -149
  341. package/dist/commands/improve/distill/promote-memory.js +0 -291
  342. package/dist/commands/improve/distill/quality-gate.js +0 -337
  343. package/dist/commands/improve/eval-cases.js +0 -52
  344. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  345. package/dist/commands/improve/proposal-envelope.js +0 -31
  346. package/dist/commands/improve/run-context.js +0 -123
  347. package/dist/commands/improve/shared.js +0 -31
  348. package/dist/commands/improve/source-identity.js +0 -28
  349. package/dist/commands/improve/triage.js +0 -96
  350. package/dist/commands/proposal/drain-policies.js +0 -151
  351. package/dist/commands/sources/update-transaction.js +0 -220
  352. package/dist/core/action-contributors.js +0 -28
  353. package/dist/core/config/config-version-shim.js +0 -101
  354. package/dist/core/fs-txn.js +0 -405
  355. package/dist/core/lexical-score.js +0 -25
  356. package/dist/core/maintenance-barrier.js +0 -167
  357. package/dist/execution/executable-identity.js +0 -105
  358. package/dist/execution/guarded-source.js +0 -427
  359. package/dist/indexer/db/graph-db.js +0 -444
  360. package/dist/indexer/graph/graph-boost.js +0 -427
  361. package/dist/indexer/graph/graph-dedup.js +0 -95
  362. package/dist/indexer/graph/graph-extraction.js +0 -1108
  363. package/dist/indexer/search/name-match.js +0 -35
  364. package/dist/indexer/search/ranking-contributors.js +0 -515
  365. package/dist/indexer/search/ranking-types.js +0 -4
  366. package/dist/indexer/walk/project-context.js +0 -192
  367. package/dist/integrations/agent/execution-cascade.js +0 -566
  368. package/dist/integrations/agent/execution-definitions.js +0 -202
  369. package/dist/integrations/agent/execution-lowering.js +0 -841
  370. package/dist/integrations/agent/execution-preparation.js +0 -98
  371. package/dist/integrations/agent/inline-execution.js +0 -74
  372. package/dist/llm/graph-extract.js +0 -728
  373. package/dist/llm/metadata-enhance.js +0 -96
  374. package/dist/registry/create-provider-registry.js +0 -29
  375. package/dist/registry/pinned-request-helper.js +0 -247
  376. package/dist/registry/pinned-transport.js +0 -717
  377. package/dist/sources/providers/index.js +0 -14
  378. package/dist/storage/engines/sqlite-migrations.js +0 -271
  379. package/dist/storage/repositories/canaries-repository.js +0 -107
  380. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  381. package/dist/storage/repositories/registry-cache.js +0 -113
  382. package/dist/tasks/scheduler-sync-preview.js +0 -52
  383. package/dist/tasks/source/task-to-v3.js +0 -507
  384. package/dist/workflows/freeze/resolve-steps.js +0 -86
  385. package/dist/workflows/freeze/source-freeze.js +0 -64
  386. package/dist/workflows/ir/compile.js +0 -321
  387. package/dist/workflows/ir/environment-v4.js +0 -330
  388. package/dist/workflows/ir/freeze-v4.js +0 -153
  389. package/dist/workflows/ir/schema-v4.js +0 -745
  390. package/dist/workflows/ir/schema.js +0 -354
  391. package/dist/workflows/program/schema.js +0 -77
  392. package/dist/workflows/runtime/checkin.js +0 -57
  393. package/dist/workflows/runtime/plan-classifier.js +0 -196
  394. package/dist/workflows/runtime/unit-checkin.js +0 -45
  395. package/dist/workflows/runtime/unit-phases.js +0 -20
  396. package/dist/workflows/schema.js +0 -4
  397. package/dist/workflows/source-ir/compile.js +0 -200
  398. package/dist/workflows/source-ir/program.js +0 -50
  399. package/dist/workflows/source-ir/result.js +0 -26
  400. package/dist/workflows/source-ir/schema.js +0 -786
  401. package/dist/workflows/source-ir/triggers.js +0 -79
  402. package/dist/workflows/source-ir/uses.js +0 -40
  403. package/dist/workflows/validator.js +0 -60
@@ -0,0 +1,92 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * `memory-cleanup-archive` advisory for `akm health` (item 4, 0.9.17-alpha.9
6
+ * plan §5.4/§8 step 8).
7
+ *
8
+ * Reports the archive's size and file count for every bundle, git-backed or
9
+ * not. A bundle with no `.git` of its own keeps every retirement's archived
10
+ * bytes forever (the purge sweep never runs there at all), so that alone is
11
+ * reported. A git-backed bundle can ALSO have bytes the purge sweep will
12
+ * never remove: `.git` presence alone does not prove a retirement was ever
13
+ * committed (`proposal accept` only commits for a `kind: "git"` write
14
+ * target, and a `kind: "filesystem"` bundle that merely happens to have a
15
+ * `.git` directory never gets one) — those bytes sit there indefinitely,
16
+ * however old they get, with nothing else to say so. This checks the SAME
17
+ * git state `purgeGracedArchive` checks (tracked, clean, verifiable) and
18
+ * reports how much of the archive fails it.
19
+ *
20
+ * Silent whenever there is nothing to say: the archive does not exist or is
21
+ * empty, or (for a git-backed bundle) every byte in it is purgeable once it
22
+ * ages out.
23
+ */
24
+ import fs from "node:fs";
25
+ import path from "node:path";
26
+ import { MEMORY_ARCHIVE_REL } from "../../core/asset/memory-archive.js";
27
+ import { toPosix } from "../../core/common.js";
28
+ import { checkGitPathSafety, isGitBackedStash } from "../../sources/providers/git-stash.js";
29
+ import { MAX_WALK_ENTRIES, sizeOfPath } from "./data-dir-usage.js";
30
+ /**
31
+ * Build the `memory-cleanup-archive` advisory, or `undefined` when there is
32
+ * nothing to report.
33
+ */
34
+ export function collectArchiveUsageAdvisory(stashDir) {
35
+ const archiveRoot = path.join(stashDir, MEMORY_ARCHIVE_REL);
36
+ if (!fs.existsSync(archiveRoot))
37
+ return undefined;
38
+ if (!isGitBackedStash(stashDir)) {
39
+ const usage = sizeOfPath(archiveRoot, { remaining: MAX_WALK_ENTRIES });
40
+ if (usage.files === 0)
41
+ return undefined;
42
+ const lowerBound = usage.truncated ? ` (a lower bound — the walk stopped after ${MAX_WALK_ENTRIES} entries)` : "";
43
+ return {
44
+ name: "memory-cleanup-archive",
45
+ kind: "deterministic",
46
+ status: "pass",
47
+ confidence: "high",
48
+ message: `${usage.files} archived file(s), ${usage.bytes} byte(s)${lowerBound} in .akm/memory-cleanup/archive — ` +
49
+ "this bundle has no git history, so the purge sweep leaves it untouched.",
50
+ evidence: { files: usage.files, bytes: usage.bytes, truncated: usage.truncated },
51
+ };
52
+ }
53
+ // Git-backed: the SAME three checks purgeGracedArchive runs (B1, G10) —
54
+ // computed once here, not per file, and reused via `onFile` below instead
55
+ // of a second walk of the same tree. A failed git check here fails the
56
+ // same way purgeGracedArchive's own sweep would: nothing in the archive
57
+ // can be proven purgeable, so every byte counts as unpurgeable rather
58
+ // than guessing (`checkGitPathSafety`'s `isSafe` is always `false` when
59
+ // `ok` is `false`).
60
+ const gitSafety = checkGitPathSafety(stashDir, MEMORY_ARCHIVE_REL);
61
+ let unpurgeableFiles = 0;
62
+ let unpurgeableBytes = 0;
63
+ const usage = sizeOfPath(archiveRoot, { remaining: MAX_WALK_ENTRIES }, (filePath, bytes) => {
64
+ const key = toPosix(path.relative(stashDir, filePath));
65
+ if (!gitSafety.isSafe(key)) {
66
+ unpurgeableFiles++;
67
+ unpurgeableBytes += bytes;
68
+ }
69
+ });
70
+ if (usage.files === 0)
71
+ return undefined;
72
+ if (unpurgeableFiles === 0)
73
+ return undefined; // everything here is purgeable once it ages out — nothing to say
74
+ const lowerBound = usage.truncated ? ` (a lower bound — the walk stopped after ${MAX_WALK_ENTRIES} entries)` : "";
75
+ return {
76
+ name: "memory-cleanup-archive",
77
+ kind: "deterministic",
78
+ status: "warn",
79
+ confidence: "high",
80
+ message: `${usage.files} archived file(s), ${usage.bytes} byte(s)${lowerBound} in .akm/memory-cleanup/archive; ` +
81
+ `${unpurgeableFiles} file(s), ${unpurgeableBytes} byte(s) of that cannot be purged (untracked, modified, ` +
82
+ "or unverifiable in git) — commit them so the purge sweep can remove them once they age out.",
83
+ evidence: {
84
+ files: usage.files,
85
+ bytes: usage.bytes,
86
+ truncated: usage.truncated,
87
+ unpurgeableFiles,
88
+ unpurgeableBytes,
89
+ gitStateKnown: gitSafety.ok,
90
+ },
91
+ };
92
+ }
@@ -10,9 +10,10 @@ import { EXTRACT_INFRASTRUCTURE_SKIP_REASONS } from "../../core/improve-types.js
10
10
  import { listPendingStateMigrations } from "../../core/state-db.js";
11
11
  import { withEngineFallback } from "../../integrations/agent/engine-fallback.js";
12
12
  import { isLlmCredentialAvailable, resolveEngine, } from "../../integrations/agent/engine-resolution.js";
13
- import { executionEngineDefinitionsFromConfig } from "../../integrations/agent/execution-definitions.js";
13
+ import { executionEngineDefinitionsFromConfig } from "../../integrations/agent/execution.js";
14
14
  import { loadModelMap, mergeModelMapLayers, parseModelMapLayer, readInstalledModelMapText, resolveModelMapAlias, userModelMapPath, } from "../../integrations/agent/model-map.js";
15
15
  import { probeEndpointOnce } from "../../llm/client.js";
16
+ import { STATE_DB_FREELIST_WARN_RATIO, } from "../../storage/state-db-integrity.js";
16
17
  import { listKeys } from "../env/env.js";
17
18
  import { resolveImprovePlan } from "../improve/improve-strategies.js";
18
19
  import { ENGINE_LAST_USED_LOOKBACK_DAYS } from "./engine-usage.js";
@@ -783,16 +784,10 @@ export function runSelectedModelAliasesProbe(deps = {}) {
783
784
  };
784
785
  }
785
786
  /**
786
- * Hard check: state.db's migration ledger has no pending entries.
787
- *
788
- * Read-only via `listPendingStateMigrations` (a preflight open, never a
789
- * managed one), so running this check is always safe — even when the
790
- * corresponding managed open would refuse outright because a pending
791
- * migration is historical-destructive (see `beforeMigrationLocked` in
792
- * `src/core/state/migrations.ts`). This is what lets `akm health` report that
793
- * refusal as an ordinary `fail` check instead of crashing the whole command —
794
- * and what replaces a bundler grepping akm's refusal error text
795
- * to detect the same case.
787
+ * `state-db-migrations` when the open itself failed: the migrations still
788
+ * pending after a failed apply, from a read-only listing that never applies
789
+ * anything. A `fail` row, not a crash, is what a bundler watches for instead
790
+ * of grepping akm's error text.
796
791
  */
797
792
  export function runPendingStateMigrationsCheck(stateDbPath, deps = {}) {
798
793
  const pending = (deps.listPendingStateMigrations ?? listPendingStateMigrations)(stateDbPath);
@@ -816,6 +811,27 @@ export function runPendingStateMigrationsCheck(stateDbPath, deps = {}) {
816
811
  evidence: { path: stateDbPath, pending },
817
812
  };
818
813
  }
814
+ /**
815
+ * Hard check: state.db's ledger is current. Every open applies the pending
816
+ * migrations (copying the file aside first when one drops schema), so after
817
+ * health's own open nothing is pending; this names what that open applied, so
818
+ * an upgrade that migrated state.db is visible in the report.
819
+ */
820
+ export function appliedStateMigrationsCheck(stateDbPath, report) {
821
+ const { applied, backupPath } = report;
822
+ const range = applied.length > 1 ? `${applied[0]} … ${applied[applied.length - 1]}` : applied[0];
823
+ return {
824
+ name: "state-db-migrations",
825
+ kind: "deterministic",
826
+ status: "pass",
827
+ confidence: "high",
828
+ message: applied.length === 0
829
+ ? "state.db has no pending migrations."
830
+ : `Applied ${applied.length} pending state.db migration(s) on open (${range})` +
831
+ (backupPath ? `; the pre-migration copy is ${backupPath}.` : "."),
832
+ evidence: { path: stateDbPath, pending: [], applied, ...(backupPath ? { backupPath } : {}) },
833
+ };
834
+ }
819
835
  /**
820
836
  * #943: name the dominant `detail.reason` behind `task-fail-rate`'s warning
821
837
  * when one reason accounts for at least half of the window's command-task
@@ -868,10 +884,65 @@ export const HEALTH_CHECKS = [
868
884
  evidence: { path: ctx.stateDbPath, durationMs: ctx.probe.durationMs },
869
885
  }),
870
886
  },
887
+ {
888
+ // R0: nothing looked at state.db's own SQLite-level integrity before
889
+ // this — the round-trip probe above only proves one row can be appended
890
+ // and read back, which stays true on a database that fails
891
+ // `PRAGMA quick_check` elsewhere (corrupt indexes, out-of-order rowids).
892
+ // Also reports the freelist ratio (fraction of pages VACUUM could
893
+ // reclaim) so a bloated-but-uncorrupted file is visible as a warning
894
+ // rather than silence.
895
+ name: "state-db-integrity",
896
+ channel: "hard",
897
+ run: (ctx) => {
898
+ const { ok, lines, error } = ctx.stateDbIntegrity;
899
+ const { ratio: freelistRatio, error: freelistError } = ctx.stateDbFreelist;
900
+ if (!ok) {
901
+ const detail = error ?? lines.join("; ");
902
+ return {
903
+ name: "state-db-integrity",
904
+ kind: "deterministic",
905
+ status: "fail",
906
+ confidence: "high",
907
+ message: `state.db failed PRAGMA quick_check: ${detail}. Repair: back up state.db, then run ` +
908
+ `sqlite3 state.db ".recover" | sqlite3 state.new.db, verify state.new.db passes quick_check, stop ` +
909
+ "every akm process, then delete state.db-wal and state.db-shm before swapping state.new.db in as " +
910
+ "state.db — a leftover WAL from the OLD database is replayed onto the new one and corrupts it.",
911
+ evidence: { path: ctx.stateDbPath, lines, freelistRatio },
912
+ };
913
+ }
914
+ if (freelistError) {
915
+ return {
916
+ name: "state-db-integrity",
917
+ kind: "deterministic",
918
+ status: "fail",
919
+ confidence: "high",
920
+ message: `state.db passed PRAGMA quick_check, but reading its freelist/page-count failed: ${freelistError}.`,
921
+ evidence: { path: ctx.stateDbPath, lines, freelistError },
922
+ };
923
+ }
924
+ const freelistWarn = freelistRatio > STATE_DB_FREELIST_WARN_RATIO;
925
+ return {
926
+ name: "state-db-integrity",
927
+ kind: "deterministic",
928
+ status: freelistWarn ? "warn" : "pass",
929
+ confidence: "high",
930
+ message: freelistWarn
931
+ ? `state.db passed PRAGMA quick_check, but ${(freelistRatio * 100).toFixed(1)}% of its pages are free (reclaimable by VACUUM).`
932
+ : "state.db passed PRAGMA quick_check.",
933
+ evidence: {
934
+ path: ctx.stateDbPath,
935
+ freelistCount: ctx.stateDbFreelist.freelistCount,
936
+ pageCount: ctx.stateDbFreelist.pageCount,
937
+ freelistRatio,
938
+ },
939
+ };
940
+ },
941
+ },
871
942
  {
872
943
  name: "state-db-migrations",
873
944
  channel: "hard",
874
- run: (ctx) => runPendingStateMigrationsCheck(ctx.stateDbPath),
945
+ run: (ctx) => appliedStateMigrationsCheck(ctx.stateDbPath, ctx.stateDbMigrations),
875
946
  },
876
947
  {
877
948
  name: "task-history-read",
@@ -885,20 +956,6 @@ export const HEALTH_CHECKS = [
885
956
  evidence: { rows: ctx.taskRowCount, since: ctx.since },
886
957
  }),
887
958
  },
888
- {
889
- name: "task-log-backing",
890
- channel: "hard",
891
- run: (ctx) => ({
892
- name: "task-log-backing",
893
- kind: "deterministic",
894
- status: ctx.logBackingRate === 1 ? "pass" : "fail",
895
- confidence: "high",
896
- message: ctx.logBackingRate === 1
897
- ? "Every task_history log_path resolved on disk."
898
- : `${ctx.taskRowsWithLogsCount - ctx.existingLogRowsCount} task log(s) referenced in task_history are missing.`,
899
- evidence: { totalWithLogs: ctx.taskRowsWithLogsCount, existingLogs: ctx.existingLogRowsCount },
900
- }),
901
- },
902
959
  {
903
960
  name: "active-runs",
904
961
  channel: "hard",
@@ -1073,54 +1130,6 @@ export const HEALTH_CHECKS = [
1073
1130
  };
1074
1131
  },
1075
1132
  },
1076
- {
1077
- // #603: pool-saturation advisory. The raw `sessionsScanned` count fired on
1078
- // normal cadence changes (the Jun 12 false alarm). Instead track the ratio
1079
- // of NEW (unseen) sessions to the total session pool extract evaluated in
1080
- // the window: a low ratio is the *expected* steady state, only a near-zero
1081
- // ratio signals a possible discovery/dedup bug.
1082
- //
1083
- // unseen ≈ `sessionsScanned` (extract only processes new sessions; already-
1084
- // seen ones are deduped into `sessionsSkipped`). total = scanned + skipped.
1085
- // This is a heuristic approximation — `sessionsSkipped` also folds in
1086
- // too-short skips — so the check is informational and never gates status.
1087
- name: "pool-saturation",
1088
- channel: "advisory",
1089
- run: (ctx) => {
1090
- const sx = ctx.sessionExtraction;
1091
- const total = sx.sessionsScanned + sx.sessionsSkipped;
1092
- const unseen = sx.sessionsScanned;
1093
- const ratio = total > 0 ? unseen / total : null;
1094
- const pct = ratio === null ? null : Math.round(ratio * 1000) / 10;
1095
- let status = "pass";
1096
- let confidence = "low";
1097
- let message;
1098
- if (!sx.ran || ratio === null) {
1099
- message = "Pool saturation: no extract activity in the window — no signal.";
1100
- }
1101
- else if (ratio < 0.02) {
1102
- status = "warn";
1103
- confidence = "medium";
1104
- message = `Session pool near-exhausted: only ${pct}% of the ${total}-session pool was new (<2%). Possible discovery/dedup bug — verify extract is still finding new sessions.`;
1105
- }
1106
- else if (ratio < 0.1) {
1107
- confidence = "medium";
1108
- message = `Session pool saturation: ${pct}% of ${total} sessions were new (<10%, steady-state expected — informational).`;
1109
- }
1110
- else {
1111
- confidence = "medium";
1112
- message = `Session pool healthy: ${pct}% of ${total} sessions were new.`;
1113
- }
1114
- return {
1115
- name: "pool-saturation",
1116
- kind: "heuristic",
1117
- status,
1118
- confidence,
1119
- message,
1120
- evidence: { totalSessions: total, unseenSessions: unseen, saturationRatio: ratio },
1121
- };
1122
- },
1123
- },
1124
1133
  {
1125
1134
  name: "auto-accept-validation",
1126
1135
  channel: "advisory",
@@ -0,0 +1,38 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * `binary-config-skew` advisory for `akm health`: warn when config.json
6
+ * carries a `configVersion` NEWER than (or unorderable against) this binary's
7
+ * CURRENT_CONFIG_VERSION — a newer akm wrote the shared config, so this
8
+ * install is stale. That is the proven multi-install incident class. Silent
9
+ * for current or older versions and for unreadable configs (config loading
10
+ * reports its own errors).
11
+ */
12
+ import { readTextFile } from "../../core/common.js";
13
+ import { CURRENT_CONFIG_VERSION } from "../../core/config/config-schema.js";
14
+ import { compareConfigVersion } from "../../core/config/config-version.js";
15
+ export function collectConfigSkewAdvisory(configPath) {
16
+ let raw;
17
+ try {
18
+ raw = JSON.parse(readTextFile(configPath, "Config file"));
19
+ }
20
+ catch {
21
+ return undefined;
22
+ }
23
+ const onDisk = raw.configVersion;
24
+ const order = compareConfigVersion(onDisk, CURRENT_CONFIG_VERSION);
25
+ const skewed = order === 1 || (onDisk !== undefined && order === undefined);
26
+ if (!skewed)
27
+ return undefined;
28
+ return {
29
+ name: "binary-config-skew",
30
+ kind: "deterministic",
31
+ status: "warn",
32
+ confidence: "high",
33
+ message: `config.json has configVersion ${JSON.stringify(onDisk)} but this binary knows ${CURRENT_CONFIG_VERSION} — ` +
34
+ "a newer akm wrote the shared config, so this install is stale. Upgrade this install; do not keep a stale " +
35
+ "binary against the shared config/DBs.",
36
+ evidence: { onDiskConfigVersion: onDisk, binaryConfigVersion: CURRENT_CONFIG_VERSION },
37
+ };
38
+ }
@@ -41,7 +41,7 @@ const DOMINANT_SUBDIR_PERCENT_THRESHOLD = 50;
41
41
  * cap the walk stops descending further and the advisory says its size
42
42
  * figures are a lower bound.
43
43
  */
44
- const MAX_WALK_ENTRIES = 100_000;
44
+ export const MAX_WALK_ENTRIES = 100_000;
45
45
  /**
46
46
  * Below this the data dir is not worth an opinion. The advisory exists for
47
47
  * disk blowups (74 GB in the incident); on a small directory a ratio is
@@ -59,31 +59,42 @@ function liveDbBytesFor(name, sizes) {
59
59
  return ((sizes.get(name)?.bytes ?? 0) + (sizes.get(`${name}-wal`)?.bytes ?? 0) + (sizes.get(`${name}-shm`)?.bytes ?? 0));
60
60
  }
61
61
  /**
62
- * Recursively sum file sizes under `root` (stat-only, symlinks not
63
- * followed so a cyclic or huge-target symlink can't blow up the walk).
64
- * `budget` is a shared mutable counter across the whole tree so the
65
- * `MAX_WALK_ENTRIES` cap applies to the walk as a whole, not per-branch.
62
+ * Recursively sum file sizes (and count files) under `root` (stat-only,
63
+ * symlinks not followed so a cyclic or huge-target symlink can't blow up the
64
+ * walk). `budget` is a shared mutable counter across the whole tree so the
65
+ * entry cap applies to the walk as a whole, not per-branch — callers
66
+ * typically pass {@link MAX_WALK_ENTRIES}, sized for this module's own data
67
+ * dir walk, but a smaller/larger budget is fine for a different tree.
68
+ * Shared with the `archive-usage` advisory (N2) — the same "don't let a
69
+ * pathological tree hang a health check" concern applies to both.
70
+ *
71
+ * `onFile`, when given, is called once per leaf file (path, bytes) as the
72
+ * walk visits it — `archive-usage` uses this to classify each file's git
73
+ * state without a second, separate walk of the same tree.
66
74
  */
67
- function sizeOfPath(root, budget) {
75
+ export function sizeOfPath(root, budget, onFile) {
68
76
  let stat;
69
77
  try {
70
78
  stat = fs.lstatSync(root);
71
79
  }
72
80
  catch {
73
- return { bytes: 0, truncated: false };
81
+ return { bytes: 0, files: 0, truncated: false };
74
82
  }
75
83
  if (stat.isSymbolicLink())
76
- return { bytes: 0, truncated: false };
77
- if (!stat.isDirectory())
78
- return { bytes: stat.size, truncated: false };
84
+ return { bytes: 0, files: 0, truncated: false };
85
+ if (!stat.isDirectory()) {
86
+ onFile?.(root, stat.size);
87
+ return { bytes: stat.size, files: 1, truncated: false };
88
+ }
79
89
  let entries;
80
90
  try {
81
91
  entries = fs.readdirSync(root, { withFileTypes: true });
82
92
  }
83
93
  catch {
84
- return { bytes: 0, truncated: false };
94
+ return { bytes: 0, files: 0, truncated: false };
85
95
  }
86
96
  let bytes = 0;
97
+ let files = 0;
87
98
  let truncated = false;
88
99
  for (const entry of entries) {
89
100
  if (budget.remaining <= 0) {
@@ -91,12 +102,13 @@ function sizeOfPath(root, budget) {
91
102
  break;
92
103
  }
93
104
  budget.remaining--;
94
- const sub = sizeOfPath(path.join(root, entry.name), budget);
105
+ const sub = sizeOfPath(path.join(root, entry.name), budget, onFile);
95
106
  bytes += sub.bytes;
107
+ files += sub.files;
96
108
  if (sub.truncated)
97
109
  truncated = true;
98
110
  }
99
- return { bytes, truncated };
111
+ return { bytes, files, truncated };
100
112
  }
101
113
  /** `1610612736` -> `"1.5G"`. Values under 10 in a unit keep one decimal; 10+ round to an integer. */
102
114
  function formatBytes(bytes) {
@@ -0,0 +1,54 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * `egress-endpoints` advisory for `akm health` (meta-review 08, surfaces 3/9):
6
+ * the remote-destination list, for eyeball diff. A pure projection over the
7
+ * effective config (no process.env reads); silent when nothing remote is
8
+ * configured, matching the `stash-git-exposure` / `binary-config-skew`
9
+ * advisories' pattern.
10
+ */
11
+ import { formatRegistryUrl } from "../../core/registry-url.js";
12
+ /**
13
+ * `egress-endpoints` (08 surfaces 3/9): the full list of remote destinations
14
+ * akm can talk to under the effective config — registries, remote sources,
15
+ * LLM endpoints, embedding endpoint — as one pass-status informational entry
16
+ * for eyeball diff against expectations. Silent only when nothing remote is
17
+ * configured at all.
18
+ */
19
+ export function collectEgressAdvisory(config) {
20
+ if (!config)
21
+ return undefined;
22
+ const endpoints = [];
23
+ for (const reg of config.registries ?? []) {
24
+ if (reg.enabled === false || !reg.url)
25
+ continue;
26
+ endpoints.push(`registry ${reg.name ?? "(unnamed)"}: ${formatRegistryUrl(reg.url)}`);
27
+ }
28
+ for (const [key, bundle] of Object.entries(config.bundles ?? {})) {
29
+ if (!bundle)
30
+ continue;
31
+ const url = bundle.git ?? bundle.website?.url;
32
+ if (!url)
33
+ continue;
34
+ endpoints.push(`source ${key} (${bundle.git ? "git" : "website"}): ${url}`);
35
+ }
36
+ for (const [name, engine] of Object.entries(config.engines ?? {})) {
37
+ if (engine?.kind !== "llm" || !engine.endpoint)
38
+ continue;
39
+ endpoints.push(`llm ${name}: ${engine.endpoint}`);
40
+ }
41
+ if (config.embedding?.endpoint)
42
+ endpoints.push(`embedding: ${config.embedding.endpoint}`);
43
+ if (endpoints.length === 0)
44
+ return undefined;
45
+ return {
46
+ name: "egress-endpoints",
47
+ kind: "deterministic",
48
+ status: "pass",
49
+ confidence: "high",
50
+ message: `${endpoints.length} remote endpoint(s) in the effective config (registries/sources/LLM/embedding) — ` +
51
+ "review the evidence list for unexpected destinations.",
52
+ evidence: { endpoints },
53
+ };
54
+ }
@@ -131,7 +131,6 @@ function renderExecSummary(vm) {
131
131
  const trendRows = [
132
132
  trendLi("Decision quality", vm.trend.decisionQuality),
133
133
  trendLi("Output volume", vm.trend.outputVolume),
134
- trendLi("Failures", vm.trend.failures),
135
134
  trendLi("Latency", vm.trend.latency),
136
135
  ].join("");
137
136
  const deltaRows = [
@@ -151,7 +150,6 @@ function renderExecSummary(vm) {
151
150
  li("Promoted", String(vm.latest.promoted)),
152
151
  li("Judged: no action", `<abbr title="Candidates reviewed but intentionally left unchanged on this run.">${vm.latest.judgedNoAction}</abbr>`),
153
152
  li("MI written", String(vm.latest.miWritten)),
154
- li("Graph entities/relations", `${vm.latest.geEntities} / ${vm.latest.geRelations}`),
155
153
  ].join("")
156
154
  : '<li><span class="k">No runs in window</span><span class="v">—</span></li>';
157
155
  const windowRows = [
@@ -197,7 +195,7 @@ function renderExecSummary(vm) {
197
195
  </div>
198
196
  </div>
199
197
  <div class="overall">Overall trend: <b>${esc(vm.trend.overall)}</b> ${overallEmoji}
200
- &nbsp;·&nbsp; based on decision quality, output volume, failures, and latency ${vm.comparisonMode === "custom" ? "across the selected windows" : "vs the prior window"}.</div>`.trim();
198
+ &nbsp;·&nbsp; based on decision quality, output volume, and latency ${vm.comparisonMode === "custom" ? "across the selected windows" : "vs the prior window"}.</div>`.trim();
201
199
  }
202
200
  /**
203
201
  * Color is a health SIGNAL, not decoration: green/yellow/red where a card has
@@ -221,7 +219,6 @@ function renderKpiCards(vm) {
221
219
  kpiCard("neutral", "Median Duration", `${vm.medianDurMin}m`, `p95 = ${vm.p95DurMin}m`),
222
220
  kpiCard("blue", "Total Promoted", num(vm.consolidation.promoted), `avg ${vm.avgPromoted} / run`),
223
221
  kpiCard("blue", "MI Written", num(vm.miWritten), `${vm.miYieldRate} yield rate`),
224
- kpiCard("purple", "Graph Entities", num(vm.graphExtraction.entities), `+${num(vm.graphExtraction.relations)} relations`),
225
222
  kpiCard("neutral", "Stash Derived", num(vm.memorySummary.derived), `of ${num(vm.memorySummary.eligible)} eligible (whole-stash)`),
226
223
  // #576: real LLM work — duration leads, tokens compact, not a GPU proxy.
227
224
  kpiCard(vm.llm.calls > 0 ? "purple" : "neutral", "🧠 LLM Work", `${vm.llmTokensCompact} tok`, `${fmtMs(vm.llm.totalDurationMs)} · ${num(vm.llm.calls)} calls · ${compact(vm.llm.reasoningTokens)} reasoning`),
@@ -331,44 +328,6 @@ function renderActionItems(vm) {
331
328
  descHtml: `Newest run is ${esc(latestRunHuman)} — older than the 6h freshness threshold. Check the improve scheduler/cron.`,
332
329
  });
333
330
  }
334
- // WS-5: corpus entrenchment flag.
335
- if (vm.degradation?.entrenchmentFlagged) {
336
- pushItem({
337
- key: "corpus-entrenchment",
338
- prio: "P2",
339
- cls: "warn",
340
- title: "Corpus entrenchment risk: retrieval_salience Gini > 0.35",
341
- descHtml: "A small set of assets dominates retrieval — retrieval diversity is low. " +
342
- "Review top-ranked assets for stale or over-represented content. " +
343
- `Corpus diversity proxy: ${esc(String(vm.degradation.corpusCentroidDistance))}.`,
344
- remedy: "akm health --format json | jq '.improve.degradation'",
345
- });
346
- }
347
- // Low-tail companion: salience distribution collapsed toward uniform.
348
- if (vm.degradation?.salienceUniformityFlagged) {
349
- pushItem({
350
- key: "salience-uniformity-collapse",
351
- prio: "P2",
352
- cls: "warn",
353
- title: "Salience distribution collapsed: retrieval_salience Gini < 0.08",
354
- descHtml: `The ${vm.degradation.retrievalSalienceSampleSize} observed, resolvable salience scores are near-uniform — ` +
355
- "ranking carries little discrimination among assets with retrieval evidence. " +
356
- `Corpus diversity proxy: ${esc(String(vm.degradation.corpusCentroidDistance))}.`,
357
- remedy: "akm health --format json | jq '.improve.degradation'",
358
- });
359
- }
360
- // WS-5: over-budget consolidation advisory.
361
- if (vm.perf.overBudgetRuns > 0) {
362
- pushItem({
363
- key: "over-budget-consolidation",
364
- prio: "P2",
365
- cls: "warn",
366
- title: `${vm.perf.overBudgetRuns} consolidation run${vm.perf.overBudgetRuns === 1 ? "" : "s"} exceeded budget`,
367
- descHtml: "Consolidation phase wall time exceeded the total run budget on these runs. " +
368
- "Consider increasing the timeout or reducing the consolidation pool via strategy config.",
369
- remedy: "akm config list",
370
- });
371
- }
372
331
  items.sort((a, b) => PRIO_RANK[a.prio] - PRIO_RANK[b.prio]);
373
332
  return items.length > 0
374
333
  ? items.map(actionItemCard).join("\n")