@mneme-ai/core 2.18.0 → 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 +11 -1
- package/dist/agent_manifest.js.map +1 -1
- package/dist/arena/index.d.ts +1 -1
- package/dist/arena/index.d.ts.map +1 -1
- 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_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 +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -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/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/package.json +1 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.0 — MNEME VENDOR BOOMERANG (the cross-vendor brain no single vendor has)
|
|
3
|
+
*
|
|
4
|
+
* "Grok generates code that touches src/foo.ts. Claude wrote that file
|
|
5
|
+
* yesterday. Grok has no idea Claude exists — xAI's silo can't see
|
|
6
|
+
* Anthropic's history, and vice versa. BOOMERANG closes the gap:
|
|
7
|
+
* Mneme records every vendor's recent edits in a local activity
|
|
8
|
+
* ledger, and when a NEW vendor arrives at a file another vendor
|
|
9
|
+
* just touched, Mneme injects 'recent cross-vendor context' into the
|
|
10
|
+
* incoming vendor's prompt: 'last touched by claude 2h ago — they
|
|
11
|
+
* introduced calculateTotal at line 42; don't duplicate.'"
|
|
12
|
+
*
|
|
13
|
+
* Vendor-agnostic: every vendor (claude / chatgpt / gemini / cursor /
|
|
14
|
+
* copilot / codex / llama / mistral / qwen / deepseek / grok /
|
|
15
|
+
* perplexity / other) writes to the same ledger and reads the same
|
|
16
|
+
* boomerang context.
|
|
17
|
+
*
|
|
18
|
+
* Honest scope:
|
|
19
|
+
* - BOOMERANG ledger is local to the repo's .mneme/ directory by
|
|
20
|
+
* default; no cross-org leakage.
|
|
21
|
+
* - BOOMERANG does NOT execute on the vendor's behalf — it formats a
|
|
22
|
+
* plain-text context block the AI agent should prepend to its
|
|
23
|
+
* next prompt. The user's MCP client wires that into the call.
|
|
24
|
+
* - Activity ledger entries are HMAC-signed (chain), so a vendor
|
|
25
|
+
* can't falsely "claim credit" for edits it didn't make.
|
|
26
|
+
*
|
|
27
|
+
* Composes onto v2.18 NEXUS PROACTIVE (push side) + v2.16 LIVING MODEL
|
|
28
|
+
* (anti-entropy if you want it to gossip). Pure additive layer.
|
|
29
|
+
*/
|
|
30
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
31
|
+
const PROTOCOL_VERSION = 1;
|
|
32
|
+
function canon(v) {
|
|
33
|
+
if (v === null || typeof v !== "object")
|
|
34
|
+
return JSON.stringify(v);
|
|
35
|
+
if (Array.isArray(v))
|
|
36
|
+
return "[" + v.map(canon).join(",") + "]";
|
|
37
|
+
const keys = Object.keys(v).sort();
|
|
38
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
|
|
39
|
+
}
|
|
40
|
+
function defaultSecret() {
|
|
41
|
+
return process.env["MNEME_BOOMERANG_SECRET"] || `mneme-vendor-boomerang-v${PROTOCOL_VERSION}`;
|
|
42
|
+
}
|
|
43
|
+
export class VendorBoomerang {
|
|
44
|
+
ledger = [];
|
|
45
|
+
secret;
|
|
46
|
+
constructor(secret) {
|
|
47
|
+
this.secret = secret ?? defaultSecret();
|
|
48
|
+
}
|
|
49
|
+
/** Record an activity. Returns the signed record. */
|
|
50
|
+
record(input) {
|
|
51
|
+
const ts = input.ts ?? new Date().toISOString();
|
|
52
|
+
const prevSig = this.ledger.length === 0 ? "genesis".padEnd(64, "0") : this.ledger[this.ledger.length - 1].sig;
|
|
53
|
+
const recordId = "act-" + createHmac("sha256", "mneme-boomerang-id")
|
|
54
|
+
.update(`${input.vendor}|${input.filePath}|${ts}|${this.ledger.length}`)
|
|
55
|
+
.digest("hex").slice(0, 14);
|
|
56
|
+
const body = {
|
|
57
|
+
v: PROTOCOL_VERSION,
|
|
58
|
+
recordId,
|
|
59
|
+
vendor: input.vendor,
|
|
60
|
+
kind: input.kind,
|
|
61
|
+
filePath: input.filePath,
|
|
62
|
+
...(input.symbol ? { symbol: input.symbol } : {}),
|
|
63
|
+
...(input.location ? { location: input.location } : {}),
|
|
64
|
+
note: input.note,
|
|
65
|
+
ts,
|
|
66
|
+
prevSig,
|
|
67
|
+
};
|
|
68
|
+
const sig = createHmac("sha256", this.secret).update(canon(body)).digest("hex");
|
|
69
|
+
const rec = { ...body, sig };
|
|
70
|
+
this.ledger.push(rec);
|
|
71
|
+
return rec;
|
|
72
|
+
}
|
|
73
|
+
/** Build a boomerang context for `incomingVendor` touching `filePath`. */
|
|
74
|
+
build(input) {
|
|
75
|
+
const now = input.nowMs ?? Date.now();
|
|
76
|
+
const lookbackMs = (input.lookbackSeconds ?? 86400) * 1000;
|
|
77
|
+
const cutoff = now - lookbackMs;
|
|
78
|
+
const max = input.maxRecords ?? 8;
|
|
79
|
+
const relevant = this.ledger
|
|
80
|
+
.filter((r) => r.vendor !== input.incomingVendor)
|
|
81
|
+
.filter((r) => r.filePath === input.filePath)
|
|
82
|
+
.filter((r) => Date.parse(r.ts) >= cutoff)
|
|
83
|
+
.sort((a, b) => Date.parse(b.ts) - Date.parse(a.ts))
|
|
84
|
+
.slice(0, max);
|
|
85
|
+
const lines = relevant.length === 0
|
|
86
|
+
? ["(no recent cross-vendor activity on this file)"]
|
|
87
|
+
: relevant.map((r) => {
|
|
88
|
+
const ageMin = Math.round((now - Date.parse(r.ts)) / 60_000);
|
|
89
|
+
const sym = r.symbol ? ` · symbol \`${r.symbol}\`` : "";
|
|
90
|
+
const loc = r.location ? ` @ ${r.location}` : "";
|
|
91
|
+
return `- ${r.vendor} · ${r.kind}${sym}${loc} · ${ageMin}m ago · "${r.note}"`;
|
|
92
|
+
});
|
|
93
|
+
const injectedContextBlock = [
|
|
94
|
+
`[MNEME BOOMERANG · ${input.filePath}]`,
|
|
95
|
+
`Recent activity by OTHER vendors on this file (look-back ${input.lookbackSeconds ?? 86400}s):`,
|
|
96
|
+
...lines,
|
|
97
|
+
`(Source: HMAC-signed local activity ledger; ${relevant.length} record(s).)`,
|
|
98
|
+
].join("\n");
|
|
99
|
+
const builtAt = new Date(now).toISOString();
|
|
100
|
+
const body = {
|
|
101
|
+
v: PROTOCOL_VERSION,
|
|
102
|
+
builtFor: input.incomingVendor,
|
|
103
|
+
filePath: input.filePath,
|
|
104
|
+
relevantRecords: relevant,
|
|
105
|
+
injectedContextBlock,
|
|
106
|
+
builtAt,
|
|
107
|
+
};
|
|
108
|
+
const sig = createHmac("sha256", this.secret).update(canon(body)).digest("hex");
|
|
109
|
+
return { ...body, sig };
|
|
110
|
+
}
|
|
111
|
+
/** Verify a record's signature in isolation. */
|
|
112
|
+
verifyRecord(r) {
|
|
113
|
+
const { sig: claimed, ...body } = r;
|
|
114
|
+
const expected = createHmac("sha256", this.secret).update(canon(body)).digest("hex");
|
|
115
|
+
try {
|
|
116
|
+
return timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(claimed, "hex"));
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Verify the full chain integrity (each record's prevSig matches predecessor.sig). */
|
|
123
|
+
verifyChain() {
|
|
124
|
+
for (let i = 0; i < this.ledger.length; i++) {
|
|
125
|
+
const rec = this.ledger[i];
|
|
126
|
+
if (!this.verifyRecord(rec)) {
|
|
127
|
+
return { ok: false, brokenAt: i, reason: "record sig mismatch" };
|
|
128
|
+
}
|
|
129
|
+
if (i === 0) {
|
|
130
|
+
if (rec.prevSig !== "genesis".padEnd(64, "0")) {
|
|
131
|
+
return { ok: false, brokenAt: 0, reason: "genesis prevSig wrong" };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const prev = this.ledger[i - 1];
|
|
136
|
+
if (rec.prevSig !== prev.sig) {
|
|
137
|
+
return { ok: false, brokenAt: i, reason: "chain link mismatch" };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return { ok: true };
|
|
142
|
+
}
|
|
143
|
+
/** Per-vendor activity counts. */
|
|
144
|
+
stats() {
|
|
145
|
+
const perVendor = {};
|
|
146
|
+
const files = new Set();
|
|
147
|
+
for (const r of this.ledger) {
|
|
148
|
+
perVendor[r.vendor] = (perVendor[r.vendor] ?? 0) + 1;
|
|
149
|
+
files.add(r.filePath);
|
|
150
|
+
}
|
|
151
|
+
return { totalRecords: this.ledger.length, perVendor, uniqueFiles: files.size };
|
|
152
|
+
}
|
|
153
|
+
/** Export the full ledger (e.g., to persist .mneme/boomerang.jsonl). */
|
|
154
|
+
exportLedger() {
|
|
155
|
+
return [...this.ledger];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export function formatBoomerangLine(c) {
|
|
159
|
+
return `📡 BOOMERANG · for ${c.builtFor} · ${c.filePath} · ${c.relevantRecords.length} cross-vendor record(s)`;
|
|
160
|
+
}
|
|
161
|
+
let _instance = null;
|
|
162
|
+
export function defaultBoomerang() {
|
|
163
|
+
if (!_instance)
|
|
164
|
+
_instance = new VendorBoomerang();
|
|
165
|
+
return _instance;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vendor_boomerang/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor_boomerang.test.d.ts","sourceRoot":"","sources":["../../src/vendor_boomerang/vendor_boomerang.test.ts"],"names":[],"mappings":""}
|
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"vendor_ghost.test.d.ts","sourceRoot":"","sources":["../../src/vendor_ghost/vendor_ghost.test.ts"],"names":[],"mappings":""}
|