@mneme-ai/core 2.17.1 → 2.19.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/agent_manifest.d.ts +1 -1
- package/dist/agent_manifest.d.ts.map +1 -1
- package/dist/agent_manifest.js +24 -1
- package/dist/agent_manifest.js.map +1 -1
- package/dist/arena/arena.test.d.ts +2 -0
- package/dist/arena/arena.test.d.ts.map +1 -0
- package/dist/arena/arena.test.js +107 -0
- package/dist/arena/arena.test.js.map +1 -0
- package/dist/arena/index.d.ts +114 -0
- package/dist/arena/index.d.ts.map +1 -0
- package/dist/arena/index.js +158 -0
- package/dist/arena/index.js.map +1 -0
- package/dist/confessional/confessional.test.d.ts +2 -0
- package/dist/confessional/confessional.test.d.ts.map +1 -0
- package/dist/confessional/confessional.test.js +136 -0
- package/dist/confessional/confessional.test.js.map +1 -0
- package/dist/confessional/index.d.ts +72 -0
- package/dist/confessional/index.d.ts.map +1 -0
- package/dist/confessional/index.js +137 -0
- package/dist/confessional/index.js.map +1 -0
- package/dist/cosmic/aurelian_v218.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v218.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v218.test.js +68 -0
- package/dist/cosmic/aurelian_v218.test.js.map +1 -0
- package/dist/cosmic/aurelian_v219.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v219.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v219.test.js +80 -0
- package/dist/cosmic/aurelian_v219.test.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/insurance_market/index.d.ts +77 -0
- package/dist/insurance_market/index.d.ts.map +1 -0
- package/dist/insurance_market/index.js +131 -0
- package/dist/insurance_market/index.js.map +1 -0
- package/dist/insurance_market/insurance_market.test.d.ts +2 -0
- package/dist/insurance_market/insurance_market.test.d.ts.map +1 -0
- package/dist/insurance_market/insurance_market.test.js +78 -0
- package/dist/insurance_market/insurance_market.test.js.map +1 -0
- package/dist/nexus_proactive/index.d.ts +134 -0
- package/dist/nexus_proactive/index.d.ts.map +1 -0
- package/dist/nexus_proactive/index.js +277 -0
- package/dist/nexus_proactive/index.js.map +1 -0
- package/dist/nexus_proactive/nexus_proactive.test.d.ts +2 -0
- package/dist/nexus_proactive/nexus_proactive.test.d.ts.map +1 -0
- package/dist/nexus_proactive/nexus_proactive.test.js +135 -0
- package/dist/nexus_proactive/nexus_proactive.test.js.map +1 -0
- package/dist/oracle_liability/index.d.ts +122 -0
- package/dist/oracle_liability/index.d.ts.map +1 -0
- package/dist/oracle_liability/index.js +203 -0
- package/dist/oracle_liability/index.js.map +1 -0
- package/dist/oracle_liability/oracle_liability.test.d.ts +2 -0
- package/dist/oracle_liability/oracle_liability.test.d.ts.map +1 -0
- package/dist/oracle_liability/oracle_liability.test.js +186 -0
- package/dist/oracle_liability/oracle_liability.test.js.map +1 -0
- package/dist/trinity_vote/index.d.ts +86 -0
- package/dist/trinity_vote/index.d.ts.map +1 -0
- package/dist/trinity_vote/index.js +173 -0
- package/dist/trinity_vote/index.js.map +1 -0
- package/dist/trinity_vote/trinity_vote.test.d.ts +2 -0
- package/dist/trinity_vote/trinity_vote.test.d.ts.map +1 -0
- package/dist/trinity_vote/trinity_vote.test.js +137 -0
- package/dist/trinity_vote/trinity_vote.test.js.map +1 -0
- package/dist/vendor_boomerang/index.d.ts +106 -0
- package/dist/vendor_boomerang/index.d.ts.map +1 -0
- package/dist/vendor_boomerang/index.js +167 -0
- package/dist/vendor_boomerang/index.js.map +1 -0
- package/dist/vendor_boomerang/vendor_boomerang.test.d.ts +2 -0
- package/dist/vendor_boomerang/vendor_boomerang.test.d.ts.map +1 -0
- package/dist/vendor_boomerang/vendor_boomerang.test.js +102 -0
- package/dist/vendor_boomerang/vendor_boomerang.test.js.map +1 -0
- package/dist/vendor_ghost/index.d.ts +93 -0
- package/dist/vendor_ghost/index.d.ts.map +1 -0
- package/dist/vendor_ghost/index.js +206 -0
- package/dist/vendor_ghost/index.js.map +1 -0
- package/dist/vendor_ghost/vendor_ghost.test.d.ts +2 -0
- package/dist/vendor_ghost/vendor_ghost.test.d.ts.map +1 -0
- package/dist/vendor_ghost/vendor_ghost.test.js +93 -0
- package/dist/vendor_ghost/vendor_ghost.test.js.map +1 -0
- package/dist/verified_badge/index.d.ts +78 -0
- package/dist/verified_badge/index.d.ts.map +1 -0
- package/dist/verified_badge/index.js +131 -0
- package/dist/verified_badge/index.js.map +1 -0
- package/dist/verified_badge/verified_badge.test.d.ts +2 -0
- package/dist/verified_badge/verified_badge.test.d.ts.map +1 -0
- package/dist/verified_badge/verified_badge.test.js +88 -0
- package/dist/verified_badge/verified_badge.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.18.0 — MNEME VERIFIED BADGE (the "Energy Star" of AI)
|
|
3
|
+
*
|
|
4
|
+
* "Vendor with measured falseRateLB < 0.05 (and minimum sample size)
|
|
5
|
+
* earns the right to display the 🛡 Mneme Verified Trustworthy badge.
|
|
6
|
+
* Badges are HMAC-signed time-limited certificates. Vendors PAY annual
|
|
7
|
+
* license to display. Renewal requires re-passing the gate."
|
|
8
|
+
*
|
|
9
|
+
* Tier system:
|
|
10
|
+
* PLATINUM — falseRateLB < 0.02, totalVerdicts >= 5000
|
|
11
|
+
* GOLD — falseRateLB < 0.05, totalVerdicts >= 1000
|
|
12
|
+
* SILVER — falseRateLB < 0.10, totalVerdicts >= 200
|
|
13
|
+
* BRONZE — falseRateLB < 0.20, totalVerdicts >= 50
|
|
14
|
+
* FAIL — none of the above; cannot display the badge
|
|
15
|
+
*
|
|
16
|
+
* Each badge:
|
|
17
|
+
* - Validity period: 90 days (re-test required)
|
|
18
|
+
* - Tier-locked (vendor can't claim PLATINUM if measured GOLD)
|
|
19
|
+
* - HMAC-signed; verifier can confirm any badge in the wild
|
|
20
|
+
* - Embed-safe SVG generator for marketing pages
|
|
21
|
+
*
|
|
22
|
+
* Composes onto v2.14 BOUNTY (falseRateLB) + v2.16 OBELISK (federated
|
|
23
|
+
* trust graph) + v2.18 ARENA (leaderboard). Pure issuance + verification;
|
|
24
|
+
* no liability — that's MNEME ORACLE.
|
|
25
|
+
*/
|
|
26
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
27
|
+
const PROTOCOL_VERSION = 1;
|
|
28
|
+
const TIER_RULES = [
|
|
29
|
+
{ tier: "platinum", maxFR: 0.02, minVerdicts: 5000 },
|
|
30
|
+
{ tier: "gold", maxFR: 0.05, minVerdicts: 1000 },
|
|
31
|
+
{ tier: "silver", maxFR: 0.10, minVerdicts: 200 },
|
|
32
|
+
{ tier: "bronze", maxFR: 0.20, minVerdicts: 50 },
|
|
33
|
+
];
|
|
34
|
+
function canon(v) {
|
|
35
|
+
if (v === null || typeof v !== "object")
|
|
36
|
+
return JSON.stringify(v);
|
|
37
|
+
if (Array.isArray(v))
|
|
38
|
+
return "[" + v.map(canon).join(",") + "]";
|
|
39
|
+
const keys = Object.keys(v).sort();
|
|
40
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
|
|
41
|
+
}
|
|
42
|
+
function defaultSecret() {
|
|
43
|
+
return process.env["MNEME_BADGE_SECRET"] || `mneme-verified-badge-v${PROTOCOL_VERSION}`;
|
|
44
|
+
}
|
|
45
|
+
export function determineTier(falseRateLB, totalVerdicts) {
|
|
46
|
+
for (const rule of TIER_RULES) {
|
|
47
|
+
if (falseRateLB < rule.maxFR && totalVerdicts >= rule.minVerdicts) {
|
|
48
|
+
return rule.tier;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return "fail";
|
|
52
|
+
}
|
|
53
|
+
function rng32(seed) {
|
|
54
|
+
// Deterministic certId derived from canonical body — easier to verify out
|
|
55
|
+
// of band; not a secret, just a pretty handle.
|
|
56
|
+
return createHmac("sha256", "mneme-badge-certid").update(seed).digest("hex").slice(0, 12);
|
|
57
|
+
}
|
|
58
|
+
export function issueBadge(input) {
|
|
59
|
+
const tier = determineTier(input.falseRateLB, input.totalVerdicts);
|
|
60
|
+
const issuedAt = input.issuedAt ?? new Date().toISOString();
|
|
61
|
+
const validityDays = input.validityDays ?? 90;
|
|
62
|
+
const validUntil = new Date(Date.parse(issuedAt) + validityDays * 24 * 60 * 60 * 1000).toISOString();
|
|
63
|
+
const certIdSeed = `${input.vendor}|${tier}|${issuedAt}|${input.falseRateLB}`;
|
|
64
|
+
const body = {
|
|
65
|
+
v: PROTOCOL_VERSION,
|
|
66
|
+
vendor: input.vendor,
|
|
67
|
+
displayName: input.displayName,
|
|
68
|
+
tier,
|
|
69
|
+
measured: {
|
|
70
|
+
falseRateLB: Math.round(input.falseRateLB * 100000) / 100000,
|
|
71
|
+
totalVerdicts: input.totalVerdicts,
|
|
72
|
+
},
|
|
73
|
+
issuedAt,
|
|
74
|
+
validUntil,
|
|
75
|
+
certId: rng32(certIdSeed),
|
|
76
|
+
};
|
|
77
|
+
const sig = createHmac("sha256", input.secret ?? defaultSecret()).update(canon(body)).digest("hex");
|
|
78
|
+
return { ...body, sig };
|
|
79
|
+
}
|
|
80
|
+
export function verifyBadge(badge, secret) {
|
|
81
|
+
const { sig: claimed, ...body } = badge;
|
|
82
|
+
const expected = createHmac("sha256", secret ?? defaultSecret()).update(canon(body)).digest("hex");
|
|
83
|
+
let okSig = false;
|
|
84
|
+
try {
|
|
85
|
+
okSig = timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(claimed, "hex"));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
okSig = false;
|
|
89
|
+
}
|
|
90
|
+
if (!okSig)
|
|
91
|
+
return { ok: false, expired: false, reason: "badge sig mismatch — forged or wrong key" };
|
|
92
|
+
const expired = Date.now() > Date.parse(badge.validUntil);
|
|
93
|
+
if (expired)
|
|
94
|
+
return { ok: false, expired: true, reason: "badge expired", badge };
|
|
95
|
+
if (badge.tier === "fail")
|
|
96
|
+
return { ok: false, expired: false, reason: "tier=fail; vendor cannot display badge" };
|
|
97
|
+
return { ok: true, expired: false, badge };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Generate an embed-safe SVG for the badge. Width/height fixed at 240×60
|
|
101
|
+
* for marketing footers. Tier color: platinum silver-blue, gold yellow-orange,
|
|
102
|
+
* silver gray, bronze copper. Includes the certId so verifiers can lookup.
|
|
103
|
+
*/
|
|
104
|
+
export function badgeSvg(badge) {
|
|
105
|
+
const colors = {
|
|
106
|
+
platinum: { bg: "#1e293b", ring: "#94a3b8", text: "#e2e8f0" },
|
|
107
|
+
gold: { bg: "#3a2e0a", ring: "#fbbf24", text: "#fef3c7" },
|
|
108
|
+
silver: { bg: "#27272a", ring: "#a1a1aa", text: "#f4f4f5" },
|
|
109
|
+
bronze: { bg: "#3a1f0e", ring: "#d97706", text: "#fed7aa" },
|
|
110
|
+
fail: { bg: "#1a1015", ring: "#6b7280", text: "#9ca3af" },
|
|
111
|
+
};
|
|
112
|
+
const c = colors[badge.tier];
|
|
113
|
+
const escape = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
114
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="240" height="60" viewBox="0 0 240 60" role="img" aria-label="Mneme Verified Trustworthy ${badge.tier} for ${badge.vendor}">
|
|
115
|
+
<rect width="240" height="60" rx="8" fill="${c.bg}" stroke="${c.ring}" stroke-width="2"/>
|
|
116
|
+
<text x="14" y="22" font-family="system-ui, sans-serif" font-size="11" fill="${c.ring}" letter-spacing="1.5">🛡 MNEME VERIFIED</text>
|
|
117
|
+
<text x="14" y="42" font-family="system-ui, sans-serif" font-size="14" font-weight="700" fill="${c.text}">${escape(badge.displayName)}</text>
|
|
118
|
+
<text x="226" y="22" text-anchor="end" font-family="system-ui, sans-serif" font-size="11" fill="${c.ring}" font-weight="700" letter-spacing="2">${badge.tier.toUpperCase()}</text>
|
|
119
|
+
<text x="226" y="42" text-anchor="end" font-family="ui-monospace, monospace" font-size="9" fill="${c.text}" opacity="0.65">cert:${badge.certId}</text>
|
|
120
|
+
</svg>`;
|
|
121
|
+
}
|
|
122
|
+
/** One-line pulse summary. */
|
|
123
|
+
export function formatBadgeLine(b) {
|
|
124
|
+
return `BADGE 🛡 · ${b.displayName} · ${b.tier} · expires ${b.validUntil.slice(0, 10)}`;
|
|
125
|
+
}
|
|
126
|
+
/** Tier-pricing model (informational; the actual billing is out of band). */
|
|
127
|
+
export function tierAnnualLicense(tier) {
|
|
128
|
+
// USD/year. Defensible numbers based on certification industry comparables.
|
|
129
|
+
return { platinum: 50000, gold: 12000, silver: 3000, bronze: 500, fail: 0 }[tier];
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/verified_badge/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verified_badge.test.d.ts","sourceRoot":"","sources":["../../src/verified_badge/verified_badge.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { issueBadge, verifyBadge, badgeSvg, determineTier, tierAnnualLicense, formatBadgeLine } from "./index.js";
|
|
3
|
+
describe("v2.18 · MNEME VERIFIED BADGE", () => {
|
|
4
|
+
describe("determineTier", () => {
|
|
5
|
+
it("PLATINUM: <2% falseRate + 5000+ verdicts", () => {
|
|
6
|
+
expect(determineTier(0.01, 6000)).toBe("platinum");
|
|
7
|
+
});
|
|
8
|
+
it("GOLD: <5% + 1000+", () => {
|
|
9
|
+
expect(determineTier(0.04, 1500)).toBe("gold");
|
|
10
|
+
});
|
|
11
|
+
it("SILVER: <10% + 200+", () => {
|
|
12
|
+
expect(determineTier(0.08, 250)).toBe("silver");
|
|
13
|
+
});
|
|
14
|
+
it("BRONZE: <20% + 50+", () => {
|
|
15
|
+
expect(determineTier(0.15, 60)).toBe("bronze");
|
|
16
|
+
});
|
|
17
|
+
it("FAIL: too few samples even with low rate", () => {
|
|
18
|
+
expect(determineTier(0.01, 10)).toBe("fail");
|
|
19
|
+
});
|
|
20
|
+
it("FAIL: too high rate even with many samples", () => {
|
|
21
|
+
expect(determineTier(0.30, 10000)).toBe("fail");
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe("issue + verify", () => {
|
|
25
|
+
it("issues a GOLD badge", () => {
|
|
26
|
+
const b = issueBadge({ vendor: "claude", displayName: "Claude", falseRateLB: 0.04, totalVerdicts: 1500 });
|
|
27
|
+
expect(b.tier).toBe("gold");
|
|
28
|
+
expect(b.sig).toMatch(/^[0-9a-f]{64}$/);
|
|
29
|
+
expect(b.certId).toMatch(/^[0-9a-f]{12}$/);
|
|
30
|
+
});
|
|
31
|
+
it("verifies a clean badge", () => {
|
|
32
|
+
const b = issueBadge({ vendor: "x", displayName: "X", falseRateLB: 0.02, totalVerdicts: 100 });
|
|
33
|
+
const r = verifyBadge(b);
|
|
34
|
+
// SILVER (under 10%, >= 200 needed) — actually 100 < 200 → BRONZE? No, 100 < 50? no >= 50 → BRONZE
|
|
35
|
+
// 0.02 < 0.20 ✓ + 100 >= 50 ✓ → BRONZE
|
|
36
|
+
expect(b.tier).toBe("bronze");
|
|
37
|
+
expect(r.ok).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
it("rejects tampered badge", () => {
|
|
40
|
+
const b = issueBadge({ vendor: "claude", displayName: "Claude", falseRateLB: 0.04, totalVerdicts: 1500 });
|
|
41
|
+
const tampered = { ...b, displayName: "EVIL TWIN" };
|
|
42
|
+
const r = verifyBadge(tampered);
|
|
43
|
+
expect(r.ok).toBe(false);
|
|
44
|
+
expect(r.reason).toContain("sig mismatch");
|
|
45
|
+
});
|
|
46
|
+
it("rejects expired badge", () => {
|
|
47
|
+
const issuedAt = new Date(Date.now() - 91 * 24 * 60 * 60 * 1000).toISOString();
|
|
48
|
+
const b = issueBadge({ vendor: "x", displayName: "X", falseRateLB: 0.02, totalVerdicts: 1500, issuedAt });
|
|
49
|
+
const r = verifyBadge(b);
|
|
50
|
+
expect(r.expired).toBe(true);
|
|
51
|
+
expect(r.ok).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
it("rejects FAIL tier badges (cannot display)", () => {
|
|
54
|
+
const b = issueBadge({ vendor: "x", displayName: "X", falseRateLB: 0.5, totalVerdicts: 10 });
|
|
55
|
+
expect(b.tier).toBe("fail");
|
|
56
|
+
const r = verifyBadge(b);
|
|
57
|
+
expect(r.ok).toBe(false);
|
|
58
|
+
expect(r.reason).toContain("tier=fail");
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe("badgeSvg", () => {
|
|
62
|
+
it("returns valid SVG with vendor name + tier + certId", () => {
|
|
63
|
+
const b = issueBadge({ vendor: "claude", displayName: "Anthropic Claude", falseRateLB: 0.01, totalVerdicts: 6000 });
|
|
64
|
+
const svg = badgeSvg(b);
|
|
65
|
+
expect(svg).toContain("<svg");
|
|
66
|
+
expect(svg).toContain("Anthropic Claude");
|
|
67
|
+
expect(svg).toContain("PLATINUM");
|
|
68
|
+
expect(svg).toContain(b.certId);
|
|
69
|
+
});
|
|
70
|
+
it("escapes vendor name to prevent SVG injection", () => {
|
|
71
|
+
const b = issueBadge({ vendor: "x", displayName: "<script>alert(1)</script>", falseRateLB: 0.01, totalVerdicts: 6000 });
|
|
72
|
+
const svg = badgeSvg(b);
|
|
73
|
+
expect(svg).not.toContain("<script>");
|
|
74
|
+
expect(svg).toContain("<script>");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
it("tierAnnualLicense returns sensible USD values", () => {
|
|
78
|
+
expect(tierAnnualLicense("platinum")).toBeGreaterThan(tierAnnualLicense("gold"));
|
|
79
|
+
expect(tierAnnualLicense("gold")).toBeGreaterThan(tierAnnualLicense("silver"));
|
|
80
|
+
expect(tierAnnualLicense("fail")).toBe(0);
|
|
81
|
+
});
|
|
82
|
+
it("formatBadgeLine summarises", () => {
|
|
83
|
+
const b = issueBadge({ vendor: "claude", displayName: "Claude", falseRateLB: 0.04, totalVerdicts: 1500 });
|
|
84
|
+
expect(formatBadgeLine(b)).toContain("BADGE");
|
|
85
|
+
expect(formatBadgeLine(b)).toContain("gold");
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=verified_badge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verified_badge.test.js","sourceRoot":"","sources":["../../src/verified_badge/verified_badge.test.ts"],"names":[],"mappings":"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"}
|