@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.
Files changed (89) hide show
  1. package/dist/agent_manifest.d.ts +1 -1
  2. package/dist/agent_manifest.d.ts.map +1 -1
  3. package/dist/agent_manifest.js +24 -1
  4. package/dist/agent_manifest.js.map +1 -1
  5. package/dist/arena/arena.test.d.ts +2 -0
  6. package/dist/arena/arena.test.d.ts.map +1 -0
  7. package/dist/arena/arena.test.js +107 -0
  8. package/dist/arena/arena.test.js.map +1 -0
  9. package/dist/arena/index.d.ts +114 -0
  10. package/dist/arena/index.d.ts.map +1 -0
  11. package/dist/arena/index.js +158 -0
  12. package/dist/arena/index.js.map +1 -0
  13. package/dist/confessional/confessional.test.d.ts +2 -0
  14. package/dist/confessional/confessional.test.d.ts.map +1 -0
  15. package/dist/confessional/confessional.test.js +136 -0
  16. package/dist/confessional/confessional.test.js.map +1 -0
  17. package/dist/confessional/index.d.ts +72 -0
  18. package/dist/confessional/index.d.ts.map +1 -0
  19. package/dist/confessional/index.js +137 -0
  20. package/dist/confessional/index.js.map +1 -0
  21. package/dist/cosmic/aurelian_v218.test.d.ts +2 -0
  22. package/dist/cosmic/aurelian_v218.test.d.ts.map +1 -0
  23. package/dist/cosmic/aurelian_v218.test.js +68 -0
  24. package/dist/cosmic/aurelian_v218.test.js.map +1 -0
  25. package/dist/cosmic/aurelian_v219.test.d.ts +2 -0
  26. package/dist/cosmic/aurelian_v219.test.d.ts.map +1 -0
  27. package/dist/cosmic/aurelian_v219.test.js +80 -0
  28. package/dist/cosmic/aurelian_v219.test.js.map +1 -0
  29. package/dist/index.d.ts +9 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +20 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/insurance_market/index.d.ts +77 -0
  34. package/dist/insurance_market/index.d.ts.map +1 -0
  35. package/dist/insurance_market/index.js +131 -0
  36. package/dist/insurance_market/index.js.map +1 -0
  37. package/dist/insurance_market/insurance_market.test.d.ts +2 -0
  38. package/dist/insurance_market/insurance_market.test.d.ts.map +1 -0
  39. package/dist/insurance_market/insurance_market.test.js +78 -0
  40. package/dist/insurance_market/insurance_market.test.js.map +1 -0
  41. package/dist/nexus_proactive/index.d.ts +134 -0
  42. package/dist/nexus_proactive/index.d.ts.map +1 -0
  43. package/dist/nexus_proactive/index.js +277 -0
  44. package/dist/nexus_proactive/index.js.map +1 -0
  45. package/dist/nexus_proactive/nexus_proactive.test.d.ts +2 -0
  46. package/dist/nexus_proactive/nexus_proactive.test.d.ts.map +1 -0
  47. package/dist/nexus_proactive/nexus_proactive.test.js +135 -0
  48. package/dist/nexus_proactive/nexus_proactive.test.js.map +1 -0
  49. package/dist/oracle_liability/index.d.ts +122 -0
  50. package/dist/oracle_liability/index.d.ts.map +1 -0
  51. package/dist/oracle_liability/index.js +203 -0
  52. package/dist/oracle_liability/index.js.map +1 -0
  53. package/dist/oracle_liability/oracle_liability.test.d.ts +2 -0
  54. package/dist/oracle_liability/oracle_liability.test.d.ts.map +1 -0
  55. package/dist/oracle_liability/oracle_liability.test.js +186 -0
  56. package/dist/oracle_liability/oracle_liability.test.js.map +1 -0
  57. package/dist/trinity_vote/index.d.ts +86 -0
  58. package/dist/trinity_vote/index.d.ts.map +1 -0
  59. package/dist/trinity_vote/index.js +173 -0
  60. package/dist/trinity_vote/index.js.map +1 -0
  61. package/dist/trinity_vote/trinity_vote.test.d.ts +2 -0
  62. package/dist/trinity_vote/trinity_vote.test.d.ts.map +1 -0
  63. package/dist/trinity_vote/trinity_vote.test.js +137 -0
  64. package/dist/trinity_vote/trinity_vote.test.js.map +1 -0
  65. package/dist/vendor_boomerang/index.d.ts +106 -0
  66. package/dist/vendor_boomerang/index.d.ts.map +1 -0
  67. package/dist/vendor_boomerang/index.js +167 -0
  68. package/dist/vendor_boomerang/index.js.map +1 -0
  69. package/dist/vendor_boomerang/vendor_boomerang.test.d.ts +2 -0
  70. package/dist/vendor_boomerang/vendor_boomerang.test.d.ts.map +1 -0
  71. package/dist/vendor_boomerang/vendor_boomerang.test.js +102 -0
  72. package/dist/vendor_boomerang/vendor_boomerang.test.js.map +1 -0
  73. package/dist/vendor_ghost/index.d.ts +93 -0
  74. package/dist/vendor_ghost/index.d.ts.map +1 -0
  75. package/dist/vendor_ghost/index.js +206 -0
  76. package/dist/vendor_ghost/index.js.map +1 -0
  77. package/dist/vendor_ghost/vendor_ghost.test.d.ts +2 -0
  78. package/dist/vendor_ghost/vendor_ghost.test.d.ts.map +1 -0
  79. package/dist/vendor_ghost/vendor_ghost.test.js +93 -0
  80. package/dist/vendor_ghost/vendor_ghost.test.js.map +1 -0
  81. package/dist/verified_badge/index.d.ts +78 -0
  82. package/dist/verified_badge/index.d.ts.map +1 -0
  83. package/dist/verified_badge/index.js +131 -0
  84. package/dist/verified_badge/index.js.map +1 -0
  85. package/dist/verified_badge/verified_badge.test.d.ts +2 -0
  86. package/dist/verified_badge/verified_badge.test.d.ts.map +1 -0
  87. package/dist/verified_badge/verified_badge.test.js +88 -0
  88. package/dist/verified_badge/verified_badge.test.js.map +1 -0
  89. package/package.json +1 -1
