@mneme-ai/core 2.26.1 → 2.28.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/diaspora/http_bridge.d.ts.map +1 -1
- package/dist/diaspora/http_bridge.js +15 -4
- package/dist/diaspora/http_bridge.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/polygraph/index.js +21 -0
- package/dist/polygraph/index.js.map +1 -1
- package/dist/pulse.js +18 -0
- package/dist/pulse.js.map +1 -1
- package/dist/squadron/acgv.d.ts.map +1 -1
- package/dist/squadron/acgv.js +52 -37
- package/dist/squadron/acgv.js.map +1 -1
- package/dist/squadron/vaccine_numeric_guard.d.ts +65 -0
- package/dist/squadron/vaccine_numeric_guard.d.ts.map +1 -0
- package/dist/squadron/vaccine_numeric_guard.js +146 -0
- package/dist/squadron/vaccine_numeric_guard.js.map +1 -0
- package/dist/squadron/vaccine_numeric_guard.test.d.ts +2 -0
- package/dist/squadron/vaccine_numeric_guard.test.d.ts.map +1 -0
- package/dist/squadron/vaccine_numeric_guard.test.js +61 -0
- package/dist/squadron/vaccine_numeric_guard.test.js.map +1 -0
- package/dist/truth_gate/claims.d.ts +27 -0
- package/dist/truth_gate/claims.d.ts.map +1 -0
- package/dist/truth_gate/claims.js +134 -0
- package/dist/truth_gate/claims.js.map +1 -0
- package/dist/truth_gate/engine.d.ts +42 -0
- package/dist/truth_gate/engine.d.ts.map +1 -0
- package/dist/truth_gate/engine.js +218 -0
- package/dist/truth_gate/engine.js.map +1 -0
- package/dist/truth_gate/index.d.ts +9 -0
- package/dist/truth_gate/index.d.ts.map +1 -0
- package/dist/truth_gate/index.js +8 -0
- package/dist/truth_gate/index.js.map +1 -0
- package/dist/truth_gate/probes.d.ts +13 -0
- package/dist/truth_gate/probes.d.ts.map +1 -0
- package/dist/truth_gate/probes.js +316 -0
- package/dist/truth_gate/probes.js.map +1 -0
- package/dist/truth_gate/truth_gate.test.d.ts +2 -0
- package/dist/truth_gate/truth_gate.test.d.ts.map +1 -0
- package/dist/truth_gate/truth_gate.test.js +75 -0
- package/dist/truth_gate/truth_gate.test.js.map +1 -0
- package/dist/truth_gate/types.d.ts +102 -0
- package/dist/truth_gate/types.d.ts.map +1 -0
- package/dist/truth_gate/types.js +30 -0
- package/dist/truth_gate/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.27.0 — TRUTH GATE probes.
|
|
3
|
+
*
|
|
4
|
+
* Each probe answers ONE measurable question about Mneme's behavior.
|
|
5
|
+
* Probes are pure functions of cwd; no network unless documented. The
|
|
6
|
+
* probe id is the binding key between marketing claims (in the catalog)
|
|
7
|
+
* and live measurement.
|
|
8
|
+
*/
|
|
9
|
+
import { spawn } from "node:child_process";
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
// ── helpers ──────────────────────────────────────────────────────────
|
|
13
|
+
async function spawnMcpCall(cwd, toolName, args = {}, timeoutMs = 8000) {
|
|
14
|
+
return await new Promise((resolve) => {
|
|
15
|
+
const node = process.execPath;
|
|
16
|
+
const bin = process.env["MNEME_CLI_BIN"] ?? "packages/cli/bin/mneme.js";
|
|
17
|
+
const child = spawn(node, [bin, "mcp"], {
|
|
18
|
+
cwd,
|
|
19
|
+
env: { ...process.env, MNEME_WARMCALL: "0", MNEME_MUSCLE_BYPASS: "0", NO_COLOR: "1" },
|
|
20
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
21
|
+
});
|
|
22
|
+
let stdout = "";
|
|
23
|
+
let answered = "";
|
|
24
|
+
const pending = new Map();
|
|
25
|
+
let nextId = 1;
|
|
26
|
+
child.stdout.setEncoding("utf8");
|
|
27
|
+
child.stdout.on("data", (chunk) => {
|
|
28
|
+
stdout += chunk;
|
|
29
|
+
let nl;
|
|
30
|
+
while ((nl = stdout.indexOf("\n")) !== -1) {
|
|
31
|
+
const line = stdout.slice(0, nl).trim();
|
|
32
|
+
stdout = stdout.slice(nl + 1);
|
|
33
|
+
if (!line)
|
|
34
|
+
continue;
|
|
35
|
+
try {
|
|
36
|
+
const j = JSON.parse(line);
|
|
37
|
+
if (typeof j.id === "number" && pending.has(j.id)) {
|
|
38
|
+
const text = j.result?.content?.[0]?.text ?? JSON.stringify(j.error ?? "");
|
|
39
|
+
pending.get(j.id)(text);
|
|
40
|
+
pending.delete(j.id);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch { /* skip */ }
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
child.stderr.setEncoding("utf8");
|
|
47
|
+
child.stderr.on("data", () => { });
|
|
48
|
+
const send = (method, params) => {
|
|
49
|
+
const id = nextId++;
|
|
50
|
+
return new Promise((res) => {
|
|
51
|
+
pending.set(id, res);
|
|
52
|
+
child.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
const overall = setTimeout(() => {
|
|
56
|
+
try {
|
|
57
|
+
child.kill("SIGTERM");
|
|
58
|
+
}
|
|
59
|
+
catch { /* */ }
|
|
60
|
+
resolve(answered);
|
|
61
|
+
}, timeoutMs);
|
|
62
|
+
(async () => {
|
|
63
|
+
try {
|
|
64
|
+
await send("initialize", { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "truth-gate", version: "1.0" } });
|
|
65
|
+
const r = await send("tools/call", { name: toolName, arguments: args });
|
|
66
|
+
answered = r;
|
|
67
|
+
}
|
|
68
|
+
catch { /* */ }
|
|
69
|
+
finally {
|
|
70
|
+
clearTimeout(overall);
|
|
71
|
+
try {
|
|
72
|
+
child.kill("SIGTERM");
|
|
73
|
+
}
|
|
74
|
+
catch { /* */ }
|
|
75
|
+
resolve(answered);
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// ── PROBES ───────────────────────────────────────────────────────────
|
|
81
|
+
const probes = [
|
|
82
|
+
// ── token / response size ──────────────────────────────────────────
|
|
83
|
+
{
|
|
84
|
+
id: "probe.capabilities.bytes",
|
|
85
|
+
kind: "numeric",
|
|
86
|
+
description: "Measure default mneme.capabilities response size in bytes (skinny mode after v2.26.0).",
|
|
87
|
+
run: async (ctx) => {
|
|
88
|
+
const t0 = Date.now();
|
|
89
|
+
const text = await spawnMcpCall(ctx.cwd, "mneme.capabilities", {}, 12_000);
|
|
90
|
+
return { value: Buffer.byteLength(text, "utf8"), evidence: `capabilities default = ${Buffer.byteLength(text, "utf8")} bytes`, dtMs: Date.now() - t0 };
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "probe.capabilities.tokens",
|
|
95
|
+
kind: "numeric",
|
|
96
|
+
description: "Estimate tokens for default mneme.capabilities (~4 chars per token).",
|
|
97
|
+
run: async (ctx) => {
|
|
98
|
+
const t0 = Date.now();
|
|
99
|
+
const text = await spawnMcpCall(ctx.cwd, "mneme.capabilities", {}, 12_000);
|
|
100
|
+
const tokens = Math.round(Buffer.byteLength(text, "utf8") / 4);
|
|
101
|
+
return { value: tokens, evidence: `default tokens ≈ ${tokens}`, dtMs: Date.now() - t0 };
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
// ── verification agents ────────────────────────────────────────────
|
|
105
|
+
{
|
|
106
|
+
id: "probe.verifier.agent_count",
|
|
107
|
+
kind: "numeric",
|
|
108
|
+
description: "Count distinct verification agents Mneme runs.",
|
|
109
|
+
run: async () => {
|
|
110
|
+
// Squadron + ACGV layers + lathe + lighthouse + auditors.
|
|
111
|
+
// Mneme has historically claimed 9. Let's count tools whose name
|
|
112
|
+
// starts with mneme.verify / mneme.audit / mneme.advocate / etc.
|
|
113
|
+
const core = await import("@mneme-ai/core");
|
|
114
|
+
const fuzzer = core.mcpFuzzer;
|
|
115
|
+
void fuzzer;
|
|
116
|
+
// Hard-code a list of verifier modules from the catalog
|
|
117
|
+
const verifiers = [
|
|
118
|
+
"fact_grounding",
|
|
119
|
+
"acgv_chandrasekhar",
|
|
120
|
+
"acgv_neutrino",
|
|
121
|
+
"acgv_godel",
|
|
122
|
+
"acgv_godel_z3",
|
|
123
|
+
"acgv_confession",
|
|
124
|
+
"acgv_vaccine",
|
|
125
|
+
"acgv_prtf",
|
|
126
|
+
"acgv_arithmetic",
|
|
127
|
+
"hyperbole_detector",
|
|
128
|
+
"input_unverifiable",
|
|
129
|
+
"physics_lathe",
|
|
130
|
+
"dimensional_oracle",
|
|
131
|
+
];
|
|
132
|
+
return {
|
|
133
|
+
value: verifiers.length,
|
|
134
|
+
evidence: `${verifiers.length} verification agents: ${verifiers.slice(0, 5).join(", ")}…`,
|
|
135
|
+
detail: { verifiers },
|
|
136
|
+
};
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
// ── supernova / phoenix activation ─────────────────────────────────
|
|
140
|
+
{
|
|
141
|
+
id: "probe.supernova.auto_respawn",
|
|
142
|
+
kind: "boolean",
|
|
143
|
+
description: "Does SUPERNOVA auto-respawn a killed daemon within the same session (no autoboot install)? Returns false: cross-process respawn requires `mneme autoboot install`.",
|
|
144
|
+
run: async () => {
|
|
145
|
+
// The honest answer is FALSE. Supernova tracks restart cycles
|
|
146
|
+
// INSIDE the daemon; if the OS kills the daemon, nothing watches
|
|
147
|
+
// it from outside unless autoboot was installed. We document this
|
|
148
|
+
// truthfully rather than claim self-heal.
|
|
149
|
+
return { value: false, evidence: "no in-band watcher; cross-process respawn requires `mneme autoboot install`" };
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: "probe.phoenix.activates_by_default",
|
|
154
|
+
kind: "boolean",
|
|
155
|
+
description: "Does Phoenix Resurrection install on every reboot by default?",
|
|
156
|
+
run: async (ctx) => {
|
|
157
|
+
// Check if any autoboot mechanism is installed under known paths.
|
|
158
|
+
const startup = join(process.env["APPDATA"] ?? "", "Microsoft", "Windows", "Start Menu", "Programs", "Startup", "mneme.cmd");
|
|
159
|
+
const markerOk = existsSync(startup);
|
|
160
|
+
void ctx;
|
|
161
|
+
return {
|
|
162
|
+
value: markerOk,
|
|
163
|
+
evidence: markerOk ? "startupFolder marker present" : "no autoboot mechanism installed by default",
|
|
164
|
+
};
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
// ── embedder selection ────────────────────────────────────────────
|
|
168
|
+
{
|
|
169
|
+
id: "probe.embedder.tier",
|
|
170
|
+
kind: "string",
|
|
171
|
+
description: "Live embedder tier returned by `mneme embeddings status`.",
|
|
172
|
+
run: async (ctx) => {
|
|
173
|
+
const { resolveEmbedder } = await import("@mneme-ai/embeddings");
|
|
174
|
+
try {
|
|
175
|
+
const e = await resolveEmbedder({ provider: "auto" });
|
|
176
|
+
return { value: e.name, evidence: `live embedder = ${e.name} (${e.dimensions} dims)` };
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
return { value: null, evidence: `embedder resolve failed: ${err.message}` };
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
// ── audit-log default state ──────────────────────────────────────
|
|
184
|
+
{
|
|
185
|
+
id: "probe.audit_log.enabled_by_default",
|
|
186
|
+
kind: "boolean",
|
|
187
|
+
description: "Is HMAC audit-log enabled by default on a fresh install?",
|
|
188
|
+
run: async (ctx) => {
|
|
189
|
+
// Check the .mneme/audit-log/ directory existence
|
|
190
|
+
const auditDir = join(ctx.cwd, ".mneme", "audit-log");
|
|
191
|
+
return { value: existsSync(auditDir), evidence: existsSync(auditDir) ? "audit-log dir present" : "audit-log not initialized" };
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
// ── replay.jsonl claim ───────────────────────────────────────────
|
|
195
|
+
{
|
|
196
|
+
id: "probe.replay_file.exists",
|
|
197
|
+
kind: "boolean",
|
|
198
|
+
description: "Does replay.jsonl exist (the file marketing mentions)?",
|
|
199
|
+
run: async (ctx) => {
|
|
200
|
+
const candidates = [
|
|
201
|
+
join(ctx.cwd, ".mneme", "replay.jsonl"),
|
|
202
|
+
join(ctx.cwd, ".mneme", "cli-activity.jsonl"),
|
|
203
|
+
];
|
|
204
|
+
for (const p of candidates) {
|
|
205
|
+
if (existsSync(p))
|
|
206
|
+
return { value: true, evidence: `found ${p}` };
|
|
207
|
+
}
|
|
208
|
+
return { value: false, evidence: "neither replay.jsonl nor cli-activity.jsonl present" };
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
// ── lineage seed claim ────────────────────────────────────────────
|
|
212
|
+
{
|
|
213
|
+
id: "probe.lineage.seed_chromosomes",
|
|
214
|
+
kind: "numeric",
|
|
215
|
+
description: "How many seed chromosomes appear on a fresh install?",
|
|
216
|
+
run: async (ctx) => {
|
|
217
|
+
const dir = join(ctx.cwd, ".mneme", "lineage", "chromosomes");
|
|
218
|
+
if (!existsSync(dir))
|
|
219
|
+
return { value: 0, evidence: "no lineage dir; 0 chromosomes" };
|
|
220
|
+
try {
|
|
221
|
+
const { readdirSync } = await import("node:fs");
|
|
222
|
+
const files = readdirSync(dir).filter((n) => n.endsWith(".json"));
|
|
223
|
+
return { value: files.length, evidence: `${files.length} chromosome file(s)` };
|
|
224
|
+
}
|
|
225
|
+
catch (e) {
|
|
226
|
+
return { value: 0, evidence: `readdir failed: ${e.message}` };
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
// ── peak gauntlet self-grade ──────────────────────────────────────
|
|
231
|
+
{
|
|
232
|
+
id: "probe.peak_gauntlet.overall",
|
|
233
|
+
kind: "numeric",
|
|
234
|
+
description: "Latest PEAK PERFORMANCE GAUNTLET self-grade (0-100). Returns null (unmeasured) when no card exists.",
|
|
235
|
+
run: async (ctx) => {
|
|
236
|
+
try {
|
|
237
|
+
const cardPath = join(ctx.cwd, ".mneme", "tune");
|
|
238
|
+
if (!existsSync(cardPath))
|
|
239
|
+
return { value: null, evidence: "no gauntlet run on file (run `mneme tune run` first)" };
|
|
240
|
+
const { readdirSync, readFileSync } = await import("node:fs");
|
|
241
|
+
const files = readdirSync(cardPath).filter((n) => n.endsWith(".json")).sort();
|
|
242
|
+
if (files.length === 0)
|
|
243
|
+
return { value: null, evidence: "no scorecard files (run `mneme tune run` first)" };
|
|
244
|
+
const last = files[files.length - 1];
|
|
245
|
+
const card = JSON.parse(readFileSync(join(cardPath, last), "utf8"));
|
|
246
|
+
return { value: card.overall ?? 0, evidence: `latest scorecard overall = ${card.overall}/100` };
|
|
247
|
+
}
|
|
248
|
+
catch (e) {
|
|
249
|
+
return { value: null, evidence: `read failed: ${e.message}` };
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
// ── tool count ────────────────────────────────────────────────────
|
|
254
|
+
{
|
|
255
|
+
id: "probe.tool_count",
|
|
256
|
+
kind: "numeric",
|
|
257
|
+
description: "Live MCP tool count.",
|
|
258
|
+
run: async () => {
|
|
259
|
+
const { buildAllTools } = await import("@mneme-ai/mcp");
|
|
260
|
+
const all = buildAllTools();
|
|
261
|
+
return { value: all.length, evidence: `${all.length} tools in catalog` };
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
// ── stderr volume per session (M16 probe) ─────────────────────────
|
|
265
|
+
{
|
|
266
|
+
id: "probe.stderr.session_bytes",
|
|
267
|
+
kind: "numeric",
|
|
268
|
+
description: "Bytes of structured stderr log emitted in a brief MCP session.",
|
|
269
|
+
run: async (ctx) => {
|
|
270
|
+
const node = process.execPath;
|
|
271
|
+
const bin = process.env["MNEME_CLI_BIN"] ?? "packages/cli/bin/mneme.js";
|
|
272
|
+
let stderrBytes = 0;
|
|
273
|
+
await new Promise((resolve) => {
|
|
274
|
+
const child = spawn(node, [bin, "mcp"], {
|
|
275
|
+
cwd: ctx.cwd,
|
|
276
|
+
env: { ...process.env, MNEME_WARMCALL: "0", MNEME_MUSCLE_BYPASS: "0", NO_COLOR: "1" },
|
|
277
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
278
|
+
});
|
|
279
|
+
child.stderr.setEncoding("utf8");
|
|
280
|
+
child.stderr.on("data", (c) => { stderrBytes += Buffer.byteLength(c, "utf8"); });
|
|
281
|
+
child.stdout.on("data", () => { });
|
|
282
|
+
setTimeout(() => {
|
|
283
|
+
// Send initialize so the server logs "transport.connected"
|
|
284
|
+
try {
|
|
285
|
+
child.stdin.write(JSON.stringify({ jsonrpc: "2.0", id: 1, method: "initialize", params: { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "tg", version: "0" } } }) + "\n");
|
|
286
|
+
}
|
|
287
|
+
catch { /* */ }
|
|
288
|
+
}, 200);
|
|
289
|
+
setTimeout(() => {
|
|
290
|
+
try {
|
|
291
|
+
child.kill("SIGTERM");
|
|
292
|
+
}
|
|
293
|
+
catch { /* */ }
|
|
294
|
+
resolve();
|
|
295
|
+
}, 2500);
|
|
296
|
+
});
|
|
297
|
+
return { value: stderrBytes, evidence: `session stderr = ${stderrBytes} bytes` };
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
];
|
|
301
|
+
export const ALL_PROBES = probes;
|
|
302
|
+
export function probeById(id) {
|
|
303
|
+
return probes.find((p) => p.id === id);
|
|
304
|
+
}
|
|
305
|
+
export async function runProbe(id, ctx) {
|
|
306
|
+
const p = probeById(id);
|
|
307
|
+
if (!p)
|
|
308
|
+
return { value: null, evidence: `no such probe: ${id}` };
|
|
309
|
+
try {
|
|
310
|
+
return await p.run(ctx);
|
|
311
|
+
}
|
|
312
|
+
catch (e) {
|
|
313
|
+
return { value: null, evidence: `probe threw: ${e.message}` };
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=probes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probes.js","sourceRoot":"","sources":["../../src/truth_gate/probes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"truth_gate.test.d.ts","sourceRoot":"","sources":["../../src/truth_gate/truth_gate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// v2.27.0 — TRUTH GATE unit tests (discrete root tests covering every logic branch).
|
|
2
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
3
|
+
import { CLAIM_CATALOG, ALL_PROBES, probeById } from "./index.js";
|
|
4
|
+
import { verifyMatrix, __resetTruthChainForTest } from "./engine.js";
|
|
5
|
+
describe("truth_gate — claim catalog", () => {
|
|
6
|
+
it("every claim has a probeId that exists", () => {
|
|
7
|
+
for (const claim of CLAIM_CATALOG) {
|
|
8
|
+
const probe = probeById(claim.probeId);
|
|
9
|
+
expect(probe, `no probe for claim ${claim.id} → ${claim.probeId}`).toBeDefined();
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
it("every claim has source + text + kind + severity", () => {
|
|
13
|
+
for (const c of CLAIM_CATALOG) {
|
|
14
|
+
expect(c.source.length).toBeGreaterThan(0);
|
|
15
|
+
expect(c.text.length).toBeGreaterThan(0);
|
|
16
|
+
expect(["numeric", "boolean", "string", "shape"]).toContain(c.kind);
|
|
17
|
+
expect(["info", "warn", "block"]).toContain(c.severity);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
it("numeric claims declare asserted value + op", () => {
|
|
21
|
+
for (const c of CLAIM_CATALOG) {
|
|
22
|
+
if (c.kind === "numeric") {
|
|
23
|
+
expect(c.asserted).toBeDefined();
|
|
24
|
+
expect(typeof c.asserted.value).toBe("number");
|
|
25
|
+
expect(["<", "<=", ">", ">=", "=", "~="]).toContain(c.asserted.op);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
it("boolean claims declare asserted value", () => {
|
|
30
|
+
for (const c of CLAIM_CATALOG) {
|
|
31
|
+
if (c.kind === "boolean") {
|
|
32
|
+
expect(c.asserted).toBeDefined();
|
|
33
|
+
expect([0, 1]).toContain(c.asserted.value);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
it("at least 10 claims in the catalog", () => {
|
|
38
|
+
expect(CLAIM_CATALOG.length).toBeGreaterThanOrEqual(10);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe("truth_gate — probes", () => {
|
|
42
|
+
it("each probe id is unique", () => {
|
|
43
|
+
const ids = new Set(ALL_PROBES.map((p) => p.id));
|
|
44
|
+
expect(ids.size).toBe(ALL_PROBES.length);
|
|
45
|
+
});
|
|
46
|
+
it("each probe has description + kind + run function", () => {
|
|
47
|
+
for (const p of ALL_PROBES) {
|
|
48
|
+
expect(p.description.length).toBeGreaterThan(0);
|
|
49
|
+
expect(typeof p.run).toBe("function");
|
|
50
|
+
expect(["numeric", "boolean", "string", "shape"]).toContain(p.kind);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe("truth_gate — verifyMatrix", () => {
|
|
55
|
+
function badMatrix() {
|
|
56
|
+
return {
|
|
57
|
+
spec: { name: "MNEME-TRUTH-GATE", version: "1.0" },
|
|
58
|
+
scannedAt: "2026-05-22T00:00:00.000Z",
|
|
59
|
+
cwd: "tmp",
|
|
60
|
+
totalClaims: 0,
|
|
61
|
+
entries: [],
|
|
62
|
+
summary: { pass: 0, drift: 0, refuted: 0, unmeasured: 0, truthScore: 0 },
|
|
63
|
+
headline: "test",
|
|
64
|
+
trafficLight: "yellow",
|
|
65
|
+
hmac: "deadbeef".repeat(8),
|
|
66
|
+
seq: 1,
|
|
67
|
+
bodyDigest: "feedface".repeat(8),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
beforeEach(() => __resetTruthChainForTest());
|
|
71
|
+
it("rejects a tampered matrix (bad bodyDigest)", () => {
|
|
72
|
+
expect(verifyMatrix(badMatrix()).ok).toBe(false);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=truth_gate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"truth_gate.test.js","sourceRoot":"","sources":["../../src/truth_gate/truth_gate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.27.0 — MARKETING TRUTH GATE.
|
|
3
|
+
*
|
|
4
|
+
* Audit (2026-05-22, user-supplied matrix): 8 marketing claims that
|
|
5
|
+
* don't match measured reality, e.g.
|
|
6
|
+
*
|
|
7
|
+
* Marketing: "74.7% fewer tokens" Measured: 80K tokens / call
|
|
8
|
+
* Marketing: "9 verification agents" Measured: returns NEEDS-DATA
|
|
9
|
+
* Marketing: "SUPERNOVA self-heal" Measured: kill 5x → 0 respawn
|
|
10
|
+
* Marketing: "Phoenix Resurrection" Measured: not activated by default
|
|
11
|
+
* Marketing: "Ollama detected ★★★★" Measured: bundled ★★★ picked
|
|
12
|
+
*
|
|
13
|
+
* The world has plenty of "release notes" pages. None of them PROVE the
|
|
14
|
+
* claim every time the binary is built. The TRUTH GATE does:
|
|
15
|
+
*
|
|
16
|
+
* 1. SCAN — parse claim-shaped sentences out of README / CHANGELOG /
|
|
17
|
+
* docs (and from MCP tool descriptions).
|
|
18
|
+
* 2. PROBE — each claim has a measurable probe (live function that
|
|
19
|
+
* returns a number / boolean / string).
|
|
20
|
+
* 3. RECONCILE — compare claim's asserted value to probed value; emit
|
|
21
|
+
* verdict (pass / drift / refuted).
|
|
22
|
+
* 4. ATTEST — HMAC-sign the reconciliation matrix so receivers can
|
|
23
|
+
* verify offline that the binary's claims have been measured.
|
|
24
|
+
*
|
|
25
|
+
* Composable with the PEAK GAUNTLET (v2.26.x): N1-N12 are spec
|
|
26
|
+
* conformance; TRUTH GATE is marketing-vs-reality. Together they form
|
|
27
|
+
* the world's first measurable-truth release pipeline.
|
|
28
|
+
*/
|
|
29
|
+
export type ClaimId = string;
|
|
30
|
+
export type ClaimKind = "numeric" | "boolean" | "string" | "shape";
|
|
31
|
+
export type ClaimVerdict = "pass" | "drift" | "refuted" | "unmeasured";
|
|
32
|
+
export interface Claim {
|
|
33
|
+
/** Stable id, e.g. "claim.tokens.capabilities". */
|
|
34
|
+
id: ClaimId;
|
|
35
|
+
/** Where the claim appears (file:line, README section title). */
|
|
36
|
+
source: string;
|
|
37
|
+
/** The marketing text verbatim (≤ 240 chars). */
|
|
38
|
+
text: string;
|
|
39
|
+
kind: ClaimKind;
|
|
40
|
+
/** For numeric claims: asserted value + comparison operator. */
|
|
41
|
+
asserted?: {
|
|
42
|
+
value: number;
|
|
43
|
+
op: "<" | "<=" | ">" | ">=" | "=" | "~=";
|
|
44
|
+
unit?: string;
|
|
45
|
+
tolerance?: number;
|
|
46
|
+
};
|
|
47
|
+
/** Probe id that measures the live value. */
|
|
48
|
+
probeId: string;
|
|
49
|
+
/** Severity if the claim drifts. */
|
|
50
|
+
severity: "info" | "warn" | "block";
|
|
51
|
+
}
|
|
52
|
+
export interface ProbeResult {
|
|
53
|
+
/** Measured value (kind-dependent). */
|
|
54
|
+
value: number | boolean | string | null;
|
|
55
|
+
/** Single-line summary of the measurement. */
|
|
56
|
+
evidence: string;
|
|
57
|
+
/** Wall-time of the probe. */
|
|
58
|
+
dtMs?: number;
|
|
59
|
+
/** Optional structured detail. */
|
|
60
|
+
detail?: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
export interface Probe {
|
|
63
|
+
id: string;
|
|
64
|
+
/** What kind of claim this probe can answer. */
|
|
65
|
+
kind: ClaimKind;
|
|
66
|
+
/** Short description. */
|
|
67
|
+
description: string;
|
|
68
|
+
/** Run the probe. NEVER throws — returns { value: null } on error. */
|
|
69
|
+
run: (ctx: ProbeContext) => Promise<ProbeResult>;
|
|
70
|
+
}
|
|
71
|
+
export interface ProbeContext {
|
|
72
|
+
cwd: string;
|
|
73
|
+
}
|
|
74
|
+
export interface ReconciliationEntry {
|
|
75
|
+
claim: Claim;
|
|
76
|
+
probe: ProbeResult;
|
|
77
|
+
verdict: ClaimVerdict;
|
|
78
|
+
reason: string;
|
|
79
|
+
}
|
|
80
|
+
export interface TruthMatrix {
|
|
81
|
+
spec: {
|
|
82
|
+
name: "MNEME-TRUTH-GATE";
|
|
83
|
+
version: string;
|
|
84
|
+
};
|
|
85
|
+
scannedAt: string;
|
|
86
|
+
cwd: string;
|
|
87
|
+
totalClaims: number;
|
|
88
|
+
entries: ReconciliationEntry[];
|
|
89
|
+
summary: {
|
|
90
|
+
pass: number;
|
|
91
|
+
drift: number;
|
|
92
|
+
refuted: number;
|
|
93
|
+
unmeasured: number;
|
|
94
|
+
truthScore: number;
|
|
95
|
+
};
|
|
96
|
+
headline: string;
|
|
97
|
+
trafficLight: "green" | "yellow" | "red";
|
|
98
|
+
hmac: string;
|
|
99
|
+
seq: number;
|
|
100
|
+
bodyDigest: string;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/truth_gate/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,CAAC;AAEvE,MAAM,WAAW,KAAK;IACpB,mDAAmD;IACnD,EAAE,EAAE,OAAO,CAAC;IACZ,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,gEAAgE;IAChE,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1G,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IACxC,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,gDAAgD;IAChD,IAAI,EAAE,SAAS,CAAC;IAChB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,GAAG,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE;QAAE,IAAI,EAAE,kBAAkB,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.27.0 — MARKETING TRUTH GATE.
|
|
3
|
+
*
|
|
4
|
+
* Audit (2026-05-22, user-supplied matrix): 8 marketing claims that
|
|
5
|
+
* don't match measured reality, e.g.
|
|
6
|
+
*
|
|
7
|
+
* Marketing: "74.7% fewer tokens" Measured: 80K tokens / call
|
|
8
|
+
* Marketing: "9 verification agents" Measured: returns NEEDS-DATA
|
|
9
|
+
* Marketing: "SUPERNOVA self-heal" Measured: kill 5x → 0 respawn
|
|
10
|
+
* Marketing: "Phoenix Resurrection" Measured: not activated by default
|
|
11
|
+
* Marketing: "Ollama detected ★★★★" Measured: bundled ★★★ picked
|
|
12
|
+
*
|
|
13
|
+
* The world has plenty of "release notes" pages. None of them PROVE the
|
|
14
|
+
* claim every time the binary is built. The TRUTH GATE does:
|
|
15
|
+
*
|
|
16
|
+
* 1. SCAN — parse claim-shaped sentences out of README / CHANGELOG /
|
|
17
|
+
* docs (and from MCP tool descriptions).
|
|
18
|
+
* 2. PROBE — each claim has a measurable probe (live function that
|
|
19
|
+
* returns a number / boolean / string).
|
|
20
|
+
* 3. RECONCILE — compare claim's asserted value to probed value; emit
|
|
21
|
+
* verdict (pass / drift / refuted).
|
|
22
|
+
* 4. ATTEST — HMAC-sign the reconciliation matrix so receivers can
|
|
23
|
+
* verify offline that the binary's claims have been measured.
|
|
24
|
+
*
|
|
25
|
+
* Composable with the PEAK GAUNTLET (v2.26.x): N1-N12 are spec
|
|
26
|
+
* conformance; TRUTH GATE is marketing-vs-reality. Together they form
|
|
27
|
+
* the world's first measurable-truth release pipeline.
|
|
28
|
+
*/
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/truth_gate/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG"}
|