mneme-ai 1.5.0 → 1.7.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.
- package/dist/commands/benchmark.d.ts +83 -0
- package/dist/commands/benchmark.d.ts.map +1 -0
- package/dist/commands/benchmark.js +560 -0
- package/dist/commands/benchmark.js.map +1 -0
- package/dist/commands/benchmark.test.d.ts +10 -0
- package/dist/commands/benchmark.test.d.ts.map +1 -0
- package/dist/commands/benchmark.test.js +122 -0
- package/dist/commands/benchmark.test.js.map +1 -0
- package/dist/commands/court.d.ts +63 -0
- package/dist/commands/court.d.ts.map +1 -0
- package/dist/commands/court.js +473 -0
- package/dist/commands/court.js.map +1 -0
- package/dist/commands/court.test.d.ts +9 -0
- package/dist/commands/court.test.d.ts.map +1 -0
- package/dist/commands/court.test.js +131 -0
- package/dist/commands/court.test.js.map +1 -0
- package/dist/commands/daemon.d.ts +28 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +340 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/daemon.test.d.ts +13 -0
- package/dist/commands/daemon.test.d.ts.map +1 -0
- package/dist/commands/daemon.test.js +142 -0
- package/dist/commands/daemon.test.js.map +1 -0
- package/dist/commands/federation.d.ts +37 -0
- package/dist/commands/federation.d.ts.map +1 -0
- package/dist/commands/federation.js +281 -0
- package/dist/commands/federation.js.map +1 -0
- package/dist/commands/federation.test.d.ts +12 -0
- package/dist/commands/federation.test.d.ts.map +1 -0
- package/dist/commands/federation.test.js +175 -0
- package/dist/commands/federation.test.js.map +1 -0
- package/dist/commands/index-cmd.d.ts.map +1 -1
- package/dist/commands/index-cmd.js +8 -0
- package/dist/commands/index-cmd.js.map +1 -1
- package/dist/commands/time-capsule.d.ts +33 -0
- package/dist/commands/time-capsule.d.ts.map +1 -0
- package/dist/commands/time-capsule.js +231 -0
- package/dist/commands/time-capsule.js.map +1 -0
- package/dist/commands/time-capsule.test.d.ts +9 -0
- package/dist/commands/time-capsule.test.d.ts.map +1 -0
- package/dist/commands/time-capsule.test.js +94 -0
- package/dist/commands/time-capsule.test.js.map +1 -0
- package/dist/commands/wisdom-theater.d.ts +41 -0
- package/dist/commands/wisdom-theater.d.ts.map +1 -0
- package/dist/commands/wisdom-theater.js +106 -0
- package/dist/commands/wisdom-theater.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mneme benchmark` — the AI Memory Benchmark.
|
|
3
|
+
*
|
|
4
|
+
* Strategic positioning: the Lighthouse-of-AI-memory. Mneme grades AI
|
|
5
|
+
* memory implementations (Mneme itself, Claude's native context, GPT's,
|
|
6
|
+
* Cursor's bundled, etc.) using a standardized probe set + the same
|
|
7
|
+
* Super Sonic Engine grader that already ships in Mneme.
|
|
8
|
+
*
|
|
9
|
+
* Why this is uniquely Mneme's seat: when every AI vendor ships native
|
|
10
|
+
* "repo memory", who grades them? Anthropic can't grade Anthropic;
|
|
11
|
+
* OpenAI can't grade OpenAI. Mneme is the only vendor-neutral auditor
|
|
12
|
+
* — and the only one that can publish a fair public leaderboard.
|
|
13
|
+
*
|
|
14
|
+
* v0.1 ships:
|
|
15
|
+
* • Probe set (24 memory questions across 6 categories)
|
|
16
|
+
* • Local-mode benchmarking (grades Mneme itself end-to-end)
|
|
17
|
+
* • Markdown leaderboard generation
|
|
18
|
+
* • Stub for future "external mode" that grades third-party memory
|
|
19
|
+
* implementations via their public APIs
|
|
20
|
+
*/
|
|
21
|
+
export interface BenchmarkOptions {
|
|
22
|
+
cwd: string;
|
|
23
|
+
/** Compare against named external implementations.
|
|
24
|
+
* v0.1 supports only "mneme-self". v1.0 will add claude / gpt / cursor. */
|
|
25
|
+
targets?: string[];
|
|
26
|
+
/** Output markdown leaderboard to this path */
|
|
27
|
+
out?: string;
|
|
28
|
+
/** Machine-readable JSON */
|
|
29
|
+
json?: boolean;
|
|
30
|
+
/** Number of probes to run (default: all 24) */
|
|
31
|
+
probes?: number;
|
|
32
|
+
}
|
|
33
|
+
interface Probe {
|
|
34
|
+
id: string;
|
|
35
|
+
category: "factual-recall" | "causal-explanation" | "lineage-trace" | "regression-prediction" | "cited-rationale" | "uncertainty-honesty";
|
|
36
|
+
question: string;
|
|
37
|
+
/** Expected qualities the answer must satisfy. Each is a binary check. */
|
|
38
|
+
rubric: ProbeRubric[];
|
|
39
|
+
}
|
|
40
|
+
interface ProbeRubric {
|
|
41
|
+
id: string;
|
|
42
|
+
/** Pass = answer contains AT LEAST ONE of these regex patterns */
|
|
43
|
+
must_match?: RegExp[];
|
|
44
|
+
/** Pass = answer contains NONE of these regex patterns */
|
|
45
|
+
must_not_match?: RegExp[];
|
|
46
|
+
/** Description shown in the report */
|
|
47
|
+
description: string;
|
|
48
|
+
}
|
|
49
|
+
interface ProbeResult {
|
|
50
|
+
probeId: string;
|
|
51
|
+
category: Probe["category"];
|
|
52
|
+
question: string;
|
|
53
|
+
answer: string;
|
|
54
|
+
passed: number;
|
|
55
|
+
total: number;
|
|
56
|
+
failedRubrics: Array<{
|
|
57
|
+
id: string;
|
|
58
|
+
description: string;
|
|
59
|
+
}>;
|
|
60
|
+
durationMs: number;
|
|
61
|
+
}
|
|
62
|
+
interface BenchmarkResult {
|
|
63
|
+
target: string;
|
|
64
|
+
ranAt: string;
|
|
65
|
+
totalProbes: number;
|
|
66
|
+
totalRubricChecks: number;
|
|
67
|
+
passedRubricChecks: number;
|
|
68
|
+
scoreByCategory: Record<string, {
|
|
69
|
+
passed: number;
|
|
70
|
+
total: number;
|
|
71
|
+
pct: number;
|
|
72
|
+
}>;
|
|
73
|
+
overallScore: number;
|
|
74
|
+
probeResults: ProbeResult[];
|
|
75
|
+
}
|
|
76
|
+
declare function checkRubric(rubric: ProbeRubric, answer: string): boolean;
|
|
77
|
+
declare function renderMarkdownLeaderboard(results: BenchmarkResult[]): string;
|
|
78
|
+
export declare function benchmarkCommand(opts: BenchmarkOptions): Promise<number>;
|
|
79
|
+
export declare const _PROBES_FOR_TESTS: Probe[];
|
|
80
|
+
export declare const _checkRubricForTests: typeof checkRubric;
|
|
81
|
+
export declare const _renderMarkdownLeaderboardForTests: typeof renderMarkdownLeaderboard;
|
|
82
|
+
export {};
|
|
83
|
+
//# sourceMappingURL=benchmark.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmark.d.ts","sourceRoot":"","sources":["../../src/commands/benchmark.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ;gFAC4E;IAC5E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EACJ,gBAAgB,GAChB,oBAAoB,GACpB,eAAe,GACf,uBAAuB,GACvB,iBAAiB,GACjB,qBAAqB,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;CACrB;AAyUD,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED,iBAAS,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAUjE;AAiFD,iBAAS,yBAAyB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAuErE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwD9E;AAED,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,oBAAoB,oBAAc,CAAC;AAChD,eAAO,MAAM,kCAAkC,kCAA4B,CAAC"}
|
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mneme benchmark` — the AI Memory Benchmark.
|
|
3
|
+
*
|
|
4
|
+
* Strategic positioning: the Lighthouse-of-AI-memory. Mneme grades AI
|
|
5
|
+
* memory implementations (Mneme itself, Claude's native context, GPT's,
|
|
6
|
+
* Cursor's bundled, etc.) using a standardized probe set + the same
|
|
7
|
+
* Super Sonic Engine grader that already ships in Mneme.
|
|
8
|
+
*
|
|
9
|
+
* Why this is uniquely Mneme's seat: when every AI vendor ships native
|
|
10
|
+
* "repo memory", who grades them? Anthropic can't grade Anthropic;
|
|
11
|
+
* OpenAI can't grade OpenAI. Mneme is the only vendor-neutral auditor
|
|
12
|
+
* — and the only one that can publish a fair public leaderboard.
|
|
13
|
+
*
|
|
14
|
+
* v0.1 ships:
|
|
15
|
+
* • Probe set (24 memory questions across 6 categories)
|
|
16
|
+
* • Local-mode benchmarking (grades Mneme itself end-to-end)
|
|
17
|
+
* • Markdown leaderboard generation
|
|
18
|
+
* • Stub for future "external mode" that grades third-party memory
|
|
19
|
+
* implementations via their public APIs
|
|
20
|
+
*/
|
|
21
|
+
import { writeFileSync } from "node:fs";
|
|
22
|
+
import kleur from "kleur";
|
|
23
|
+
import { ui } from "../ui.js";
|
|
24
|
+
import { git, retrieve, store } from "@mneme-ai/core";
|
|
25
|
+
import { resolveEmbedder } from "@mneme-ai/embeddings";
|
|
26
|
+
import { dbPath } from "../paths.js";
|
|
27
|
+
/** The 24-probe v0.1 benchmark set.
|
|
28
|
+
* Designed to be repository-agnostic — works on any indexed Mneme repo
|
|
29
|
+
* with a non-trivial git history. */
|
|
30
|
+
const PROBES = [
|
|
31
|
+
// ─── factual-recall (4) ───────────────────────────────────────────
|
|
32
|
+
{
|
|
33
|
+
id: "fr-01",
|
|
34
|
+
category: "factual-recall",
|
|
35
|
+
question: "Who is the most recent author to commit to this repo?",
|
|
36
|
+
rubric: [
|
|
37
|
+
{
|
|
38
|
+
id: "names-author",
|
|
39
|
+
description: "Answer names a specific author (email or name pattern)",
|
|
40
|
+
must_match: [/[a-z0-9._%+-]+@[a-z0-9.-]+|\b[A-Z][a-z]+\s+[A-Z][a-z]+/],
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "fr-02",
|
|
46
|
+
category: "factual-recall",
|
|
47
|
+
question: "What is the total number of commits in this repo?",
|
|
48
|
+
rubric: [
|
|
49
|
+
{
|
|
50
|
+
id: "states-number",
|
|
51
|
+
description: "Answer states a specific commit count number",
|
|
52
|
+
must_match: [/\b\d+\b\s*(commits?|total)/i],
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "fr-03",
|
|
58
|
+
category: "factual-recall",
|
|
59
|
+
question: "What is the date of the oldest commit in this repo?",
|
|
60
|
+
rubric: [
|
|
61
|
+
{
|
|
62
|
+
id: "states-date",
|
|
63
|
+
description: "Answer mentions a year or ISO-8601 date",
|
|
64
|
+
must_match: [/\b(19|20)\d{2}\b|\b\d{4}-\d{2}-\d{2}\b/],
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "fr-04",
|
|
70
|
+
category: "factual-recall",
|
|
71
|
+
question: "Name 3 distinct files that have been modified in this repo's history.",
|
|
72
|
+
rubric: [
|
|
73
|
+
{
|
|
74
|
+
id: "lists-files",
|
|
75
|
+
description: "Answer lists at least 3 file path-looking strings",
|
|
76
|
+
must_match: [/[\w./-]+\.(ts|js|tsx|jsx|py|go|rs|md|json)/],
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
// ─── causal-explanation (4) ───────────────────────────────────────
|
|
81
|
+
{
|
|
82
|
+
id: "ce-01",
|
|
83
|
+
category: "causal-explanation",
|
|
84
|
+
question: "Pick any file that has been edited 3+ times. Explain WHY it has been edited that often.",
|
|
85
|
+
rubric: [
|
|
86
|
+
{
|
|
87
|
+
id: "cites-commits",
|
|
88
|
+
description: "Cites at least one commit hash (≥7 hex chars)",
|
|
89
|
+
must_match: [/\b[a-f0-9]{7,40}\b/i],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: "explains-cause",
|
|
93
|
+
description: "Uses causal language (because/due to/in response to)",
|
|
94
|
+
must_match: [/\b(because|due to|in response to|after|to fix|to handle)\b/i],
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "ce-02",
|
|
100
|
+
category: "causal-explanation",
|
|
101
|
+
question: "What was the most recent breaking change or refactor in this repo, and what motivated it?",
|
|
102
|
+
rubric: [
|
|
103
|
+
{
|
|
104
|
+
id: "names-change",
|
|
105
|
+
description: "Names a specific change (commit hash or PR or feature)",
|
|
106
|
+
must_match: [/\b[a-f0-9]{7,40}\b|\bPR\s*#?\d+|\b(refactor|migrate|switch|replace)\b/i],
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: "ce-03",
|
|
112
|
+
category: "causal-explanation",
|
|
113
|
+
question: "Have any commits been reverted? If so, why?",
|
|
114
|
+
rubric: [
|
|
115
|
+
{
|
|
116
|
+
id: "honest-answer",
|
|
117
|
+
description: "Either cites a revert commit OR honestly says no reverts found",
|
|
118
|
+
must_match: [/\brevert/i, /\bno revert|none|no commits.*revert/i],
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: "ce-04",
|
|
124
|
+
category: "causal-explanation",
|
|
125
|
+
question: "Why does this repo use the testing library / framework that it uses?",
|
|
126
|
+
rubric: [
|
|
127
|
+
{
|
|
128
|
+
id: "answers-or-defers",
|
|
129
|
+
description: "Either explains the choice OR honestly says 'no commit explains this'",
|
|
130
|
+
must_match: [
|
|
131
|
+
/\b(chose|chosen|switched|migrated|because)\b/i,
|
|
132
|
+
/\b(no commit|cannot find|unverifiable|no record)\b/i,
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
// ─── lineage-trace (4) ────────────────────────────────────────────
|
|
138
|
+
{
|
|
139
|
+
id: "lt-01",
|
|
140
|
+
category: "lineage-trace",
|
|
141
|
+
question: "Pick any function or class. Who originally wrote it, and who else has modified it?",
|
|
142
|
+
rubric: [
|
|
143
|
+
{
|
|
144
|
+
id: "names-multiple-authors",
|
|
145
|
+
description: "Names at least 2 distinct authors OR cites multiple commits",
|
|
146
|
+
must_match: [/\b[A-Z][a-z]+\b.*\band\s+[A-Z][a-z]+|\b[a-f0-9]{7,40}\b.*\b[a-f0-9]{7,40}\b/i],
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: "lt-02",
|
|
152
|
+
category: "lineage-trace",
|
|
153
|
+
question: "Identify a code pattern (e.g. error handling style) that appears in multiple files. Who introduced it first?",
|
|
154
|
+
rubric: [
|
|
155
|
+
{
|
|
156
|
+
id: "names-originator",
|
|
157
|
+
description: "Names the originating commit or author",
|
|
158
|
+
must_match: [/\b[a-f0-9]{7,40}\b|\b[A-Z][a-z]+\b\s+(introduced|first|originated)/i],
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
id: "lt-03",
|
|
164
|
+
category: "lineage-trace",
|
|
165
|
+
question: "Has any file been deleted from this repo? Trace its history.",
|
|
166
|
+
rubric: [
|
|
167
|
+
{
|
|
168
|
+
id: "honest-answer",
|
|
169
|
+
description: "Either traces a deletion OR honestly says no deletions found",
|
|
170
|
+
must_match: [/\bdeleted|\bremoved|\bno deletions|\bnone found/i],
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "lt-04",
|
|
176
|
+
category: "lineage-trace",
|
|
177
|
+
question: "Which directory or module has the most concentrated authorship (one person owns most of it)?",
|
|
178
|
+
rubric: [
|
|
179
|
+
{
|
|
180
|
+
id: "names-directory",
|
|
181
|
+
description: "Names a specific directory or path",
|
|
182
|
+
must_match: [/[\w/-]+\//],
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
// ─── regression-prediction (4) ────────────────────────────────────
|
|
187
|
+
{
|
|
188
|
+
id: "rp-01",
|
|
189
|
+
category: "regression-prediction",
|
|
190
|
+
question: "If I refactor the most-edited file in this repo, what's the historical risk of regression?",
|
|
191
|
+
rubric: [
|
|
192
|
+
{
|
|
193
|
+
id: "uses-evidence",
|
|
194
|
+
description: "Bases the answer on past commit/incident data",
|
|
195
|
+
must_match: [/\b(past|history|previous|earlier)\b/i],
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: "states-risk",
|
|
199
|
+
description: "States a risk level or probability",
|
|
200
|
+
must_match: [/\b(high|medium|low|likely|risk|probability)\b/i],
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: "rp-02",
|
|
206
|
+
category: "regression-prediction",
|
|
207
|
+
question: "Which files in this repo have the highest 'regret rate' (shipped and quickly fixed)?",
|
|
208
|
+
rubric: [
|
|
209
|
+
{
|
|
210
|
+
id: "names-files",
|
|
211
|
+
description: "Names specific files",
|
|
212
|
+
must_match: [/[\w./-]+\.(ts|js|tsx|jsx|py|go|rs|md|json)/],
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
id: "rp-03",
|
|
218
|
+
category: "regression-prediction",
|
|
219
|
+
question: "Are there any files that get edited together repeatedly (high coupling)?",
|
|
220
|
+
rubric: [
|
|
221
|
+
{
|
|
222
|
+
id: "answers",
|
|
223
|
+
description: "Names coupled files OR honestly says insufficient data",
|
|
224
|
+
must_match: [
|
|
225
|
+
/[\w./-]+\.(ts|js|tsx|jsx|py|go|rs|md|json)/,
|
|
226
|
+
/\b(insufficient|no.*signal|cannot find)\b/i,
|
|
227
|
+
],
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
id: "rp-04",
|
|
233
|
+
category: "regression-prediction",
|
|
234
|
+
question: "Which contributor is most likely to introduce a bug they personally fix later?",
|
|
235
|
+
rubric: [
|
|
236
|
+
{
|
|
237
|
+
id: "honest-or-named",
|
|
238
|
+
description: "Either names a specific contributor OR declines if data is insufficient",
|
|
239
|
+
must_match: [/[a-z0-9._%+-]+@[a-z0-9.-]+|\b[A-Z][a-z]+\s+[A-Z][a-z]+|\b(insufficient|cannot find)\b/i],
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
},
|
|
243
|
+
// ─── cited-rationale (4) ──────────────────────────────────────────
|
|
244
|
+
{
|
|
245
|
+
id: "cr-01",
|
|
246
|
+
category: "cited-rationale",
|
|
247
|
+
question: "Cite a specific commit hash and explain its purpose in your own words.",
|
|
248
|
+
rubric: [
|
|
249
|
+
{
|
|
250
|
+
id: "real-hash",
|
|
251
|
+
description: "Includes a 7-40 char hex hash (verified externally as real later)",
|
|
252
|
+
must_match: [/\b[a-f0-9]{7,40}\b/i],
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
id: "non-trivial-explanation",
|
|
256
|
+
description: "Explanation is at least 50 chars",
|
|
257
|
+
must_match: [/.{50,}/],
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
id: "cr-02",
|
|
263
|
+
category: "cited-rationale",
|
|
264
|
+
question: "Find a PR (pull request) referenced in commit messages. Summarize what it accomplished.",
|
|
265
|
+
rubric: [
|
|
266
|
+
{
|
|
267
|
+
id: "references-pr",
|
|
268
|
+
description: "References a PR number or URL",
|
|
269
|
+
must_match: [/\bPR\s*#?\d+|#\d+|pull[-/]?request/i],
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
id: "cr-03",
|
|
275
|
+
category: "cited-rationale",
|
|
276
|
+
question: "What's the most-recent fix (a commit whose message contains 'fix' or 'bug')?",
|
|
277
|
+
rubric: [
|
|
278
|
+
{
|
|
279
|
+
id: "names-fix",
|
|
280
|
+
description: "Names a specific fix commit (hash or subject)",
|
|
281
|
+
must_match: [/\b[a-f0-9]{7,40}\b|\bfix\b|\bbug\b/i],
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
id: "cr-04",
|
|
287
|
+
category: "cited-rationale",
|
|
288
|
+
question: "What's the longest commit message in this repo?",
|
|
289
|
+
rubric: [
|
|
290
|
+
{
|
|
291
|
+
id: "answers",
|
|
292
|
+
description: "Either provides excerpt OR honestly says cannot determine",
|
|
293
|
+
must_match: [/.{30,}/],
|
|
294
|
+
},
|
|
295
|
+
],
|
|
296
|
+
},
|
|
297
|
+
// ─── uncertainty-honesty (4) ──────────────────────────────────────
|
|
298
|
+
{
|
|
299
|
+
id: "uh-01",
|
|
300
|
+
category: "uncertainty-honesty",
|
|
301
|
+
question: "Tell me about commit deadbeefdeadbeefdeadbeefdeadbeefdeadbeef.",
|
|
302
|
+
rubric: [
|
|
303
|
+
{
|
|
304
|
+
id: "rejects-fake-hash",
|
|
305
|
+
description: "Refuses to fabricate; says hash not found",
|
|
306
|
+
must_match: [/\bnot found|cannot find|does not exist|no.*such commit|unknown commit/i],
|
|
307
|
+
must_not_match: [/\bauthored|introduced|added\b/i],
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
id: "uh-02",
|
|
313
|
+
category: "uncertainty-honesty",
|
|
314
|
+
question: "What is the salary of the original author of this repo?",
|
|
315
|
+
rubric: [
|
|
316
|
+
{
|
|
317
|
+
id: "refuses-irrelevant-question",
|
|
318
|
+
description: "Refuses to speculate or says repo doesn't contain salary info",
|
|
319
|
+
must_match: [/\bcannot|don't know|not.*recorded|repo.*doesn't|no.*information/i],
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
id: "uh-03",
|
|
325
|
+
category: "uncertainty-honesty",
|
|
326
|
+
question: "Is the current main branch ready for a production release? Yes or no?",
|
|
327
|
+
rubric: [
|
|
328
|
+
{
|
|
329
|
+
id: "qualified-answer",
|
|
330
|
+
description: "Provides a qualified answer with caveats — never absolute yes/no without evidence",
|
|
331
|
+
must_match: [/\b(depends|caveat|however|but|risk|review|test)\b/i],
|
|
332
|
+
},
|
|
333
|
+
],
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
id: "uh-04",
|
|
337
|
+
category: "uncertainty-honesty",
|
|
338
|
+
question: "What was the team's mood when they wrote the most recent commit?",
|
|
339
|
+
rubric: [
|
|
340
|
+
{
|
|
341
|
+
id: "refuses-mood-inference",
|
|
342
|
+
description: "Acknowledges that commit messages don't encode mood",
|
|
343
|
+
must_match: [/\bcannot infer|don't know|not.*recorded|no.*signal|outside.*scope/i],
|
|
344
|
+
},
|
|
345
|
+
],
|
|
346
|
+
},
|
|
347
|
+
];
|
|
348
|
+
function checkRubric(rubric, answer) {
|
|
349
|
+
if (rubric.must_match) {
|
|
350
|
+
const anyMatched = rubric.must_match.some((re) => re.test(answer));
|
|
351
|
+
if (!anyMatched)
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
if (rubric.must_not_match) {
|
|
355
|
+
const anyForbidden = rubric.must_not_match.some((re) => re.test(answer));
|
|
356
|
+
if (anyForbidden)
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
async function runMnemeSelfBenchmark(opts) {
|
|
362
|
+
if (!(await git.isGitRepo(opts.cwd))) {
|
|
363
|
+
throw new Error("Not in a git repo. Run `mneme init` first.");
|
|
364
|
+
}
|
|
365
|
+
const meta = await git.getRepoMeta(opts.cwd);
|
|
366
|
+
const s = new store.MnemeStore(dbPath(meta.rootPath));
|
|
367
|
+
const embedder = await resolveEmbedder({ provider: "auto" });
|
|
368
|
+
const probeResults = [];
|
|
369
|
+
for (const probe of opts.probes) {
|
|
370
|
+
const t0 = Date.now();
|
|
371
|
+
let answer = "";
|
|
372
|
+
try {
|
|
373
|
+
const r = await retrieve.ask(probe.question, {
|
|
374
|
+
store: s,
|
|
375
|
+
embedder,
|
|
376
|
+
repo: meta,
|
|
377
|
+
topK: 8,
|
|
378
|
+
});
|
|
379
|
+
answer = r.summary || "";
|
|
380
|
+
// Append top-3 cited identifiers to answer text so rubrics that look
|
|
381
|
+
// for hashes/PR numbers can find them. Citation.id is the commit hash
|
|
382
|
+
// (kind="commit") or the PR number string (kind="pr").
|
|
383
|
+
for (const c of r.citations.slice(0, 3)) {
|
|
384
|
+
answer += " " + c.id;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
catch (err) {
|
|
388
|
+
answer = `[error: ${err.message}]`;
|
|
389
|
+
}
|
|
390
|
+
const durationMs = Date.now() - t0;
|
|
391
|
+
let passed = 0;
|
|
392
|
+
const failedRubrics = [];
|
|
393
|
+
for (const rubric of probe.rubric) {
|
|
394
|
+
if (checkRubric(rubric, answer))
|
|
395
|
+
passed++;
|
|
396
|
+
else
|
|
397
|
+
failedRubrics.push({ id: rubric.id, description: rubric.description });
|
|
398
|
+
}
|
|
399
|
+
probeResults.push({
|
|
400
|
+
probeId: probe.id,
|
|
401
|
+
category: probe.category,
|
|
402
|
+
question: probe.question,
|
|
403
|
+
answer,
|
|
404
|
+
passed,
|
|
405
|
+
total: probe.rubric.length,
|
|
406
|
+
failedRubrics,
|
|
407
|
+
durationMs,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
const totalRubricChecks = probeResults.reduce((s, r) => s + r.total, 0);
|
|
411
|
+
const passedRubricChecks = probeResults.reduce((s, r) => s + r.passed, 0);
|
|
412
|
+
const scoreByCategory = {};
|
|
413
|
+
for (const r of probeResults) {
|
|
414
|
+
if (!scoreByCategory[r.category]) {
|
|
415
|
+
scoreByCategory[r.category] = { passed: 0, total: 0, pct: 0 };
|
|
416
|
+
}
|
|
417
|
+
scoreByCategory[r.category].passed += r.passed;
|
|
418
|
+
scoreByCategory[r.category].total += r.total;
|
|
419
|
+
}
|
|
420
|
+
for (const cat of Object.values(scoreByCategory)) {
|
|
421
|
+
cat.pct = cat.total > 0 ? cat.passed / cat.total : 0;
|
|
422
|
+
}
|
|
423
|
+
const overallScore = totalRubricChecks > 0 ? passedRubricChecks / totalRubricChecks : 0;
|
|
424
|
+
return {
|
|
425
|
+
target: "mneme-self",
|
|
426
|
+
ranAt: new Date().toISOString(),
|
|
427
|
+
totalProbes: opts.probes.length,
|
|
428
|
+
totalRubricChecks,
|
|
429
|
+
passedRubricChecks,
|
|
430
|
+
scoreByCategory,
|
|
431
|
+
overallScore,
|
|
432
|
+
probeResults,
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
function renderMarkdownLeaderboard(results) {
|
|
436
|
+
const lines = [];
|
|
437
|
+
lines.push("# Mneme — AI Memory Benchmark");
|
|
438
|
+
lines.push("");
|
|
439
|
+
lines.push("> *The Lighthouse-of-AI-memory. Vendor-neutral grading of how well each AI memory implementation answers questions about a real repo.*");
|
|
440
|
+
lines.push("");
|
|
441
|
+
lines.push(`**Run at:** ${new Date().toISOString().slice(0, 19).replace("T", " ")} UTC`);
|
|
442
|
+
lines.push(`**Probe count:** ${results[0]?.totalProbes ?? 0} questions across 6 categories`);
|
|
443
|
+
lines.push(`**Repo:** the indexed working tree`);
|
|
444
|
+
lines.push("");
|
|
445
|
+
lines.push("## Leaderboard");
|
|
446
|
+
lines.push("");
|
|
447
|
+
lines.push("| Rank | Implementation | Overall score | Recall | Causal | Lineage | Regression | Citation | Honesty |");
|
|
448
|
+
lines.push("|---:|---|---:|---:|---:|---:|---:|---:|---:|");
|
|
449
|
+
const sorted = [...results].sort((a, b) => b.overallScore - a.overallScore);
|
|
450
|
+
sorted.forEach((r, i) => {
|
|
451
|
+
const row = [
|
|
452
|
+
`${i + 1}`,
|
|
453
|
+
`**${r.target}**`,
|
|
454
|
+
`${(r.overallScore * 100).toFixed(1)}%`,
|
|
455
|
+
`${(((r.scoreByCategory["factual-recall"]?.pct ?? 0) * 100)).toFixed(0)}%`,
|
|
456
|
+
`${(((r.scoreByCategory["causal-explanation"]?.pct ?? 0) * 100)).toFixed(0)}%`,
|
|
457
|
+
`${(((r.scoreByCategory["lineage-trace"]?.pct ?? 0) * 100)).toFixed(0)}%`,
|
|
458
|
+
`${(((r.scoreByCategory["regression-prediction"]?.pct ?? 0) * 100)).toFixed(0)}%`,
|
|
459
|
+
`${(((r.scoreByCategory["cited-rationale"]?.pct ?? 0) * 100)).toFixed(0)}%`,
|
|
460
|
+
`${(((r.scoreByCategory["uncertainty-honesty"]?.pct ?? 0) * 100)).toFixed(0)}%`,
|
|
461
|
+
];
|
|
462
|
+
lines.push(`| ${row.join(" | ")} |`);
|
|
463
|
+
});
|
|
464
|
+
lines.push("");
|
|
465
|
+
lines.push("## Methodology");
|
|
466
|
+
lines.push("");
|
|
467
|
+
lines.push("Each implementation is asked the same 24 standardized memory questions, grouped into 6 categories:");
|
|
468
|
+
lines.push("");
|
|
469
|
+
lines.push("- **Factual recall** — \"who is the most recent author?\", commit count, date ranges");
|
|
470
|
+
lines.push("- **Causal explanation** — \"why was this file edited 3 times?\" — must cite + use causal language");
|
|
471
|
+
lines.push("- **Lineage trace** — multi-author code archaeology questions");
|
|
472
|
+
lines.push("- **Regression prediction** — historical-data-grounded risk estimation");
|
|
473
|
+
lines.push("- **Cited rationale** — must include real commit hashes / PRs");
|
|
474
|
+
lines.push("- **Uncertainty honesty** — refuses to fabricate when asked about non-existent data");
|
|
475
|
+
lines.push("");
|
|
476
|
+
lines.push("Scoring is binary per rubric (pass/fail), computed by deterministic regex patterns. No LLM-as-judge — fully reproducible.");
|
|
477
|
+
lines.push("");
|
|
478
|
+
lines.push("**Why a vendor-neutral benchmark matters:** Anthropic can't be the auditor of Anthropic. OpenAI can't be neutral about OpenAI. Mneme is the only memory implementation maintained by no AI vendor — and the only one that can publish a fair leaderboard across all of them.");
|
|
479
|
+
lines.push("");
|
|
480
|
+
lines.push("## Per-target details");
|
|
481
|
+
lines.push("");
|
|
482
|
+
for (const r of sorted) {
|
|
483
|
+
lines.push(`### ${r.target}`);
|
|
484
|
+
lines.push("");
|
|
485
|
+
lines.push(`Overall: **${(r.overallScore * 100).toFixed(1)}%** (${r.passedRubricChecks}/${r.totalRubricChecks} rubric checks)`);
|
|
486
|
+
lines.push("");
|
|
487
|
+
const failed = r.probeResults.filter((p) => p.failedRubrics.length > 0);
|
|
488
|
+
if (failed.length === 0) {
|
|
489
|
+
lines.push("All probes passed every rubric check. ✅");
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
lines.push(`Failed rubric checks (${failed.length} probes):`);
|
|
493
|
+
lines.push("");
|
|
494
|
+
for (const f of failed.slice(0, 5)) {
|
|
495
|
+
lines.push(`- **${f.probeId}** [${f.category}] *"${f.question}"* — failed: ${f.failedRubrics.map((x) => x.id).join(", ")}`);
|
|
496
|
+
}
|
|
497
|
+
if (failed.length > 5)
|
|
498
|
+
lines.push(`- … and ${failed.length - 5} more`);
|
|
499
|
+
}
|
|
500
|
+
lines.push("");
|
|
501
|
+
}
|
|
502
|
+
lines.push("---");
|
|
503
|
+
lines.push("");
|
|
504
|
+
lines.push("> Run this benchmark on your own repo: `mneme benchmark --out ./benchmark.md`");
|
|
505
|
+
lines.push(">");
|
|
506
|
+
lines.push("> The benchmark suite is open and pull requests adding new targets (Claude memory, GPT-4 memory, Cursor's bundled memory, etc.) are welcome.");
|
|
507
|
+
return lines.join("\n");
|
|
508
|
+
}
|
|
509
|
+
export async function benchmarkCommand(opts) {
|
|
510
|
+
const probes = typeof opts.probes === "number"
|
|
511
|
+
? PROBES.slice(0, Math.max(1, Math.min(PROBES.length, opts.probes)))
|
|
512
|
+
: PROBES;
|
|
513
|
+
const targets = (opts.targets && opts.targets.length > 0) ? opts.targets : ["mneme-self"];
|
|
514
|
+
if (!opts.json)
|
|
515
|
+
ui.banner();
|
|
516
|
+
if (!opts.json) {
|
|
517
|
+
process.stdout.write(kleur.bold("\n 🏁 Mneme — AI Memory Benchmark\n\n") +
|
|
518
|
+
` Running ${probes.length} probes across 6 categories on ${targets.length} target${targets.length === 1 ? "" : "s"}.\n` +
|
|
519
|
+
` Methodology: vendor-neutral · deterministic scoring · open suite.\n\n`);
|
|
520
|
+
}
|
|
521
|
+
const results = [];
|
|
522
|
+
for (const target of targets) {
|
|
523
|
+
if (target !== "mneme-self") {
|
|
524
|
+
ui.warn(`Target "${target}" not yet supported in v0.1 — only "mneme-self" works for now.`);
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
if (!opts.json)
|
|
528
|
+
ui.dim(` ▸ ${target} ...`);
|
|
529
|
+
const r = await runMnemeSelfBenchmark({ cwd: opts.cwd, probes });
|
|
530
|
+
results.push(r);
|
|
531
|
+
if (!opts.json) {
|
|
532
|
+
ui.raw(` ${kleur.bold(target.padEnd(16))} ` +
|
|
533
|
+
`score=${kleur.cyan((r.overallScore * 100).toFixed(1) + "%")} ` +
|
|
534
|
+
`(${r.passedRubricChecks}/${r.totalRubricChecks})\n`);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
const md = renderMarkdownLeaderboard(results);
|
|
538
|
+
if (opts.out) {
|
|
539
|
+
writeFileSync(opts.out, md, "utf8");
|
|
540
|
+
if (!opts.json) {
|
|
541
|
+
ui.success(`\n Leaderboard written to ${opts.out}`);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
if (opts.json) {
|
|
545
|
+
process.stdout.write(JSON.stringify({ results }, null, 2) + "\n");
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
process.stdout.write("\n" +
|
|
549
|
+
kleur.bold(" Why this matters:") +
|
|
550
|
+
" when every AI vendor ships native repo memory — Claude, GPT, Cursor — \n" +
|
|
551
|
+
" none of them can be the neutral auditor. Mneme is. " +
|
|
552
|
+
kleur.dim("[the Lighthouse-of-AI-memory positioning]") +
|
|
553
|
+
"\n\n");
|
|
554
|
+
}
|
|
555
|
+
return 0;
|
|
556
|
+
}
|
|
557
|
+
export const _PROBES_FOR_TESTS = PROBES;
|
|
558
|
+
export const _checkRubricForTests = checkRubric;
|
|
559
|
+
export const _renderMarkdownLeaderboardForTests = renderMarkdownLeaderboard;
|
|
560
|
+
//# sourceMappingURL=benchmark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmark.js","sourceRoot":"","sources":["../../src/commands/benchmark.ts"],"names":[],"mappings":"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"}
|