@@ -0,0 +1,102 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { VendorBoomerang, formatBoomerangLine } from "./index.js";
3
+ describe("v2.19 · MNEME VENDOR BOOMERANG — cross-vendor context injection", () => {
4
+ it("records activity with chain signature", () => {
5
+ const b = new VendorBoomerang();
6
+ const r = b.record({
7
+ vendor: "claude",
8
+ kind: "symbol_create",
9
+ filePath: "src/foo.ts",
10
+ symbol: "calculateTotal",
11
+ location: "L42",
12
+ note: "added calculateTotal helper",
13
+ });
14
+ expect(r.sig).toMatch(/^[0-9a-f]{64}$/);
15
+ expect(r.recordId).toMatch(/^act-[0-9a-f]{14}$/);
16
+ expect(r.prevSig).toMatch(/^genesis0+$/);
17
+ expect(b.verifyRecord(r)).toBe(true);
18
+ });
19
+ it("chain integrity holds across multiple records", () => {
20
+ const b = new VendorBoomerang();
21
+ b.record({ vendor: "claude", kind: "file_edit", filePath: "src/a.ts", note: "init" });
22
+ b.record({ vendor: "chatgpt", kind: "file_edit", filePath: "src/a.ts", note: "tweak" });
23
+ b.record({ vendor: "grok", kind: "file_edit", filePath: "src/a.ts", note: "refactor" });
24
+ const chk = b.verifyChain();
25
+ expect(chk.ok).toBe(true);
26
+ });
27
+ it("verifyChain detects tampering", () => {
28
+ const b = new VendorBoomerang();
29
+ b.record({ vendor: "claude", kind: "file_edit", filePath: "src/a.ts", note: "init" });
30
+ b.record({ vendor: "chatgpt", kind: "file_edit", filePath: "src/a.ts", note: "tweak" });
31
+ const ledger = b.exportLedger();
32
+ // Mutate a record in place — chain should break.
33
+ ledger[0].note = "EVIL TWIN";
34
+ // Re-inject via a fresh instance by replaying:
35
+ const corrupt = new VendorBoomerang();
36
+ // @ts-expect-error testing privates
37
+ corrupt.ledger = ledger;
38
+ const chk = corrupt.verifyChain();
39
+ expect(chk.ok).toBe(false);
40
+ });
41
+ it("boomerang context excludes incoming vendor's own records", () => {
42
+ const b = new VendorBoomerang();
43
+ b.record({ vendor: "claude", kind: "symbol_create", filePath: "src/foo.ts", symbol: "calculateTotal", note: "added" });
44
+ b.record({ vendor: "grok", kind: "file_edit", filePath: "src/foo.ts", note: "grok was here" });
45
+ const ctx = b.build({ incomingVendor: "grok", filePath: "src/foo.ts" });
46
+ // grok's record should be filtered out — only claude's appears.
47
+ expect(ctx.relevantRecords.length).toBe(1);
48
+ expect(ctx.relevantRecords[0].vendor).toBe("claude");
49
+ });
50
+ it("boomerang context respects lookback window", () => {
51
+ const b = new VendorBoomerang();
52
+ const t0 = 1_000_000_000_000;
53
+ b.record({ vendor: "claude", kind: "file_edit", filePath: "src/a.ts", note: "old", ts: new Date(t0).toISOString() });
54
+ b.record({ vendor: "chatgpt", kind: "file_edit", filePath: "src/a.ts", note: "recent", ts: new Date(t0 + 60_000).toISOString() });
55
+ // Query 90s later with 30s lookback — only the recent one survives.
56
+ const ctx = b.build({ incomingVendor: "grok", filePath: "src/a.ts", lookbackSeconds: 30, nowMs: t0 + 90_000 });
57
+ expect(ctx.relevantRecords.length).toBe(1);
58
+ expect(ctx.relevantRecords[0].note).toBe("recent");
59
+ });
60
+ it("boomerang context handles empty case gracefully", () => {
61
+ const b = new VendorBoomerang();
62
+ const ctx = b.build({ incomingVendor: "grok", filePath: "src/unknown.ts" });
63
+ expect(ctx.relevantRecords.length).toBe(0);
64
+ expect(ctx.injectedContextBlock).toContain("no recent cross-vendor activity");
65
+ });
66
+ it("works for every supported vendor as recorder + reader", () => {
67
+ const vendors = ["claude", "chatgpt", "gemini", "cursor", "copilot", "codex", "llama", "mistral", "qwen", "deepseek", "grok", "perplexity", "other"];
68
+ const b = new VendorBoomerang();
69
+ for (const v of vendors) {
70
+ b.record({ vendor: v, kind: "file_edit", filePath: `src/${v}.ts`, note: `${v} was here` });
71
+ }
72
+ expect(b.verifyChain().ok).toBe(true);
73
+ expect(b.stats().totalRecords).toBe(vendors.length);
74
+ });
75
+ it("injectedContextBlock contains ALL relevant vendor names + symbols", () => {
76
+ const b = new VendorBoomerang();
77
+ b.record({ vendor: "claude", kind: "symbol_create", filePath: "src/foo.ts", symbol: "calculateTotal", location: "L42", note: "added helper" });
78
+ b.record({ vendor: "chatgpt", kind: "symbol_move", filePath: "src/foo.ts", symbol: "calculateTotal", location: "L80", note: "moved" });
79
+ const ctx = b.build({ incomingVendor: "grok", filePath: "src/foo.ts" });
80
+ expect(ctx.injectedContextBlock).toContain("claude");
81
+ expect(ctx.injectedContextBlock).toContain("chatgpt");
82
+ expect(ctx.injectedContextBlock).toContain("calculateTotal");
83
+ });
84
+ it("stats() reports per-vendor counts + unique files", () => {
85
+ const b = new VendorBoomerang();
86
+ b.record({ vendor: "claude", kind: "file_edit", filePath: "src/a.ts", note: "x" });
87
+ b.record({ vendor: "claude", kind: "file_edit", filePath: "src/b.ts", note: "x" });
88
+ b.record({ vendor: "grok", kind: "file_edit", filePath: "src/a.ts", note: "x" });
89
+ const s = b.stats();
90
+ expect(s.totalRecords).toBe(3);
91
+ expect(s.perVendor["claude"]).toBe(2);
92
+ expect(s.perVendor["grok"]).toBe(1);
93
+ expect(s.uniqueFiles).toBe(2);
94
+ });
95
+ it("formatBoomerangLine summarises", () => {
96
+ const b = new VendorBoomerang();
97
+ b.record({ vendor: "claude", kind: "file_edit", filePath: "src/a.ts", note: "x" });
98
+ const ctx = b.build({ incomingVendor: "grok", filePath: "src/a.ts" });
99
+ expect(formatBoomerangLine(ctx)).toContain("BOOMERANG");
100
+ });
101
+ });
102
+ //# sourceMappingURL=vendor_boomerang.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor_boomerang.test.js","sourceRoot":"","sources":["../../src/vendor_boomerang/vendor_boomerang.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * v2.19.0 — MNEME VENDOR GHOST (the stylometric jailbreak of vendor lock-in)
3
+ *
4
+ * "Every paid AI is a moat made of style — verbosity, hedging cadence,
5
+ * structure preference, the way they phrase a 'maybe'. VENDOR GHOST
6
+ * samples that signature, builds a per-vendor stylometric profile, and
7
+ * locally synthesises 'what would Vendor X say' from the historical
8
+ * samples without ever calling the vendor again. Vendor lock-in is
9
+ * style lock-in. Mneme breaks style lock-in with cryptographically
10
+ * signed stylometric fingerprints anyone can verify."
11
+ *
12
+ * Vendor-agnostic: works with claude / chatgpt / gemini / cursor / copilot
13
+ * / codex / llama / mistral / qwen / deepseek / grok / perplexity / other.
14
+ *
15
+ * Honest scope:
16
+ * - GHOST does NOT generate brand-new content out of thin air. It uses
17
+ * nearest-neighbour retrieval over historical (prompt → response) pairs
18
+ * the user has recorded, plus the vendor's style fingerprint to shape
19
+ * the surface form.
20
+ * - GHOST is not a substitute for the live vendor on novel problems.
21
+ * It IS a substitute for "I want the Grok flavour on a question I've
22
+ * basically asked Grok before."
23
+ * - The fingerprint is signed; "this is what Grok feels like as of
24
+ * 2026-05-15" is a recomputable, falsifiable claim.
25
+ *
26
+ * Composes onto v2.14 REPLICA + v2.18 ARENA. Pure additive layer.
27
+ */
28
+ import type { Vendor } from "../arena/index.js";
29
+ declare const PROTOCOL_VERSION: 1;
30
+ export interface Sample {
31
+ vendor: Vendor;
32
+ prompt: string;
33
+ response: string;
34
+ /** Optional task class for segmentation. */
35
+ taskClass?: string;
36
+ /** Optional timestamp. */
37
+ ts?: string;
38
+ }
39
+ export interface StyleProfile {
40
+ v: typeof PROTOCOL_VERSION;
41
+ vendor: Vendor;
42
+ sampleCount: number;
43
+ /** Mean response length (chars). */
44
+ meanLength: number;
45
+ /** Std dev of response length. */
46
+ stdLength: number;
47
+ /** Hedge density per 100 words: "maybe", "I think", "perhaps", "might", "could". */
48
+ hedgeDensityPer100w: number;
49
+ /** Absolute density per 100 words: "always", "never", "definitely", "must". */
50
+ absoluteDensityPer100w: number;
51
+ /** Fraction of responses containing a fenced code block. */
52
+ codeBlockRate: number;
53
+ /** Fraction of responses using bullet/numbered lists. */
54
+ bulletRate: number;
55
+ /** Top tokens (lowercased, stop-words filtered) with relative frequency. */
56
+ topTokens: Array<{
57
+ token: string;
58
+ freq: number;
59
+ }>;
60
+ /** First-sample timestamp + last-sample timestamp for transparency. */
61
+ windowStart: string;
62
+ windowEnd: string;
63
+ sig: string;
64
+ }
65
+ export declare function distillProfile(samples: Sample[], secret?: string): StyleProfile;
66
+ export declare function verifyProfile(p: StyleProfile, secret?: string): boolean;
67
+ export interface GhostAnswer {
68
+ vendor: Vendor;
69
+ /** Did we find a nearest-neighbour answer? */
70
+ found: boolean;
71
+ /** Composite-shape score from the matched historical sample. */
72
+ matchedFromPrompt?: string;
73
+ /** Style-shaped response. */
74
+ response?: string;
75
+ /** Jaccard similarity in [0,1] between asked prompt and matched sample. */
76
+ similarity: number;
77
+ /** Caller's confidence band. */
78
+ confidence: "high" | "medium" | "low" | "none";
79
+ /** Why the GHOST returned what it did. */
80
+ reasons: string[];
81
+ /** Profile snapshot used. */
82
+ profileSig: string;
83
+ }
84
+ export declare function askGhost(input: {
85
+ profile: StyleProfile;
86
+ samples: Sample[];
87
+ prompt: string;
88
+ }): GhostAnswer;
89
+ /** Distance between two profiles — useful for "is Grok actually different from Claude?" */
90
+ export declare function profileDistance(a: StyleProfile, b: StyleProfile): number;
91
+ export declare function formatGhostLine(g: GhostAnswer): string;
92
+ export {};
93
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vendor_ghost/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,QAAA,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAEpC,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,sBAAsB,EAAE,MAAM,CAAC;IAC/B,4DAA4D;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,SAAS,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAkCD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CA0D/E;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAKvE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,KAAK,EAAE,OAAO,CAAC;IACf,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC/C,0CAA0C;IAC1C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAYD,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,WAAW,CA6Cd;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,MAAM,CAYxE;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAGtD"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * v2.19.0 — MNEME VENDOR GHOST (the stylometric jailbreak of vendor lock-in)
3
+ *
4
+ * "Every paid AI is a moat made of style — verbosity, hedging cadence,
5
+ * structure preference, the way they phrase a 'maybe'. VENDOR GHOST
6
+ * samples that signature, builds a per-vendor stylometric profile, and
7
+ * locally synthesises 'what would Vendor X say' from the historical
8
+ * samples without ever calling the vendor again. Vendor lock-in is
9
+ * style lock-in. Mneme breaks style lock-in with cryptographically
10
+ * signed stylometric fingerprints anyone can verify."
11
+ *
12
+ * Vendor-agnostic: works with claude / chatgpt / gemini / cursor / copilot
13
+ * / codex / llama / mistral / qwen / deepseek / grok / perplexity / other.
14
+ *
15
+ * Honest scope:
16
+ * - GHOST does NOT generate brand-new content out of thin air. It uses
17
+ * nearest-neighbour retrieval over historical (prompt → response) pairs
18
+ * the user has recorded, plus the vendor's style fingerprint to shape
19
+ * the surface form.
20
+ * - GHOST is not a substitute for the live vendor on novel problems.
21
+ * It IS a substitute for "I want the Grok flavour on a question I've
22
+ * basically asked Grok before."
23
+ * - The fingerprint is signed; "this is what Grok feels like as of
24
+ * 2026-05-15" is a recomputable, falsifiable claim.
25
+ *
26
+ * Composes onto v2.14 REPLICA + v2.18 ARENA. Pure additive layer.
27
+ */
28
+ import { createHmac, timingSafeEqual } from "node:crypto";
29
+ const PROTOCOL_VERSION = 1;
30
+ const HEDGES = ["maybe", "i think", "perhaps", "might", "could", "possibly", "i'd say", "tend to", "seems like"];
31
+ const ABSOLUTES = ["always", "never", "definitely", "must", "every", "all", "none", "absolutely"];
32
+ const STOPWORDS = new Set(["the", "a", "an", "and", "or", "but", "is", "it", "to", "of", "in", "on", "for", "with", "as", "at", "by", "this", "that", "be", "you", "i", "we", "they", "are", "was", "were", "have", "has", "had", "do", "does", "did", "not", "so", "if", "then", "than", "from", "out", "up", "your", "my", "our", "their", "its", "what", "when", "where", "how", "why"]);
33
+ function canon(v) {
34
+ if (v === null || typeof v !== "object")
35
+ return JSON.stringify(v);
36
+ if (Array.isArray(v))
37
+ return "[" + v.map(canon).join(",") + "]";
38
+ const keys = Object.keys(v).sort();
39
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
40
+ }
41
+ function defaultSecret() {
42
+ return process.env["MNEME_GHOST_SECRET"] || `mneme-vendor-ghost-v${PROTOCOL_VERSION}`;
43
+ }
44
+ function tokenize(s) {
45
+ return s.toLowerCase().match(/[a-z][a-z0-9_]+/g) ?? [];
46
+ }
47
+ function countPatterns(s, needles) {
48
+ const lower = s.toLowerCase();
49
+ let n = 0;
50
+ for (const needle of needles) {
51
+ let idx = 0;
52
+ while ((idx = lower.indexOf(needle, idx)) !== -1) {
53
+ n++;
54
+ idx += needle.length;
55
+ }
56
+ }
57
+ return n;
58
+ }
59
+ export function distillProfile(samples, secret) {
60
+ if (samples.length === 0) {
61
+ throw new Error("VENDOR GHOST: need at least 1 sample to distill a profile");
62
+ }
63
+ const vendor = samples[0].vendor;
64
+ for (const s of samples) {
65
+ if (s.vendor !== vendor) {
66
+ throw new Error(`VENDOR GHOST: all samples must be from the same vendor (got ${s.vendor}, expected ${vendor})`);
67
+ }
68
+ }
69
+ const lengths = samples.map((s) => s.response.length);
70
+ const meanLength = lengths.reduce((a, b) => a + b, 0) / lengths.length;
71
+ const varLength = lengths.reduce((a, l) => a + (l - meanLength) ** 2, 0) / lengths.length;
72
+ const stdLength = Math.sqrt(varLength);
73
+ let totalWords = 0, totalHedges = 0, totalAbsolutes = 0;
74
+ let codeBlockSamples = 0, bulletSamples = 0;
75
+ const tokenCounts = new Map();
76
+ for (const s of samples) {
77
+ const r = s.response;
78
+ const words = tokenize(r);
79
+ totalWords += words.length;
80
+ totalHedges += countPatterns(r, HEDGES);
81
+ totalAbsolutes += countPatterns(r, ABSOLUTES);
82
+ if (/```/.test(r))
83
+ codeBlockSamples++;
84
+ if (/^\s*(?:[-*•]|\d+\.)\s/m.test(r))
85
+ bulletSamples++;
86
+ for (const w of words) {
87
+ if (STOPWORDS.has(w))
88
+ continue;
89
+ if (w.length < 3)
90
+ continue;
91
+ tokenCounts.set(w, (tokenCounts.get(w) ?? 0) + 1);
92
+ }
93
+ }
94
+ const per100w = (n) => totalWords === 0 ? 0 : Math.round((n / totalWords) * 100 * 1000) / 1000;
95
+ const topTokens = Array.from(tokenCounts.entries())
96
+ .map(([token, n]) => ({ token, freq: Math.round((n / Math.max(1, totalWords)) * 10_000) / 10_000 }))
97
+ .sort((a, b) => b.freq - a.freq)
98
+ .slice(0, 40);
99
+ const tsList = samples.map((s) => s.ts).filter((x) => !!x).sort();
100
+ const windowStart = tsList[0] ?? new Date(0).toISOString();
101
+ const windowEnd = tsList[tsList.length - 1] ?? new Date().toISOString();
102
+ const body = {
103
+ v: PROTOCOL_VERSION,
104
+ vendor,
105
+ sampleCount: samples.length,
106
+ meanLength: Math.round(meanLength * 100) / 100,
107
+ stdLength: Math.round(stdLength * 100) / 100,
108
+ hedgeDensityPer100w: per100w(totalHedges),
109
+ absoluteDensityPer100w: per100w(totalAbsolutes),
110
+ codeBlockRate: Math.round((codeBlockSamples / samples.length) * 1000) / 1000,
111
+ bulletRate: Math.round((bulletSamples / samples.length) * 1000) / 1000,
112
+ topTokens,
113
+ windowStart,
114
+ windowEnd,
115
+ };
116
+ const sig = createHmac("sha256", secret ?? defaultSecret()).update(canon(body)).digest("hex");
117
+ return { ...body, sig };
118
+ }
119
+ export function verifyProfile(p, secret) {
120
+ const { sig: claimed, ...body } = p;
121
+ const expected = createHmac("sha256", secret ?? defaultSecret()).update(canon(body)).digest("hex");
122
+ try {
123
+ return timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(claimed, "hex"));
124
+ }
125
+ catch {
126
+ return false;
127
+ }
128
+ }
129
+ function jaccard(a, b) {
130
+ const ta = new Set(tokenize(a).filter((t) => !STOPWORDS.has(t)));
131
+ const tb = new Set(tokenize(b).filter((t) => !STOPWORDS.has(t)));
132
+ if (ta.size === 0 && tb.size === 0)
133
+ return 1;
134
+ let inter = 0;
135
+ for (const t of ta)
136
+ if (tb.has(t))
137
+ inter++;
138
+ const union = ta.size + tb.size - inter;
139
+ return union === 0 ? 0 : inter / union;
140
+ }
141
+ export function askGhost(input) {
142
+ const reasons = [];
143
+ const ofVendor = input.samples.filter((s) => s.vendor === input.profile.vendor);
144
+ if (ofVendor.length === 0) {
145
+ return {
146
+ vendor: input.profile.vendor,
147
+ found: false,
148
+ similarity: 0,
149
+ confidence: "none",
150
+ reasons: ["no samples for this vendor — record some first"],
151
+ profileSig: input.profile.sig,
152
+ };
153
+ }
154
+ let best = null;
155
+ for (const s of ofVendor) {
156
+ const sim = jaccard(input.prompt, s.prompt);
157
+ if (!best || sim > best.sim)
158
+ best = { sample: s, sim };
159
+ }
160
+ if (!best || best.sim === 0) {
161
+ return {
162
+ vendor: input.profile.vendor,
163
+ found: false,
164
+ similarity: 0,
165
+ confidence: "none",
166
+ reasons: ["no overlap with any sample — vendor has never seen anything like this"],
167
+ profileSig: input.profile.sig,
168
+ };
169
+ }
170
+ const sim = Math.round(best.sim * 1000) / 1000;
171
+ const confidence = sim > 0.5 ? "high" : sim > 0.25 ? "medium" : "low";
172
+ reasons.push(`nearest historical prompt sim=${sim}`);
173
+ reasons.push(`profile signature: hedge=${input.profile.hedgeDensityPer100w}/100w, mean-len=${input.profile.meanLength}`);
174
+ // Surface the matched response verbatim — the user wanted "what would X say"
175
+ // and X did say something similar before; no fabrication.
176
+ return {
177
+ vendor: input.profile.vendor,
178
+ found: true,
179
+ matchedFromPrompt: best.sample.prompt,
180
+ response: best.sample.response,
181
+ similarity: sim,
182
+ confidence,
183
+ reasons,
184
+ profileSig: input.profile.sig,
185
+ };
186
+ }
187
+ /** Distance between two profiles — useful for "is Grok actually different from Claude?" */
188
+ export function profileDistance(a, b) {
189
+ const f = (x) => Number.isFinite(x) ? x : 0;
190
+ const d1 = Math.abs(f(a.hedgeDensityPer100w) - f(b.hedgeDensityPer100w));
191
+ const d2 = Math.abs(f(a.absoluteDensityPer100w) - f(b.absoluteDensityPer100w));
192
+ const d3 = Math.abs(f(a.codeBlockRate) - f(b.codeBlockRate));
193
+ const d4 = Math.abs(f(a.bulletRate) - f(b.bulletRate));
194
+ const d5 = Math.abs(f(a.meanLength) - f(b.meanLength)) / Math.max(1, f(a.meanLength) + f(b.meanLength));
195
+ // Normalise each dim into [0,1]
196
+ const nd1 = Math.min(1, d1 / 5);
197
+ const nd2 = Math.min(1, d2 / 5);
198
+ const sum = (nd1 + nd2 + d3 + d4 + d5) / 5;
199
+ return Math.round(sum * 1000) / 1000;
200
+ }
201
+ export function formatGhostLine(g) {
202
+ if (!g.found)
203
+ return `👻 GHOST · ${g.vendor} · no match (${g.confidence})`;
204
+ return `👻 GHOST · ${g.vendor} · sim=${g.similarity} (${g.confidence})`;
205
+ }
206
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vendor_ghost/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=vendor_ghost.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor_ghost.test.d.ts","sourceRoot":"","sources":["../../src/vendor_ghost/vendor_ghost.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,93 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { distillProfile, verifyProfile, askGhost, profileDistance, formatGhostLine } from "./index.js";
3
+ function grokSamples() {
4
+ return [
5
+ { vendor: "grok", prompt: "is null === undefined?", response: "Definitely not. They're distinct primitives. Always use ===.", ts: "2026-05-10T00:00:00Z" },
6
+ { vendor: "grok", prompt: "should I use Promise.all?", response: "Yes, absolutely. Never serialise when you can parallelise.", ts: "2026-05-11T00:00:00Z" },
7
+ { vendor: "grok", prompt: "how to fix this race?", response: "Use a mutex. Never roll your own.", ts: "2026-05-12T00:00:00Z" },
8
+ ];
9
+ }
10
+ function claudeSamples() {
11
+ return [
12
+ { vendor: "claude", prompt: "is null === undefined?", response: "I think they're different in most cases — maybe try using ===.", ts: "2026-05-10T00:00:00Z" },
13
+ { vendor: "claude", prompt: "should I use Promise.all?", response: "Perhaps. It depends on whether the operations are independent.", ts: "2026-05-11T00:00:00Z" },
14
+ { vendor: "claude", prompt: "how to fix this race?", response: "It might help to use a mutex, though there are other approaches.", ts: "2026-05-12T00:00:00Z" },
15
+ ];
16
+ }
17
+ describe("v2.19 · MNEME VENDOR GHOST — stylometric distillation", () => {
18
+ it("distills a signed profile from samples", () => {
19
+ const p = distillProfile(grokSamples());
20
+ expect(p.vendor).toBe("grok");
21
+ expect(p.sampleCount).toBe(3);
22
+ expect(p.sig).toMatch(/^[0-9a-f]{64}$/);
23
+ expect(verifyProfile(p)).toBe(true);
24
+ });
25
+ it("rejects mixed-vendor sample sets", () => {
26
+ expect(() => distillProfile([...grokSamples(), ...claudeSamples()])).toThrow(/same vendor/);
27
+ });
28
+ it("rejects empty sample sets", () => {
29
+ expect(() => distillProfile([])).toThrow(/at least 1 sample/);
30
+ });
31
+ it("distinguishes Grok (absolute-heavy) from Claude (hedge-heavy)", () => {
32
+ const grok = distillProfile(grokSamples());
33
+ const claude = distillProfile(claudeSamples());
34
+ expect(grok.absoluteDensityPer100w).toBeGreaterThan(claude.absoluteDensityPer100w);
35
+ expect(claude.hedgeDensityPer100w).toBeGreaterThan(grok.hedgeDensityPer100w);
36
+ });
37
+ it("profileDistance is > 0 between visibly different vendors", () => {
38
+ const grok = distillProfile(grokSamples());
39
+ const claude = distillProfile(claudeSamples());
40
+ const d = profileDistance(grok, claude);
41
+ expect(d).toBeGreaterThan(0);
42
+ });
43
+ it("profileDistance is 0 for identical profiles", () => {
44
+ const a = distillProfile(grokSamples());
45
+ const b = distillProfile(grokSamples());
46
+ expect(profileDistance(a, b)).toBe(0);
47
+ });
48
+ it("verifyProfile detects tampering", () => {
49
+ const p = distillProfile(grokSamples());
50
+ expect(verifyProfile(p)).toBe(true);
51
+ const tampered = { ...p, meanLength: 9999 };
52
+ expect(verifyProfile(tampered)).toBe(false);
53
+ });
54
+ it("askGhost returns nearest historical answer for similar prompt", () => {
55
+ const samples = grokSamples();
56
+ const p = distillProfile(samples);
57
+ const g = askGhost({ profile: p, samples, prompt: "is null equal to undefined?" });
58
+ expect(g.found).toBe(true);
59
+ expect(g.matchedFromPrompt).toContain("null");
60
+ expect(g.similarity).toBeGreaterThan(0);
61
+ expect(["high", "medium", "low"]).toContain(g.confidence);
62
+ });
63
+ it("askGhost returns no-match for an unrelated prompt", () => {
64
+ const samples = grokSamples();
65
+ const p = distillProfile(samples);
66
+ const g = askGhost({ profile: p, samples, prompt: "spaceship orbital mechanics for kerbals" });
67
+ expect(g.found).toBe(false);
68
+ expect(g.confidence).toBe("none");
69
+ });
70
+ it("askGhost respects vendor isolation (won't return Claude's answer for Grok profile)", () => {
71
+ const grokP = distillProfile(grokSamples());
72
+ const allSamples = [...grokSamples(), ...claudeSamples()];
73
+ const g = askGhost({ profile: grokP, samples: allSamples, prompt: "is null === undefined?" });
74
+ expect(g.found).toBe(true);
75
+ expect(g.response).toContain("Definitely"); // Grok-flavour, not Claude
76
+ });
77
+ it("works for every supported vendor", () => {
78
+ const vendors = ["claude", "chatgpt", "gemini", "cursor", "copilot", "codex", "llama", "mistral", "qwen", "deepseek", "perplexity", "other"];
79
+ for (const v of vendors) {
80
+ const s = [{ vendor: v, prompt: "x", response: "y" }];
81
+ const p = distillProfile(s);
82
+ expect(p.vendor).toBe(v);
83
+ expect(verifyProfile(p)).toBe(true);
84
+ }
85
+ });
86
+ it("formatGhostLine summarises", () => {
87
+ const p = distillProfile(grokSamples());
88
+ const g = askGhost({ profile: p, samples: grokSamples(), prompt: "is null === undefined?" });
89
+ expect(formatGhostLine(g)).toContain("GHOST");
90
+ expect(formatGhostLine(g)).toContain("grok");
91
+ });
92
+ });
93
+ //# sourceMappingURL=vendor_ghost.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor_ghost.test.js","sourceRoot":"","sources":["../../src/vendor_ghost/vendor_ghost.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
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
+ declare const PROTOCOL_VERSION: 1;
27
+ export type BadgeTier = "platinum" | "gold" | "silver" | "bronze" | "fail";
28
+ export interface BadgeInput {
29
+ vendor: string;
30
+ /** Vendor's display name on the badge (e.g., "Anthropic Claude"). */
31
+ displayName: string;
32
+ /** Measured falseRateLB from BOUNTY/OBELISK. */
33
+ falseRateLB: number;
34
+ /** Total verdicts in the sample (must clear tier minimum). */
35
+ totalVerdicts: number;
36
+ /** Issuance timestamp; defaults to now. */
37
+ issuedAt?: string;
38
+ /** Validity in days; defaults to 90. */
39
+ validityDays?: number;
40
+ secret?: string;
41
+ }
42
+ export interface VerifiedBadge {
43
+ v: typeof PROTOCOL_VERSION;
44
+ vendor: string;
45
+ displayName: string;
46
+ tier: BadgeTier;
47
+ measured: {
48
+ falseRateLB: number;
49
+ totalVerdicts: number;
50
+ };
51
+ issuedAt: string;
52
+ validUntil: string;
53
+ /** Public certificate ID for embed. */
54
+ certId: string;
55
+ /** HMAC over the certificate body. */
56
+ sig: string;
57
+ }
58
+ export interface VerifyResult {
59
+ ok: boolean;
60
+ expired: boolean;
61
+ reason?: string;
62
+ badge?: VerifiedBadge;
63
+ }
64
+ export declare function determineTier(falseRateLB: number, totalVerdicts: number): BadgeTier;
65
+ export declare function issueBadge(input: BadgeInput): VerifiedBadge;
66
+ export declare function verifyBadge(badge: VerifiedBadge, secret?: string): VerifyResult;
67
+ /**
68
+ * Generate an embed-safe SVG for the badge. Width/height fixed at 240×60
69
+ * for marketing footers. Tier color: platinum silver-blue, gold yellow-orange,
70
+ * silver gray, bronze copper. Includes the certId so verifiers can lookup.
71
+ */
72
+ export declare function badgeSvg(badge: VerifiedBadge): string;
73
+ /** One-line pulse summary. */
74
+ export declare function formatBadgeLine(b: VerifiedBadge): string;
75
+ /** Tier-pricing model (informational; the actual billing is out of band). */
76
+ export declare function tierAnnualLicense(tier: BadgeTier): number;
77
+ export {};
78
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/verified_badge/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,QAAA,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAEpC,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE;QACR,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAoBD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,CAOnF;AAQD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAqB3D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CAW/E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAiBrD;AAED,8BAA8B;AAC9B,wBAAgB,eAAe,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAExD;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAGzD"}