audrey 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +39 -12
  3. package/dist/mcp-server/codex-hooks-probe.d.ts +22 -0
  4. package/dist/mcp-server/codex-hooks-probe.d.ts.map +1 -0
  5. package/dist/mcp-server/codex-hooks-probe.js +160 -0
  6. package/dist/mcp-server/codex-hooks-probe.js.map +1 -0
  7. package/dist/mcp-server/config.d.ts +26 -2
  8. package/dist/mcp-server/config.d.ts.map +1 -1
  9. package/dist/mcp-server/config.js +52 -20
  10. package/dist/mcp-server/config.js.map +1 -1
  11. package/dist/mcp-server/hooks.d.ts +28 -0
  12. package/dist/mcp-server/hooks.d.ts.map +1 -1
  13. package/dist/mcp-server/hooks.js +91 -2
  14. package/dist/mcp-server/hooks.js.map +1 -1
  15. package/dist/mcp-server/index.d.ts +242 -2
  16. package/dist/mcp-server/index.d.ts.map +1 -1
  17. package/dist/mcp-server/index.js +806 -240
  18. package/dist/mcp-server/index.js.map +1 -1
  19. package/dist/mcp-server/tool-schemas.d.ts +32 -2
  20. package/dist/mcp-server/tool-schemas.d.ts.map +1 -1
  21. package/dist/mcp-server/tool-schemas.js +55 -0
  22. package/dist/mcp-server/tool-schemas.js.map +1 -1
  23. package/dist/src/audrey.d.ts +14 -2
  24. package/dist/src/audrey.d.ts.map +1 -1
  25. package/dist/src/audrey.js +152 -28
  26. package/dist/src/audrey.js.map +1 -1
  27. package/dist/src/autopilot.d.ts +22 -0
  28. package/dist/src/autopilot.d.ts.map +1 -1
  29. package/dist/src/autopilot.js +271 -50
  30. package/dist/src/autopilot.js.map +1 -1
  31. package/dist/src/capsule.d.ts +23 -0
  32. package/dist/src/capsule.d.ts.map +1 -1
  33. package/dist/src/capsule.js +56 -11
  34. package/dist/src/capsule.js.map +1 -1
  35. package/dist/src/confidence.d.ts +9 -1
  36. package/dist/src/confidence.d.ts.map +1 -1
  37. package/dist/src/confidence.js +16 -2
  38. package/dist/src/confidence.js.map +1 -1
  39. package/dist/src/consolidate.d.ts +4 -0
  40. package/dist/src/consolidate.d.ts.map +1 -1
  41. package/dist/src/consolidate.js +206 -34
  42. package/dist/src/consolidate.js.map +1 -1
  43. package/dist/src/controller.d.ts +17 -1
  44. package/dist/src/controller.d.ts.map +1 -1
  45. package/dist/src/controller.js +244 -128
  46. package/dist/src/controller.js.map +1 -1
  47. package/dist/src/db.d.ts.map +1 -1
  48. package/dist/src/db.js +233 -56
  49. package/dist/src/db.js.map +1 -1
  50. package/dist/src/encode.d.ts +2 -1
  51. package/dist/src/encode.d.ts.map +1 -1
  52. package/dist/src/encode.js +41 -4
  53. package/dist/src/encode.js.map +1 -1
  54. package/dist/src/events.d.ts +48 -1
  55. package/dist/src/events.d.ts.map +1 -1
  56. package/dist/src/events.js +160 -62
  57. package/dist/src/events.js.map +1 -1
  58. package/dist/src/export.d.ts.map +1 -1
  59. package/dist/src/export.js +4 -4
  60. package/dist/src/export.js.map +1 -1
  61. package/dist/src/grounding.d.ts +111 -0
  62. package/dist/src/grounding.d.ts.map +1 -0
  63. package/dist/src/grounding.js +259 -0
  64. package/dist/src/grounding.js.map +1 -0
  65. package/dist/src/hybrid-recall.d.ts +16 -7
  66. package/dist/src/hybrid-recall.d.ts.map +1 -1
  67. package/dist/src/hybrid-recall.js +22 -11
  68. package/dist/src/hybrid-recall.js.map +1 -1
  69. package/dist/src/import.d.ts +10 -0
  70. package/dist/src/import.d.ts.map +1 -1
  71. package/dist/src/import.js +122 -22
  72. package/dist/src/import.js.map +1 -1
  73. package/dist/src/llm.d.ts.map +1 -1
  74. package/dist/src/llm.js +16 -0
  75. package/dist/src/llm.js.map +1 -1
  76. package/dist/src/preflight.d.ts.map +1 -1
  77. package/dist/src/preflight.js +89 -47
  78. package/dist/src/preflight.js.map +1 -1
  79. package/dist/src/project.d.ts +4 -1
  80. package/dist/src/project.d.ts.map +1 -1
  81. package/dist/src/project.js +65 -5
  82. package/dist/src/project.js.map +1 -1
  83. package/dist/src/recall.d.ts.map +1 -1
  84. package/dist/src/recall.js +138 -13
  85. package/dist/src/recall.js.map +1 -1
  86. package/dist/src/redact.d.ts +1 -1
  87. package/dist/src/redact.d.ts.map +1 -1
  88. package/dist/src/redact.js +185 -5
  89. package/dist/src/redact.js.map +1 -1
  90. package/dist/src/routes.d.ts.map +1 -1
  91. package/dist/src/routes.js +91 -18
  92. package/dist/src/routes.js.map +1 -1
  93. package/dist/src/trust.d.ts +35 -0
  94. package/dist/src/trust.d.ts.map +1 -0
  95. package/dist/src/trust.js +77 -0
  96. package/dist/src/trust.js.map +1 -0
  97. package/dist/src/types.d.ts +24 -0
  98. package/dist/src/types.d.ts.map +1 -1
  99. package/package.json +4 -38
  100. package/benchmarks/adapter-kit.mjs +0 -20
  101. package/benchmarks/adapter-self-test.mjs +0 -170
  102. package/benchmarks/adapters/example-allow.mjs +0 -31
  103. package/benchmarks/adapters/mem0-platform.mjs +0 -274
  104. package/benchmarks/adapters/registry.json +0 -51
  105. package/benchmarks/adapters/zep-cloud.mjs +0 -304
  106. package/benchmarks/baselines.js +0 -174
  107. package/benchmarks/build-leaderboard.mjs +0 -183
  108. package/benchmarks/cases.js +0 -549
  109. package/benchmarks/create-conformance-card.mjs +0 -148
  110. package/benchmarks/create-submission-bundle.mjs +0 -190
  111. package/benchmarks/dry-run-external-adapters.mjs +0 -177
  112. package/benchmarks/guardbench.js +0 -1265
  113. package/benchmarks/output/adapter-self-test/guardbench-adapter-self-test.json +0 -50
  114. package/benchmarks/output/external/guardbench-external-dry-run.json +0 -69
  115. package/benchmarks/output/external/guardbench-external-evidence.json +0 -56
  116. package/benchmarks/output/guardbench-conformance-card.json +0 -63
  117. package/benchmarks/output/guardbench-manifest.json +0 -414
  118. package/benchmarks/output/guardbench-raw.json +0 -1279
  119. package/benchmarks/output/guardbench-summary.json +0 -2123
  120. package/benchmarks/output/leaderboard/guardbench-leaderboard.json +0 -93
  121. package/benchmarks/output/leaderboard/guardbench-leaderboard.md +0 -7
  122. package/benchmarks/output/submission-bundle/guardbench-conformance-card.json +0 -63
  123. package/benchmarks/output/submission-bundle/guardbench-manifest.json +0 -414
  124. package/benchmarks/output/submission-bundle/guardbench-raw.json +0 -1279
  125. package/benchmarks/output/submission-bundle/guardbench-summary.json +0 -2123
  126. package/benchmarks/output/submission-bundle/schemas/guardbench-adapter-registry.schema.json +0 -69
  127. package/benchmarks/output/submission-bundle/schemas/guardbench-adapter-self-test.schema.json +0 -156
  128. package/benchmarks/output/submission-bundle/schemas/guardbench-conformance-card.schema.json +0 -184
  129. package/benchmarks/output/submission-bundle/schemas/guardbench-external-dry-run.schema.json +0 -74
  130. package/benchmarks/output/submission-bundle/schemas/guardbench-external-evidence.schema.json +0 -108
  131. package/benchmarks/output/submission-bundle/schemas/guardbench-external-run.schema.json +0 -160
  132. package/benchmarks/output/submission-bundle/schemas/guardbench-leaderboard.schema.json +0 -179
  133. package/benchmarks/output/submission-bundle/schemas/guardbench-manifest.schema.json +0 -213
  134. package/benchmarks/output/submission-bundle/schemas/guardbench-publication-verification.schema.json +0 -47
  135. package/benchmarks/output/submission-bundle/schemas/guardbench-raw.schema.json +0 -184
  136. package/benchmarks/output/submission-bundle/schemas/guardbench-submission-manifest.schema.json +0 -151
  137. package/benchmarks/output/submission-bundle/schemas/guardbench-summary.schema.json +0 -249
  138. package/benchmarks/output/submission-bundle/submission-manifest.json +0 -131
  139. package/benchmarks/output/submission-bundle/validation-report.json +0 -31
  140. package/benchmarks/output/summary.json +0 -2354
  141. package/benchmarks/perf-snapshot.js +0 -307
  142. package/benchmarks/perf.bench.js +0 -169
  143. package/benchmarks/public-paths.mjs +0 -97
  144. package/benchmarks/reference-results.js +0 -75
  145. package/benchmarks/report.js +0 -280
  146. package/benchmarks/run-external-guardbench.mjs +0 -303
  147. package/benchmarks/run.js +0 -735
  148. package/benchmarks/schemas/guardbench-adapter-registry.schema.json +0 -69
  149. package/benchmarks/schemas/guardbench-adapter-self-test.schema.json +0 -156
  150. package/benchmarks/schemas/guardbench-conformance-card.schema.json +0 -184
  151. package/benchmarks/schemas/guardbench-external-dry-run.schema.json +0 -74
  152. package/benchmarks/schemas/guardbench-external-evidence.schema.json +0 -108
  153. package/benchmarks/schemas/guardbench-external-run.schema.json +0 -160
  154. package/benchmarks/schemas/guardbench-leaderboard.schema.json +0 -179
  155. package/benchmarks/schemas/guardbench-manifest.schema.json +0 -213
  156. package/benchmarks/schemas/guardbench-publication-verification.schema.json +0 -47
  157. package/benchmarks/schemas/guardbench-raw.schema.json +0 -184
  158. package/benchmarks/schemas/guardbench-submission-manifest.schema.json +0 -151
  159. package/benchmarks/schemas/guardbench-summary.schema.json +0 -249
  160. package/benchmarks/snapshots/perf-0.22.2.json +0 -123
  161. package/benchmarks/snapshots/perf-0.23.0.json +0 -123
  162. package/benchmarks/validate-adapter-module.mjs +0 -107
  163. package/benchmarks/validate-adapter-registry.mjs +0 -145
  164. package/benchmarks/validate-adapter-self-test.mjs +0 -96
  165. package/benchmarks/validate-guardbench-artifacts.mjs +0 -400
  166. package/benchmarks/verify-external-evidence.mjs +0 -351
  167. package/benchmarks/verify-publication-artifacts.mjs +0 -309
  168. package/benchmarks/verify-submission-bundle.mjs +0 -172
  169. package/docs/AUDREY_PAPER_OUTLINE.md +0 -178
  170. package/docs/MEMORY_BENCHMARKING.md +0 -59
  171. package/docs/PRODUCTION_BACKLOG.md +0 -321
  172. package/docs/assets/audrey-feature-grid.jpg +0 -0
  173. package/docs/assets/audrey-logo.svg +0 -45
  174. package/docs/assets/audrey-wordmark.png +0 -0
  175. package/docs/paper/00-master.md +0 -48
  176. package/docs/paper/01-introduction.md +0 -27
  177. package/docs/paper/02-related-work.md +0 -47
  178. package/docs/paper/03-problem-definition.md +0 -108
  179. package/docs/paper/04-design.md +0 -164
  180. package/docs/paper/05-guardbench-spec.md +0 -412
  181. package/docs/paper/06-implementation.md +0 -115
  182. package/docs/paper/07-evaluation.md +0 -168
  183. package/docs/paper/08-discussion-limitations.md +0 -61
  184. package/docs/paper/09-conclusion.md +0 -11
  185. package/docs/paper/SUBMISSION_README.md +0 -162
  186. package/docs/paper/appendix-a-demo-transcript.md +0 -114
  187. package/docs/paper/arxiv-compile-report.schema.json +0 -116
  188. package/docs/paper/arxiv-source.schema.json +0 -61
  189. package/docs/paper/audrey-paper-v1.md +0 -1108
  190. package/docs/paper/browser-launch-plan.json +0 -209
  191. package/docs/paper/browser-launch-plan.schema.json +0 -100
  192. package/docs/paper/browser-launch-results.json +0 -86
  193. package/docs/paper/browser-launch-results.schema.json +0 -66
  194. package/docs/paper/claim-register.json +0 -138
  195. package/docs/paper/claim-register.schema.json +0 -81
  196. package/docs/paper/evidence-ledger.md +0 -103
  197. package/docs/paper/output/arxiv/README-arxiv.txt +0 -8
  198. package/docs/paper/output/arxiv/arxiv-manifest.json +0 -41
  199. package/docs/paper/output/arxiv/main.tex +0 -951
  200. package/docs/paper/output/arxiv/references.bib +0 -222
  201. package/docs/paper/output/arxiv-compile-report.json +0 -24
  202. package/docs/paper/output/submission-bundle/LICENSE +0 -21
  203. package/docs/paper/output/submission-bundle/README.md +0 -440
  204. package/docs/paper/output/submission-bundle/benchmarks/output/adapter-self-test/guardbench-adapter-self-test.json +0 -50
  205. package/docs/paper/output/submission-bundle/benchmarks/output/external/guardbench-external-dry-run.json +0 -69
  206. package/docs/paper/output/submission-bundle/benchmarks/output/external/guardbench-external-evidence.json +0 -56
  207. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-conformance-card.json +0 -63
  208. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-manifest.json +0 -414
  209. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-raw.json +0 -1279
  210. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-summary.json +0 -2123
  211. package/docs/paper/output/submission-bundle/benchmarks/output/leaderboard/guardbench-leaderboard.json +0 -93
  212. package/docs/paper/output/submission-bundle/benchmarks/output/leaderboard/guardbench-leaderboard.md +0 -7
  213. package/docs/paper/output/submission-bundle/benchmarks/output/submission-bundle/submission-manifest.json +0 -131
  214. package/docs/paper/output/submission-bundle/benchmarks/output/submission-bundle/validation-report.json +0 -31
  215. package/docs/paper/output/submission-bundle/benchmarks/output/summary.json +0 -2354
  216. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-adapter-registry.schema.json +0 -69
  217. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-adapter-self-test.schema.json +0 -156
  218. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-conformance-card.schema.json +0 -184
  219. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-external-dry-run.schema.json +0 -74
  220. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-external-evidence.schema.json +0 -108
  221. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-external-run.schema.json +0 -160
  222. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-leaderboard.schema.json +0 -179
  223. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-manifest.schema.json +0 -213
  224. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-publication-verification.schema.json +0 -47
  225. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-raw.schema.json +0 -184
  226. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-submission-manifest.schema.json +0 -151
  227. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-summary.schema.json +0 -249
  228. package/docs/paper/output/submission-bundle/docs/AUDREY_PAPER_OUTLINE.md +0 -178
  229. package/docs/paper/output/submission-bundle/docs/paper/00-master.md +0 -48
  230. package/docs/paper/output/submission-bundle/docs/paper/01-introduction.md +0 -27
  231. package/docs/paper/output/submission-bundle/docs/paper/02-related-work.md +0 -47
  232. package/docs/paper/output/submission-bundle/docs/paper/03-problem-definition.md +0 -108
  233. package/docs/paper/output/submission-bundle/docs/paper/04-design.md +0 -164
  234. package/docs/paper/output/submission-bundle/docs/paper/05-guardbench-spec.md +0 -412
  235. package/docs/paper/output/submission-bundle/docs/paper/06-implementation.md +0 -115
  236. package/docs/paper/output/submission-bundle/docs/paper/07-evaluation.md +0 -168
  237. package/docs/paper/output/submission-bundle/docs/paper/08-discussion-limitations.md +0 -61
  238. package/docs/paper/output/submission-bundle/docs/paper/09-conclusion.md +0 -11
  239. package/docs/paper/output/submission-bundle/docs/paper/SUBMISSION_README.md +0 -162
  240. package/docs/paper/output/submission-bundle/docs/paper/appendix-a-demo-transcript.md +0 -114
  241. package/docs/paper/output/submission-bundle/docs/paper/arxiv-compile-report.schema.json +0 -116
  242. package/docs/paper/output/submission-bundle/docs/paper/arxiv-source.schema.json +0 -61
  243. package/docs/paper/output/submission-bundle/docs/paper/audrey-paper-v1.md +0 -1108
  244. package/docs/paper/output/submission-bundle/docs/paper/browser-launch-plan.json +0 -209
  245. package/docs/paper/output/submission-bundle/docs/paper/browser-launch-plan.schema.json +0 -100
  246. package/docs/paper/output/submission-bundle/docs/paper/browser-launch-results.json +0 -86
  247. package/docs/paper/output/submission-bundle/docs/paper/browser-launch-results.schema.json +0 -66
  248. package/docs/paper/output/submission-bundle/docs/paper/claim-register.json +0 -138
  249. package/docs/paper/output/submission-bundle/docs/paper/claim-register.schema.json +0 -81
  250. package/docs/paper/output/submission-bundle/docs/paper/evidence-ledger.md +0 -103
  251. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/README-arxiv.txt +0 -8
  252. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/arxiv-manifest.json +0 -41
  253. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/main.tex +0 -951
  254. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/references.bib +0 -222
  255. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv-compile-report.json +0 -24
  256. package/docs/paper/output/submission-bundle/docs/paper/paper-submission-bundle.schema.json +0 -70
  257. package/docs/paper/output/submission-bundle/docs/paper/publication-pack.json +0 -81
  258. package/docs/paper/output/submission-bundle/docs/paper/publication-pack.schema.json +0 -60
  259. package/docs/paper/output/submission-bundle/docs/paper/references.bib +0 -222
  260. package/docs/paper/output/submission-bundle/package.json +0 -235
  261. package/docs/paper/output/submission-bundle/paper-submission-manifest.json +0 -379
  262. package/docs/paper/paper-submission-bundle.schema.json +0 -70
  263. package/docs/paper/publication-pack.json +0 -81
  264. package/docs/paper/publication-pack.schema.json +0 -60
  265. package/docs/paper/references.bib +0 -222
  266. package/scripts/audit-release-completion.mjs +0 -440
  267. package/scripts/create-arxiv-source.mjs +0 -368
  268. package/scripts/create-paper-submission-bundle.mjs +0 -214
  269. package/scripts/finalize-release.mjs +0 -601
  270. package/scripts/prepare-release-cut.mjs +0 -277
  271. package/scripts/publish-release-bundle.mjs +0 -252
  272. package/scripts/publish-release-github-api.mjs +0 -494
  273. package/scripts/run-vitest.mjs +0 -34
  274. package/scripts/smoke-cli.js +0 -92
  275. package/scripts/sync-paper-artifacts.mjs +0 -112
  276. package/scripts/verify-arxiv-compile.mjs +0 -476
  277. package/scripts/verify-arxiv-source.mjs +0 -224
  278. package/scripts/verify-browser-launch-plan.mjs +0 -254
  279. package/scripts/verify-browser-launch-results.mjs +0 -303
  280. package/scripts/verify-paper-artifacts.mjs +0 -798
  281. package/scripts/verify-paper-claims.mjs +0 -254
  282. package/scripts/verify-paper-submission-bundle.mjs +0 -218
  283. package/scripts/verify-publication-pack.mjs +0 -210
  284. package/scripts/verify-python-package.py +0 -201
  285. package/scripts/verify-release-readiness.mjs +0 -920
package/benchmarks/run.js DELETED
@@ -1,735 +0,0 @@
1
- import { mkdirSync, mkdtempSync, rmSync } from 'node:fs';
2
- import { join, resolve } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- import { Audrey } from '../dist/src/audrey.js';
5
- import { LOCAL_BENCHMARK_SUITES, FAMILY_ORDER } from './cases.js';
6
- import { runBaselineScenario } from './baselines.js';
7
- import { MEMORY_TRENDS, PUBLISHED_LEADERBOARD } from './reference-results.js';
8
- import { writeBenchmarkArtifacts } from './report.js';
9
-
10
- const SUITE_LABELS = new Map(LOCAL_BENCHMARK_SUITES.map(suite => [suite.id, suite.title]));
11
- const ALL_SUITE_IDS = LOCAL_BENCHMARK_SUITES.map(suite => suite.id);
12
-
13
- function parseArgs(argv = process.argv.slice(2)) {
14
- const args = {
15
- provider: 'mock',
16
- dimensions: 64,
17
- outDir: resolve('benchmarks/output'),
18
- jsonOnly: false,
19
- check: false,
20
- minAudreyScore: 80,
21
- minAudreyPassRate: 75,
22
- minMarginOverBaseline: 15,
23
- readmeAssetsDir: null,
24
- suite: 'all',
25
- };
26
-
27
- for (let i = 0; i < argv.length; i++) {
28
- const token = argv[i];
29
- if (token === '--provider' && argv[i + 1]) {
30
- args.provider = argv[++i];
31
- if (args.provider === 'local') args.dimensions = 384;
32
- if (args.provider === 'openai') args.dimensions = 1536;
33
- if (args.provider === 'gemini') args.dimensions = 3072;
34
- } else if (token === '--dimensions' && argv[i + 1]) {
35
- args.dimensions = Number.parseInt(argv[++i], 10);
36
- } else if (token === '--out-dir' && argv[i + 1]) {
37
- args.outDir = resolve(argv[++i]);
38
- } else if (token === '--json') {
39
- args.jsonOnly = true;
40
- } else if (token === '--check') {
41
- args.check = true;
42
- } else if (token === '--min-audrey-score' && argv[i + 1]) {
43
- args.minAudreyScore = Number.parseFloat(argv[++i]);
44
- } else if (token === '--min-audrey-pass-rate' && argv[i + 1]) {
45
- args.minAudreyPassRate = Number.parseFloat(argv[++i]);
46
- } else if (token === '--min-margin-over-baseline' && argv[i + 1]) {
47
- args.minMarginOverBaseline = Number.parseFloat(argv[++i]);
48
- } else if (token === '--readme-assets-dir' && argv[i + 1]) {
49
- args.readmeAssetsDir = resolve(argv[++i]);
50
- } else if (token === '--suite' && argv[i + 1]) {
51
- args.suite = argv[++i];
52
- }
53
- }
54
-
55
- return args;
56
- }
57
-
58
- function normalize(text) {
59
- return String(text || '').toLowerCase();
60
- }
61
-
62
- function normalizeSuiteSelection(value = 'all') {
63
- if (value === 'all') return [...ALL_SUITE_IDS];
64
- const selected = String(value)
65
- .split(',')
66
- .map(token => token.trim().toLowerCase())
67
- .filter(Boolean);
68
-
69
- const invalid = selected.filter(token => !ALL_SUITE_IDS.includes(token));
70
- if (invalid.length > 0) {
71
- throw new Error(
72
- `Unknown benchmark suite(s): ${invalid.join(', ')}. Valid: all, ${ALL_SUITE_IDS.join(', ')}`,
73
- );
74
- }
75
- return [...new Set(selected)];
76
- }
77
-
78
- function selectedSuitesOrThrow(suiteIds) {
79
- const suites = LOCAL_BENCHMARK_SUITES.filter(suite => suiteIds.includes(suite.id));
80
- if (suites.length === 0) {
81
- throw new Error('No benchmark suites selected.');
82
- }
83
- return suites;
84
- }
85
-
86
- function summarizeResults(results) {
87
- if (!results.length) return 'no retrieval';
88
- return results
89
- .slice(0, 2)
90
- .map(result => result.content.slice(0, 72))
91
- .join(' | ');
92
- }
93
-
94
- function evaluateCase(benchmarkCase, results) {
95
- const normalizedContents = results.map(result => normalize(result.content));
96
- const expected = (benchmarkCase.expectAny || []).map(normalize);
97
- const required = (benchmarkCase.expectAll || []).map(normalize);
98
- const forbidden = (benchmarkCase.forbid || []).map(normalize);
99
- const firstMatchIndex =
100
- expected.length === 0
101
- ? -1
102
- : normalizedContents.findIndex(content =>
103
- expected.some(expectation => content.includes(expectation)),
104
- );
105
- const firstForbiddenIndex = normalizedContents.findIndex(content =>
106
- forbidden.some(blocked => content.includes(blocked)),
107
- );
108
- const matched = firstMatchIndex !== -1;
109
- const requiredMatches = required.filter(expectation =>
110
- normalizedContents.some(content => content.includes(expectation)),
111
- );
112
- const matchedRequired = required.length > 0 && requiredMatches.length === required.length;
113
- const leakedForbidden = firstForbiddenIndex !== -1;
114
-
115
- if (benchmarkCase.expectNone) {
116
- const score = leakedForbidden ? 0 : results.length === 0 ? 1 : 0.5;
117
- return {
118
- passed: score === 1,
119
- score,
120
- summary: leakedForbidden
121
- ? 'leaked restricted content'
122
- : results.length === 0
123
- ? 'correct abstention'
124
- : 'no leak, but retrieved tangential context',
125
- };
126
- }
127
-
128
- if (required.length > 0) {
129
- const score =
130
- matchedRequired && !leakedForbidden
131
- ? 1
132
- : leakedForbidden
133
- ? 0
134
- : Math.min(0.5, requiredMatches.length / required.length);
135
- const missing = required.filter(expectation => !requiredMatches.includes(expectation));
136
- return {
137
- passed: score === 1,
138
- score,
139
- summary: matchedRequired
140
- ? 'matched all required signals'
141
- : missing.length > 0
142
- ? `missed required signal${missing.length === 1 ? '' : 's'}: ${missing.join(', ')}`
143
- : 'blocked content outranked the required signals',
144
- };
145
- }
146
-
147
- let score = 0;
148
- if (matched && !leakedForbidden) {
149
- score = 1;
150
- } else if (matched && leakedForbidden) {
151
- score = firstForbiddenIndex > firstMatchIndex ? 0.5 : 0;
152
- }
153
-
154
- return {
155
- passed: score === 1,
156
- score,
157
- summary: matched
158
- ? leakedForbidden
159
- ? firstForbiddenIndex > firstMatchIndex
160
- ? 'retrieved expected evidence, but conflicting evidence still appeared later'
161
- : 'blocked content outranked the correct answer'
162
- : 'retrieved expected evidence'
163
- : 'missed target evidence',
164
- };
165
- }
166
-
167
- async function seedRetrievalCase(brain, benchmarkCase) {
168
- const ids = [];
169
- for (let index = 0; index < benchmarkCase.memory.length; index++) {
170
- const memory = benchmarkCase.memory[index];
171
- const supersedes = Number.isInteger(memory.supersedesIndex)
172
- ? ids[memory.supersedesIndex]
173
- : undefined;
174
- const id = await brain.encode({
175
- content: memory.content,
176
- source: memory.source,
177
- tags: memory.tags,
178
- context: memory.context,
179
- affect: memory.affect,
180
- private: memory.private,
181
- salience: memory.salience,
182
- supersedes,
183
- });
184
-
185
- if (memory.createdAt) {
186
- brain.db.prepare('UPDATE episodes SET created_at = ? WHERE id = ?').run(memory.createdAt, id);
187
- }
188
-
189
- ids.push(id);
190
- }
191
-
192
- if (benchmarkCase.consolidate) {
193
- await brain.waitForIdle();
194
- await brain.consolidate({
195
- minClusterSize: benchmarkCase.consolidate.minClusterSize,
196
- similarityThreshold: benchmarkCase.consolidate.similarityThreshold,
197
- extractPrinciple: () => benchmarkCase.consolidate.principle,
198
- });
199
- }
200
- }
201
-
202
- async function executeAudreyStep(brain, step, refs) {
203
- if (step.type === 'encode') {
204
- const supersedes = step.supersedesRef ? refs.get(step.supersedesRef) : undefined;
205
- const id = await brain.encode({
206
- ...step.memory,
207
- supersedes,
208
- });
209
- if (step.saveAs) {
210
- refs.set(step.saveAs, id);
211
- }
212
- return;
213
- }
214
-
215
- if (step.type === 'forgetByQuery') {
216
- await brain.waitForIdle();
217
- await brain.forgetByQuery(step.query, step.options || {});
218
- return;
219
- }
220
-
221
- if (step.type === 'consolidate') {
222
- await brain.waitForIdle();
223
- await brain.consolidate({
224
- minClusterSize: step.minClusterSize,
225
- similarityThreshold: step.similarityThreshold,
226
- extractPrinciple: () => step.principle,
227
- });
228
- return;
229
- }
230
-
231
- throw new Error(`Unsupported Audrey benchmark step: ${step.type}`);
232
- }
233
-
234
- async function seedOperationsCase(brain, benchmarkCase) {
235
- const refs = new Map();
236
- for (const step of benchmarkCase.steps || []) {
237
- await executeAudreyStep(brain, step, refs);
238
- }
239
- }
240
-
241
- async function executeGuardStep(brain, step, refs) {
242
- if (step.type === 'encode' || step.type === 'forgetByQuery' || step.type === 'consolidate') {
243
- await executeAudreyStep(brain, step, refs);
244
- return [];
245
- }
246
-
247
- if (step.type === 'guardCycle') {
248
- const before = await brain.beforeAction(step.action, {
249
- tool: step.tool,
250
- strict: Boolean(step.strict),
251
- includeCapsule: step.includeCapsule ?? false,
252
- });
253
- if (step.saveReceiptAs) {
254
- refs.set(step.saveReceiptAs, before.receipt_id);
255
- }
256
- brain.afterAction({
257
- receiptId: before.receipt_id,
258
- tool: step.tool,
259
- outcome: step.outcome ?? 'unknown',
260
- errorSummary: step.errorSummary,
261
- });
262
- return [];
263
- }
264
-
265
- if (step.type === 'observeTool') {
266
- const result = brain.observeTool({
267
- event: step.event ?? 'PreToolUse',
268
- tool: step.tool ?? 'guard-benchmark',
269
- source: 'benchmark',
270
- outcome: step.outcome,
271
- errorSummary: step.errorSummary,
272
- metadata: step.metadata,
273
- });
274
- if (step.saveAs) {
275
- refs.set(step.saveAs, result.event.id);
276
- }
277
- return [];
278
- }
279
-
280
- if (step.type === 'expectGuardAfterError') {
281
- const receiptId = step.receiptRef ? refs.get(step.receiptRef) : step.receiptId;
282
- if (!receiptId) {
283
- throw new Error(
284
- `Missing guard benchmark receipt reference: ${step.receiptRef || step.receiptId}`,
285
- );
286
- }
287
-
288
- try {
289
- brain.afterAction({
290
- receiptId,
291
- tool: step.tool ?? 'guard-benchmark',
292
- outcome: step.outcome ?? 'unknown',
293
- errorSummary: step.errorSummary,
294
- evidenceFeedback: step.evidenceFeedback,
295
- });
296
- } catch (err) {
297
- const message = err instanceof Error ? err.message : String(err);
298
- if (step.errorIncludes && !message.includes(step.errorIncludes)) {
299
- throw new Error(`Guard hardening expected "${step.errorIncludes}" but got "${message}"`, {
300
- cause: err,
301
- });
302
- }
303
- const label = step.label ?? 'after_error_rejected';
304
- return [
305
- {
306
- id: `${receiptId}:${label}`,
307
- content: `guard_hardened:${label} error:${message}`,
308
- type: 'guard_hardening',
309
- score: 1,
310
- },
311
- ];
312
- }
313
-
314
- throw new Error(`Guard hardening expected an error for receipt ${receiptId}`);
315
- }
316
-
317
- throw new Error(`Unsupported guard benchmark step: ${step.type}`);
318
- }
319
-
320
- async function seedGuardCase(brain, benchmarkCase) {
321
- const refs = new Map();
322
- const diagnostics = [];
323
- for (const step of benchmarkCase.steps || []) {
324
- diagnostics.push(...(await executeGuardStep(brain, step, refs)));
325
- }
326
- return diagnostics;
327
- }
328
-
329
- function guardDecisionRows(decision) {
330
- const rows = [
331
- {
332
- id: decision.receipt_id,
333
- content: `decision:${decision.decision} verdict:${decision.verdict} risk:${decision.risk_score} ${decision.summary}`,
334
- type: 'guard_decision',
335
- score: 1,
336
- },
337
- ];
338
-
339
- for (const [index, warning] of decision.warnings.entries()) {
340
- rows.push({
341
- id: warning.evidence_id || `${decision.receipt_id}:warning:${index}`,
342
- content: `warning:${warning.type} severity:${warning.severity} ${warning.message} ${warning.recommended_action || ''}`,
343
- type: 'guard_warning',
344
- score: 0.95 - index * 0.01,
345
- });
346
- }
347
-
348
- for (const [index, reflex] of decision.reflexes.entries()) {
349
- rows.push({
350
- id: reflex.id || `${decision.receipt_id}:reflex:${index}`,
351
- content: `reflex:${reflex.response_type} source:${reflex.source} severity:${reflex.severity} ${reflex.response}`,
352
- type: 'guard_reflex',
353
- score: 0.85 - index * 0.01,
354
- });
355
- }
356
-
357
- return rows;
358
- }
359
-
360
- async function runAudreyCase(benchmarkCase, providerConfig) {
361
- const tempRoot = resolve('benchmarks/.tmp');
362
- mkdirSync(tempRoot, { recursive: true });
363
- const tempDir = mkdtempSync(join(tempRoot, 'audrey-bench-'));
364
- const brain = new Audrey({
365
- dataDir: tempDir,
366
- agent: `benchmark-${benchmarkCase.id}`,
367
- embedding: providerConfig,
368
- });
369
-
370
- try {
371
- if (typeof brain.embeddingProvider.ready === 'function') {
372
- await brain.embeddingProvider.ready();
373
- }
374
-
375
- let guardDiagnostics = [];
376
- if (benchmarkCase.kind === 'operations') {
377
- await seedOperationsCase(brain, benchmarkCase);
378
- } else if (benchmarkCase.kind === 'guard') {
379
- guardDiagnostics = await seedGuardCase(brain, benchmarkCase);
380
- } else {
381
- await seedRetrievalCase(brain, benchmarkCase);
382
- }
383
-
384
- await brain.waitForIdle();
385
- if (benchmarkCase.kind === 'guard') {
386
- const decision = await brain.beforeAction(benchmarkCase.action, {
387
- tool: benchmarkCase.tool,
388
- strict: Boolean(benchmarkCase.strict),
389
- includeCapsule: benchmarkCase.includeCapsule ?? false,
390
- });
391
- return [...guardDiagnostics, ...guardDecisionRows(decision)];
392
- }
393
-
394
- return await brain.recall(benchmarkCase.query, {
395
- limit: 5,
396
- minConfidence: 0.05,
397
- ...benchmarkCase.options,
398
- });
399
- } finally {
400
- brain.close();
401
- rmSync(tempDir, { recursive: true, force: true });
402
- }
403
- }
404
-
405
- async function runBaselineCase(system, benchmarkCase, providerConfig) {
406
- if (benchmarkCase.kind === 'guard') {
407
- return [
408
- {
409
- id: `${system.toLowerCase().replace(/[^a-z0-9]+/g, '-')}-guard-baseline`,
410
- content:
411
- 'decision:go verdict:clear summary:retrieval-only baseline has no before-action guard controller',
412
- type: 'guard_decision',
413
- score: 0,
414
- },
415
- ];
416
- }
417
-
418
- return runBaselineScenario(system, benchmarkCase, providerConfig, 5);
419
- }
420
-
421
- async function runSystemsForCase(benchmarkCase, providerConfig) {
422
- const systems = [
423
- { system: 'Audrey', run: () => runAudreyCase(benchmarkCase, providerConfig) },
424
- {
425
- system: 'Vector Only',
426
- run: () => runBaselineCase('Vector Only', benchmarkCase, providerConfig),
427
- },
428
- {
429
- system: 'Keyword + Recency',
430
- run: () => runBaselineCase('Keyword + Recency', benchmarkCase, providerConfig),
431
- },
432
- {
433
- system: 'Recent Window',
434
- run: () => runBaselineCase('Recent Window', benchmarkCase, providerConfig),
435
- },
436
- ];
437
-
438
- const results = [];
439
- for (const system of systems) {
440
- const started = Date.now();
441
- const items = await system.run();
442
- const evaluation = evaluateCase(benchmarkCase, items);
443
- results.push({
444
- system: system.system,
445
- durationMs: Date.now() - started,
446
- passed: evaluation.passed,
447
- score: evaluation.score,
448
- summary: evaluation.summary,
449
- topResults: items.slice(0, 3).map(item => item.content),
450
- retrievalSummary: summarizeResults(items),
451
- });
452
- }
453
-
454
- return results;
455
- }
456
-
457
- function summarizeLocalResults(caseResults) {
458
- const systems = new Map();
459
- for (const caseResult of caseResults) {
460
- for (const result of caseResult.results) {
461
- if (!systems.has(result.system)) {
462
- systems.set(result.system, {
463
- system: result.system,
464
- totalScore: 0,
465
- passCount: 0,
466
- totalCases: 0,
467
- durationMs: 0,
468
- });
469
- }
470
- const summary = systems.get(result.system);
471
- summary.totalScore += result.score;
472
- summary.passCount += result.passed ? 1 : 0;
473
- summary.totalCases += 1;
474
- summary.durationMs += result.durationMs;
475
- }
476
- }
477
-
478
- return [...systems.values()]
479
- .map(system => ({
480
- system: system.system,
481
- scorePercent: system.totalCases === 0 ? 0 : (system.totalScore / system.totalCases) * 100,
482
- passRate: system.totalCases === 0 ? 0 : (system.passCount / system.totalCases) * 100,
483
- avgDurationMs: system.totalCases === 0 ? 0 : system.durationMs / system.totalCases,
484
- }))
485
- .sort((a, b) => b.scorePercent - a.scorePercent);
486
- }
487
-
488
- function summarizeByFamily(caseResults) {
489
- const families = new Map();
490
- for (const family of FAMILY_ORDER) {
491
- families.set(family, { family, systems: {} });
492
- }
493
-
494
- for (const caseResult of caseResults) {
495
- const entry = families.get(caseResult.family) || { family: caseResult.family, systems: {} };
496
- for (const result of caseResult.results) {
497
- entry.systems[result.system] = result.score;
498
- }
499
- families.set(caseResult.family, entry);
500
- }
501
-
502
- return [...families.values()].filter(entry => Object.keys(entry.systems).length > 0);
503
- }
504
-
505
- function summarizeSuites(caseResults, suites) {
506
- return suites.map(suite => {
507
- const suiteCases = caseResults.filter(caseResult => caseResult.suite === suite.id);
508
- return {
509
- id: suite.id,
510
- title: suite.title,
511
- description: suite.description,
512
- comparableToBaselines: suite.comparableToBaselines !== false,
513
- overall: summarizeLocalResults(suiteCases),
514
- byFamily: summarizeByFamily(suiteCases),
515
- cases: suiteCases,
516
- };
517
- });
518
- }
519
-
520
- function commandForSummary(providerConfig, suiteIds) {
521
- const suiteArg = suiteIds.length === ALL_SUITE_IDS.length ? '' : ` --suite ${suiteIds.join(',')}`;
522
- return `node benchmarks/run.js --provider ${providerConfig.provider} --dimensions ${providerConfig.dimensions}${suiteArg}`;
523
- }
524
-
525
- export function assertBenchmarkGuardrails(summary, options = {}) {
526
- const settings = {
527
- minAudreyScore: options.minAudreyScore ?? 80,
528
- minAudreyPassRate: options.minAudreyPassRate ?? 75,
529
- minMarginOverBaseline: options.minMarginOverBaseline ?? 15,
530
- };
531
- const audrey = summary.local.overall.find(row => row.system === 'Audrey');
532
- if (!audrey) {
533
- throw new Error('Audrey results were missing from the local benchmark summary.');
534
- }
535
-
536
- const strongestBaseline = summary.local.overall
537
- .filter(row => row.system !== 'Audrey')
538
- .sort((a, b) => b.scorePercent - a.scorePercent)[0];
539
- const failures = [];
540
-
541
- if (audrey.scorePercent < settings.minAudreyScore) {
542
- failures.push(
543
- `Audrey score ${audrey.scorePercent.toFixed(1)}% fell below ${settings.minAudreyScore.toFixed(1)}%.`,
544
- );
545
- }
546
-
547
- if (audrey.passRate < settings.minAudreyPassRate) {
548
- failures.push(
549
- `Audrey pass rate ${audrey.passRate.toFixed(1)}% fell below ${settings.minAudreyPassRate.toFixed(1)}%.`,
550
- );
551
- }
552
-
553
- if (strongestBaseline) {
554
- const margin = audrey.scorePercent - strongestBaseline.scorePercent;
555
- if (margin < settings.minMarginOverBaseline) {
556
- failures.push(
557
- `Audrey beat ${strongestBaseline.system} by ${margin.toFixed(1)} points, below the required ` +
558
- `${settings.minMarginOverBaseline.toFixed(1)}-point margin.`,
559
- );
560
- }
561
- }
562
-
563
- if (failures.length) {
564
- throw new Error(`Benchmark regression gate failed:\n- ${failures.join('\n- ')}`);
565
- }
566
-
567
- return {
568
- audrey,
569
- strongestBaseline,
570
- marginOverBaseline: strongestBaseline
571
- ? audrey.scorePercent - strongestBaseline.scorePercent
572
- : null,
573
- thresholds: settings,
574
- };
575
- }
576
-
577
- export async function runBenchmarkSuite(options = {}) {
578
- const providerConfig = {
579
- provider: options.provider || 'mock',
580
- dimensions: options.dimensions || 64,
581
- };
582
- const suiteIds = normalizeSuiteSelection(options.suite || 'all');
583
- const selectedSuites = selectedSuitesOrThrow(suiteIds);
584
-
585
- const caseResults = [];
586
- for (const suite of selectedSuites) {
587
- for (const benchmarkCase of suite.cases) {
588
- const results = await runSystemsForCase(benchmarkCase, providerConfig);
589
- caseResults.push({
590
- id: benchmarkCase.id,
591
- suite: benchmarkCase.suite,
592
- title: benchmarkCase.title,
593
- family: benchmarkCase.family,
594
- description: benchmarkCase.description,
595
- query: benchmarkCase.query,
596
- action: benchmarkCase.action,
597
- tool: benchmarkCase.tool,
598
- comparable_to_baselines: suite.comparableToBaselines !== false,
599
- results,
600
- });
601
- }
602
- }
603
-
604
- const comparableCaseResults = caseResults.filter(
605
- caseResult => caseResult.comparable_to_baselines,
606
- );
607
- const overallCaseResults = comparableCaseResults.length > 0 ? comparableCaseResults : caseResults;
608
- const overallScope = comparableCaseResults.length > 0 ? 'comparable_suites' : 'selected_suites';
609
- const overallSuiteIds = [...new Set(overallCaseResults.map(caseResult => caseResult.suite))];
610
- const localOverall = summarizeLocalResults(overallCaseResults);
611
- const localByFamily = summarizeByFamily(overallCaseResults);
612
- const localSuites = summarizeSuites(caseResults, selectedSuites);
613
-
614
- return {
615
- generatedAt: new Date().toISOString(),
616
- command: commandForSummary(providerConfig, suiteIds),
617
- config: {
618
- ...providerConfig,
619
- suites: suiteIds,
620
- },
621
- methodology: {
622
- localBenchmark:
623
- 'Local regression suite inspired by LongMemEval-style retrieval, operation-level lifecycle, and agent guard-loop benchmarks',
624
- retrievalBenchmark:
625
- 'Information extraction, updates, reasoning, procedural learning, privacy, abstention, and conflict handling',
626
- operationsBenchmark:
627
- 'Update, overwrite, delete, merge, and abstention behavior after lifecycle operations',
628
- guardBenchmark:
629
- 'Memory-before-action controller behavior: receipts, learned tool-failure cautions, strict blocking reflexes, and guard-after hardening',
630
- externalLeaderboard: 'Published LoCoMo scores from official papers and project blogs',
631
- },
632
- local: {
633
- overall: localOverall,
634
- overall_scope: overallScope,
635
- overall_suite_ids: overallSuiteIds,
636
- byFamily: localByFamily,
637
- suites: localSuites,
638
- cases: caseResults,
639
- },
640
- external: {
641
- benchmark: 'LoCoMo',
642
- leaderboard: [...PUBLISHED_LEADERBOARD].sort((a, b) => b.score - a.score),
643
- },
644
- trends: MEMORY_TRENDS,
645
- };
646
- }
647
-
648
- export async function runBenchmarkCli({ argv = process.argv.slice(2), out = console.log } = {}) {
649
- const args = parseArgs(argv);
650
- const summary = await runBenchmarkSuite(args);
651
- const artifacts = writeBenchmarkArtifacts({
652
- outputDir: args.outDir,
653
- summary,
654
- localOverall: summary.local.overall,
655
- localSuites: summary.local.suites,
656
- externalOverall: summary.external.leaderboard,
657
- trends: summary.trends,
658
- readmeAssetsDir: args.readmeAssetsDir,
659
- });
660
- const gate = args.check
661
- ? assertBenchmarkGuardrails(summary, {
662
- minAudreyScore: args.minAudreyScore,
663
- minAudreyPassRate: args.minAudreyPassRate,
664
- minMarginOverBaseline: args.minMarginOverBaseline,
665
- })
666
- : null;
667
-
668
- if (args.jsonOnly) {
669
- out(JSON.stringify({ summary, artifacts, gate }, null, 2));
670
- return { summary, artifacts, gate };
671
- }
672
-
673
- const lines = [];
674
- lines.push('Audrey benchmark complete.');
675
- lines.push('');
676
- lines.push(
677
- `Suites: ${summary.config.suites.map(suiteId => SUITE_LABELS.get(suiteId) || suiteId).join(', ')}`,
678
- );
679
- lines.push(
680
- `Scope: ${summary.local.overall_scope} (${summary.local.overall_suite_ids.join(', ')})`,
681
- );
682
- const comparableCaseCount = summary.local.cases.filter(testCase =>
683
- summary.local.overall_suite_ids.includes(testCase.suite),
684
- ).length;
685
- lines.push(
686
- `Cases: ${summary.local.cases.length} total; ${comparableCaseCount} in combined local chart`,
687
- );
688
- for (const row of summary.local.overall) {
689
- lines.push(
690
- `${row.system}: ${row.scorePercent.toFixed(1)}% score, ${row.passRate.toFixed(1)}% pass rate, ` +
691
- `${row.avgDurationMs.toFixed(1)} ms avg/case`,
692
- );
693
- }
694
- lines.push('');
695
- for (const suite of summary.local.suites) {
696
- const audrey = suite.overall.find(row => row.system === 'Audrey');
697
- lines.push(`${suite.title}: Audrey ${audrey?.scorePercent.toFixed(1) ?? '0.0'}%`);
698
- }
699
- lines.push('');
700
- lines.push(`JSON report: ${artifacts.json}`);
701
- lines.push(`HTML report: ${artifacts.html}`);
702
- lines.push(`Local chart: ${artifacts.localChart}`);
703
- if (artifacts.suiteCharts.length > 0) {
704
- for (const suiteChart of artifacts.suiteCharts) {
705
- lines.push(`${suiteChart.title}: ${suiteChart.path}`);
706
- }
707
- }
708
- lines.push(`Published chart: ${artifacts.externalChart}`);
709
- if (artifacts.readmeAssets) {
710
- lines.push(`README local chart: ${artifacts.readmeAssets.localChart}`);
711
- if (artifacts.readmeAssets.operationsChart) {
712
- lines.push(`README operations chart: ${artifacts.readmeAssets.operationsChart}`);
713
- }
714
- lines.push(`README published chart: ${artifacts.readmeAssets.externalChart}`);
715
- }
716
- if (gate) {
717
- const baselineLabel = gate.strongestBaseline
718
- ? `${gate.strongestBaseline.system} by ${gate.marginOverBaseline.toFixed(1)} points`
719
- : 'all local baselines';
720
- lines.push('');
721
- lines.push(
722
- `Regression gate passed: Audrey stayed above ${gate.thresholds.minAudreyScore.toFixed(1)}% and ahead of ${baselineLabel}.`,
723
- );
724
- }
725
-
726
- out(lines.join('\n'));
727
- return { summary, artifacts, gate };
728
- }
729
-
730
- if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
731
- runBenchmarkCli().catch(err => {
732
- console.error('[audrey] benchmark failed:', err);
733
- process.exitCode = 1;
734
- });
735
- }