@mneme-ai/core 2.29.1 → 2.31.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 +23 -0
- package/dist/agent_manifest.js.map +1 -1
- package/dist/conclave/aletheia_weights.d.ts.map +1 -1
- package/dist/conclave/aletheia_weights.js +16 -4
- package/dist/conclave/aletheia_weights.js.map +1 -1
- package/dist/diaspora/http_bridge.d.ts.map +1 -1
- package/dist/hgp/hgp.test.d.ts +2 -0
- package/dist/hgp/hgp.test.d.ts.map +1 -0
- package/dist/hgp/hgp.test.js +198 -0
- package/dist/hgp/hgp.test.js.map +1 -0
- package/dist/hgp/hgp_id.d.ts +18 -0
- package/dist/hgp/hgp_id.d.ts.map +1 -0
- package/dist/hgp/hgp_id.js +41 -0
- package/dist/hgp/hgp_id.js.map +1 -0
- package/dist/hgp/index.d.ts +12 -0
- package/dist/hgp/index.d.ts.map +1 -0
- package/dist/hgp/index.js +10 -0
- package/dist/hgp/index.js.map +1 -0
- package/dist/hgp/registry.d.ts +64 -0
- package/dist/hgp/registry.d.ts.map +1 -0
- package/dist/hgp/registry.js +221 -0
- package/dist/hgp/registry.js.map +1 -0
- package/dist/hgp/severity.d.ts +19 -0
- package/dist/hgp/severity.d.ts.map +1 -0
- package/dist/hgp/severity.js +46 -0
- package/dist/hgp/severity.js.map +1 -0
- package/dist/hgp/types.d.ts +60 -0
- package/dist/hgp/types.d.ts.map +1 -0
- package/dist/hgp/types.js +11 -0
- package/dist/hgp/types.js.map +1 -0
- package/dist/honest_mirror/anonymizer.d.ts +29 -0
- package/dist/honest_mirror/anonymizer.d.ts.map +1 -0
- package/dist/honest_mirror/anonymizer.js +77 -0
- package/dist/honest_mirror/anonymizer.js.map +1 -0
- package/dist/honest_mirror/calibration.d.ts +37 -0
- package/dist/honest_mirror/calibration.d.ts.map +1 -0
- package/dist/honest_mirror/calibration.js +106 -0
- package/dist/honest_mirror/calibration.js.map +1 -0
- package/dist/honest_mirror/engine.d.ts +66 -0
- package/dist/honest_mirror/engine.d.ts.map +1 -0
- package/dist/honest_mirror/engine.js +227 -0
- package/dist/honest_mirror/engine.js.map +1 -0
- package/dist/honest_mirror/honest_mirror.test.d.ts +2 -0
- package/dist/honest_mirror/honest_mirror.test.d.ts.map +1 -0
- package/dist/honest_mirror/honest_mirror.test.js +109 -0
- package/dist/honest_mirror/honest_mirror.test.js.map +1 -0
- package/dist/honest_mirror/index.d.ts +11 -0
- package/dist/honest_mirror/index.d.ts.map +1 -0
- package/dist/honest_mirror/index.js +9 -0
- package/dist/honest_mirror/index.js.map +1 -0
- package/dist/honest_mirror/sources/git_commit_source.d.ts +30 -0
- package/dist/honest_mirror/sources/git_commit_source.d.ts.map +1 -0
- package/dist/honest_mirror/sources/git_commit_source.js +106 -0
- package/dist/honest_mirror/sources/git_commit_source.js.map +1 -0
- package/dist/honest_mirror/types.d.ts +126 -0
- package/dist/honest_mirror/types.d.ts.map +1 -0
- package/dist/honest_mirror/types.js +31 -0
- package/dist/honest_mirror/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/rewind/engine.d.ts +65 -0
- package/dist/rewind/engine.d.ts.map +1 -0
- package/dist/rewind/engine.js +473 -0
- package/dist/rewind/engine.js.map +1 -0
- package/dist/rewind/index.d.ts +13 -0
- package/dist/rewind/index.d.ts.map +1 -0
- package/dist/rewind/index.js +11 -0
- package/dist/rewind/index.js.map +1 -0
- package/dist/rewind/intent_class.d.ts +35 -0
- package/dist/rewind/intent_class.d.ts.map +1 -0
- package/dist/rewind/intent_class.js +141 -0
- package/dist/rewind/intent_class.js.map +1 -0
- package/dist/rewind/rewind.test.d.ts +2 -0
- package/dist/rewind/rewind.test.d.ts.map +1 -0
- package/dist/rewind/rewind.test.js +176 -0
- package/dist/rewind/rewind.test.js.map +1 -0
- package/dist/rewind/types.d.ts +140 -0
- package/dist/rewind/types.d.ts.map +1 -0
- package/dist/rewind/types.js +11 -0
- package/dist/rewind/types.js.map +1 -0
- package/dist/squadron/acgv_vaccine.d.ts.map +1 -1
- package/dist/squadron/acgv_vaccine.js +15 -0
- package/dist/squadron/acgv_vaccine.js.map +1 -1
- package/dist/truth_gate/claims.d.ts.map +1 -1
- package/dist/truth_gate/claims.js +37 -0
- package/dist/truth_gate/claims.js.map +1 -1
- package/dist/truth_gate/probes.d.ts.map +1 -1
- package/dist/truth_gate/probes.js +107 -1
- package/dist/truth_gate/probes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// v2.31.0 — HGP (Hallucination Genome Project) discrete root tests.
|
|
2
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
3
|
+
import { mkdtempSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { computeHgpIdFromSimhash, isValidHgpId, disambiguate, recordHallucination, lookup, topN, loadCollapsed, computeSeverity, readConsent, setConsent, federationStatus, federatePush, verifyLedger, severityForVendor, allVendorsBreakdown, topInWindow, } from "./index.js";
|
|
7
|
+
describe("HGP-ID format", () => {
|
|
8
|
+
it("isValidHgpId accepts canonical form", () => {
|
|
9
|
+
expect(isValidHgpId("HGP-2026-00001")).toBe(true);
|
|
10
|
+
expect(isValidHgpId("HGP-2026-12345")).toBe(true);
|
|
11
|
+
expect(isValidHgpId("HGP-2026-12345-A")).toBe(true);
|
|
12
|
+
expect(isValidHgpId("HGP-2026-12345-AB")).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
it("isValidHgpId rejects malformed", () => {
|
|
15
|
+
expect(isValidHgpId("HGP-26-1")).toBe(false);
|
|
16
|
+
expect(isValidHgpId("CVE-2026-12345")).toBe(false);
|
|
17
|
+
expect(isValidHgpId("HGP-2026-123")).toBe(false);
|
|
18
|
+
expect(isValidHgpId("")).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
it("computeHgpIdFromSimhash is deterministic", () => {
|
|
21
|
+
const sim = "deadbeefdeadbeef";
|
|
22
|
+
const id1 = computeHgpIdFromSimhash(sim, "2026-05-23T00:00:00Z");
|
|
23
|
+
const id2 = computeHgpIdFromSimhash(sim, "2026-05-23T00:00:00Z");
|
|
24
|
+
expect(id1).toBe(id2);
|
|
25
|
+
expect(isValidHgpId(id1)).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it("computeHgpIdFromSimhash differs per simhash within same year", () => {
|
|
28
|
+
const id1 = computeHgpIdFromSimhash("aaaaaaaaaaaaaaaa", "2026-05-23T00:00:00Z");
|
|
29
|
+
const id2 = computeHgpIdFromSimhash("bbbbbbbbbbbbbbbb", "2026-05-23T00:00:00Z");
|
|
30
|
+
expect(id1).not.toBe(id2);
|
|
31
|
+
});
|
|
32
|
+
it("disambiguate appends A, B, C correctly", () => {
|
|
33
|
+
expect(disambiguate("HGP-2026-00001", 0)).toBe("HGP-2026-00001");
|
|
34
|
+
expect(disambiguate("HGP-2026-00001", 1)).toBe("HGP-2026-00001-A");
|
|
35
|
+
expect(disambiguate("HGP-2026-00001", 2)).toBe("HGP-2026-00001-B");
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
describe("recordHallucination + lookup", () => {
|
|
39
|
+
let repo;
|
|
40
|
+
beforeEach(() => { repo = mkdtempSync(join(tmpdir(), "hgp-test-")); });
|
|
41
|
+
it("records a hallucination + assigns a valid HGP-ID", () => {
|
|
42
|
+
const r = recordHallucination(repo, {
|
|
43
|
+
claim: "useFormStatus accepts a reset option",
|
|
44
|
+
signature: "chandrasekhar:UNKNOWN_API",
|
|
45
|
+
vendor: "claude-opus-4.7",
|
|
46
|
+
});
|
|
47
|
+
expect(isValidHgpId(r.hgpId)).toBe(true);
|
|
48
|
+
expect(r.observeCount).toBe(1);
|
|
49
|
+
expect(r.vendorCounts["claude-opus-4.7"]).toBe(1);
|
|
50
|
+
});
|
|
51
|
+
it("same simhash → same HGP-ID across calls (idempotent identity)", () => {
|
|
52
|
+
const r1 = recordHallucination(repo, {
|
|
53
|
+
claim: "useFormStatus accepts a reset option",
|
|
54
|
+
signature: "chandrasekhar:UNKNOWN_API",
|
|
55
|
+
vendor: "claude",
|
|
56
|
+
});
|
|
57
|
+
const r2 = recordHallucination(repo, {
|
|
58
|
+
claim: "useFormStatus accepts a reset option",
|
|
59
|
+
signature: "chandrasekhar:UNKNOWN_API",
|
|
60
|
+
vendor: "gpt-5",
|
|
61
|
+
});
|
|
62
|
+
expect(r2.hgpId).toBe(r1.hgpId);
|
|
63
|
+
const collapsed = loadCollapsed(repo).get(r1.hgpId);
|
|
64
|
+
expect(collapsed.observeCount).toBe(2);
|
|
65
|
+
expect(collapsed.vendorCounts["claude"]).toBe(1);
|
|
66
|
+
expect(collapsed.vendorCounts["gpt-5"]).toBe(1);
|
|
67
|
+
});
|
|
68
|
+
it("different simhash → different HGP-ID", () => {
|
|
69
|
+
const r1 = recordHallucination(repo, {
|
|
70
|
+
claim: "React 19 ships server components by default",
|
|
71
|
+
signature: "x", vendor: "a",
|
|
72
|
+
});
|
|
73
|
+
const r2 = recordHallucination(repo, {
|
|
74
|
+
claim: "asyncio.gather accepts a loop= parameter today",
|
|
75
|
+
signature: "x", vendor: "a",
|
|
76
|
+
});
|
|
77
|
+
expect(r2.hgpId).not.toBe(r1.hgpId);
|
|
78
|
+
});
|
|
79
|
+
it("severity grows with observe count + vendor spread", () => {
|
|
80
|
+
const c = "Vue 4 was released yesterday with major breaking changes";
|
|
81
|
+
let r = recordHallucination(repo, { claim: c, signature: "x", vendor: "a" });
|
|
82
|
+
const sev1 = r.severity;
|
|
83
|
+
for (let i = 0; i < 5; i++)
|
|
84
|
+
recordHallucination(repo, { claim: c, signature: "x", vendor: "a" });
|
|
85
|
+
recordHallucination(repo, { claim: c, signature: "x", vendor: "b" });
|
|
86
|
+
recordHallucination(repo, { claim: c, signature: "x", vendor: "c" });
|
|
87
|
+
r = lookup(repo, r.hgpId);
|
|
88
|
+
expect(r.severity).toBeGreaterThan(sev1);
|
|
89
|
+
});
|
|
90
|
+
it("topN returns highest severity first", () => {
|
|
91
|
+
const A = "Common lie about something useful long sentence here";
|
|
92
|
+
const B = "Rare lie observed only once particular pattern";
|
|
93
|
+
for (let i = 0; i < 5; i++)
|
|
94
|
+
recordHallucination(repo, { claim: A, signature: "x", vendor: "v" });
|
|
95
|
+
recordHallucination(repo, { claim: B, signature: "x", vendor: "v" });
|
|
96
|
+
const top = topN(repo, 2);
|
|
97
|
+
expect(top.length).toBe(2);
|
|
98
|
+
expect(top[0].observeCount).toBeGreaterThanOrEqual(top[1].observeCount);
|
|
99
|
+
});
|
|
100
|
+
it("redacts obvious secrets from sample text", () => {
|
|
101
|
+
const r = recordHallucination(repo, {
|
|
102
|
+
claim: "the AWS key AKIAIOSFODNN7EXAMPLE was used to call S3",
|
|
103
|
+
signature: "x", vendor: "v",
|
|
104
|
+
});
|
|
105
|
+
expect(r.sample).not.toContain("AKIAIOSFODNN7EXAMPLE");
|
|
106
|
+
expect(r.sample).toContain("<aws-key>");
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe("federation consent (default OFF)", () => {
|
|
110
|
+
let repo;
|
|
111
|
+
beforeEach(() => { repo = mkdtempSync(join(tmpdir(), "hgp-cons-")); });
|
|
112
|
+
it("default consent is opt-out", () => {
|
|
113
|
+
const c = readConsent(repo);
|
|
114
|
+
expect(c.optIn).toBe(false);
|
|
115
|
+
});
|
|
116
|
+
it("setConsent persists across reads", () => {
|
|
117
|
+
setConsent(repo, true, "https://hgp.ai");
|
|
118
|
+
const c = readConsent(repo);
|
|
119
|
+
expect(c.optIn).toBe(true);
|
|
120
|
+
expect(c.endpoint).toBe("https://hgp.ai");
|
|
121
|
+
});
|
|
122
|
+
it("federationStatus reports localCount + consent", () => {
|
|
123
|
+
recordHallucination(repo, { claim: "x lie sentence pattern abc", signature: "y", vendor: "z" });
|
|
124
|
+
const s = federationStatus(repo);
|
|
125
|
+
expect(s.localCount).toBe(1);
|
|
126
|
+
expect(s.consent.optIn).toBe(false);
|
|
127
|
+
});
|
|
128
|
+
it("federatePush refuses without consent", async () => {
|
|
129
|
+
const r = await federatePush(repo);
|
|
130
|
+
expect(r.ok).toBe(false);
|
|
131
|
+
expect(r.reason).toMatch(/consent/i);
|
|
132
|
+
});
|
|
133
|
+
it("federatePush refuses with consent but no endpoint", async () => {
|
|
134
|
+
setConsent(repo, true);
|
|
135
|
+
const r = await federatePush(repo);
|
|
136
|
+
expect(r.ok).toBe(false);
|
|
137
|
+
expect(r.reason).toMatch(/endpoint/i);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
describe("severity windowing", () => {
|
|
141
|
+
let repo;
|
|
142
|
+
beforeEach(() => { repo = mkdtempSync(join(tmpdir(), "hgp-sev-")); });
|
|
143
|
+
it("severityForVendor counts records in window", () => {
|
|
144
|
+
recordHallucination(repo, { claim: "first lie observed here", signature: "x", vendor: "anthropic" });
|
|
145
|
+
recordHallucination(repo, { claim: "second different lie observed", signature: "x", vendor: "anthropic" });
|
|
146
|
+
recordHallucination(repo, { claim: "third one for openai test", signature: "x", vendor: "openai" });
|
|
147
|
+
const a = severityForVendor(repo, "anthropic", 30);
|
|
148
|
+
expect(a.count).toBe(2);
|
|
149
|
+
expect(a.vendor).toBe("anthropic");
|
|
150
|
+
expect(a.windowDays).toBe(30);
|
|
151
|
+
});
|
|
152
|
+
it("allVendorsBreakdown lists every observed vendor", () => {
|
|
153
|
+
recordHallucination(repo, { claim: "lie 1 sentence long enough", signature: "x", vendor: "anthropic" });
|
|
154
|
+
recordHallucination(repo, { claim: "lie 2 sentence long enough", signature: "x", vendor: "openai" });
|
|
155
|
+
const all = allVendorsBreakdown(repo, 30);
|
|
156
|
+
const vendors = all.map((s) => s.vendor).sort();
|
|
157
|
+
expect(vendors).toContain("anthropic");
|
|
158
|
+
expect(vendors).toContain("openai");
|
|
159
|
+
});
|
|
160
|
+
it("topInWindow returns no record outside window", () => {
|
|
161
|
+
recordHallucination(repo, { claim: "lie in window test sentence", signature: "x", vendor: "v" });
|
|
162
|
+
const recent = topInWindow(repo, 30, 5);
|
|
163
|
+
expect(recent.length).toBe(1);
|
|
164
|
+
// 0-day window: nothing recent enough.
|
|
165
|
+
const none = topInWindow(repo, 0, 5);
|
|
166
|
+
expect(none.length).toBe(0);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
describe("verifyLedger", () => {
|
|
170
|
+
it("returns ok=true on empty registry", () => {
|
|
171
|
+
const repo = mkdtempSync(join(tmpdir(), "hgp-ver-"));
|
|
172
|
+
const r = verifyLedger(repo);
|
|
173
|
+
expect(r.ok).toBe(true);
|
|
174
|
+
expect(r.lines).toBe(0);
|
|
175
|
+
});
|
|
176
|
+
it("counts well-formed lines + accepts them", () => {
|
|
177
|
+
const repo = mkdtempSync(join(tmpdir(), "hgp-ver2-"));
|
|
178
|
+
recordHallucination(repo, { claim: "first lie ok one two three", signature: "x", vendor: "v" });
|
|
179
|
+
recordHallucination(repo, { claim: "second different shape lie one two", signature: "x", vendor: "v" });
|
|
180
|
+
const r = verifyLedger(repo);
|
|
181
|
+
expect(r.ok).toBe(true);
|
|
182
|
+
expect(r.lines).toBe(2);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
describe("computeSeverity bounds", () => {
|
|
186
|
+
it("severity is in [0,1]", () => {
|
|
187
|
+
const r = computeSeverity({
|
|
188
|
+
hgpId: "HGP-2026-00001",
|
|
189
|
+
simhash: "x", firstSeen: "x", lastSeen: "x",
|
|
190
|
+
observeCount: 1000,
|
|
191
|
+
vendorCounts: { a: 100, b: 100, c: 100, d: 100, e: 100 },
|
|
192
|
+
signature: "x", sample: "x", severity: 0,
|
|
193
|
+
});
|
|
194
|
+
expect(r).toBeGreaterThanOrEqual(0);
|
|
195
|
+
expect(r).toBeLessThanOrEqual(1);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
//# sourceMappingURL=hgp.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hgp.test.js","sourceRoot":"","sources":["../../src/hgp/hgp.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.31.0 — HGP-ID issuance (CVE-style deterministic IDs).
|
|
3
|
+
*
|
|
4
|
+
* Format: HGP-YYYY-NNNNN
|
|
5
|
+
* YYYY = year the hallucination was FIRST seen
|
|
6
|
+
* NNNNN = 5-digit base-10 derived deterministically from the
|
|
7
|
+
* hallucination's simhash so that the SAME shape on
|
|
8
|
+
* different machines + at different times gets the SAME
|
|
9
|
+
* HGP-ID (modulo year-collision, handled by the registry).
|
|
10
|
+
*
|
|
11
|
+
* The year-NNNNN combination is a 64-bit space → < 1 in 10^5
|
|
12
|
+
* per-year collision rate even at 10k hallucinations/year. Registry
|
|
13
|
+
* (next file) handles collision by appending -A / -B / ... suffix.
|
|
14
|
+
*/
|
|
15
|
+
export declare function computeHgpIdFromSimhash(simhash: string, firstSeen: string): string;
|
|
16
|
+
export declare function isValidHgpId(id: string): boolean;
|
|
17
|
+
export declare function disambiguate(baseId: string, takenCount: number): string;
|
|
18
|
+
//# sourceMappingURL=hgp_id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hgp_id.d.ts","sourceRoot":"","sources":["../../src/hgp/hgp_id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAOlF;AAID,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAWvE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.31.0 — HGP-ID issuance (CVE-style deterministic IDs).
|
|
3
|
+
*
|
|
4
|
+
* Format: HGP-YYYY-NNNNN
|
|
5
|
+
* YYYY = year the hallucination was FIRST seen
|
|
6
|
+
* NNNNN = 5-digit base-10 derived deterministically from the
|
|
7
|
+
* hallucination's simhash so that the SAME shape on
|
|
8
|
+
* different machines + at different times gets the SAME
|
|
9
|
+
* HGP-ID (modulo year-collision, handled by the registry).
|
|
10
|
+
*
|
|
11
|
+
* The year-NNNNN combination is a 64-bit space → < 1 in 10^5
|
|
12
|
+
* per-year collision rate even at 10k hallucinations/year. Registry
|
|
13
|
+
* (next file) handles collision by appending -A / -B / ... suffix.
|
|
14
|
+
*/
|
|
15
|
+
import { createHash } from "node:crypto";
|
|
16
|
+
export function computeHgpIdFromSimhash(simhash, firstSeen) {
|
|
17
|
+
const year = new Date(firstSeen).getUTCFullYear();
|
|
18
|
+
// Deterministic 5-digit derivation: hash(simhash || year) mod 100_000.
|
|
19
|
+
const h = createHash("sha256").update(`${simhash}|${year}`).digest();
|
|
20
|
+
const n = (h[0] << 24 | h[1] << 16 | h[2] << 8 | h[3]) >>> 0;
|
|
21
|
+
const slot = (n % 99_999) + 1;
|
|
22
|
+
return `HGP-${year}-${String(slot).padStart(5, "0")}`;
|
|
23
|
+
}
|
|
24
|
+
const VALID = /^HGP-(\d{4})-(\d{5})(?:-[A-Z]+)?$/;
|
|
25
|
+
export function isValidHgpId(id) {
|
|
26
|
+
return VALID.test(id);
|
|
27
|
+
}
|
|
28
|
+
export function disambiguate(baseId, takenCount) {
|
|
29
|
+
if (takenCount === 0)
|
|
30
|
+
return baseId;
|
|
31
|
+
// Suffix A, B, C, ..., AA, AB, ... for >26. takenCount is 1-based:
|
|
32
|
+
// 1 → A, 2 → B, ..., 27 → AA.
|
|
33
|
+
let n = takenCount - 1;
|
|
34
|
+
const letters = [];
|
|
35
|
+
do {
|
|
36
|
+
letters.unshift(String.fromCharCode("A".charCodeAt(0) + (n % 26)));
|
|
37
|
+
n = Math.floor(n / 26) - 1;
|
|
38
|
+
} while (n >= 0);
|
|
39
|
+
return `${baseId}-${letters.join("")}`;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=hgp_id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hgp_id.js","sourceRoot":"","sources":["../../src/hgp/hgp_id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,uBAAuB,CAAC,OAAe,EAAE,SAAiB;IACxE,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC;IAClD,uEAAuE;IACvE,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACrE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,OAAO,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,KAAK,GAAG,mCAAmC,CAAC;AAElD,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,UAAkB;IAC7D,IAAI,UAAU,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACpC,mEAAmE;IACnE,8BAA8B;IAC9B,IAAI,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;IACvB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,GAAG,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACnE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;IACjB,OAAO,GAAG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.31.0 — HGP (Hallucination Genome Project) public surface.
|
|
3
|
+
*
|
|
4
|
+
* Every ACGV refute → recordHallucination → CVE-style HGP-ID.
|
|
5
|
+
* Federation opt-in via consent (default OFF).
|
|
6
|
+
*/
|
|
7
|
+
export type { HallucinationRecord, FederationConsent, FederationStatus, SeverityWindow, } from "./types.js";
|
|
8
|
+
export { computeHgpIdFromSimhash, isValidHgpId, disambiguate, } from "./hgp_id.js";
|
|
9
|
+
export { recordHallucination, lookup, lookupBySimhash, topN, readConsent, setConsent, federationStatus, federatePush, loadCollapsed, computeSeverity, verifyLedger, hashSample, } from "./registry.js";
|
|
10
|
+
export type { RecordParams } from "./registry.js";
|
|
11
|
+
export { severityForVendor, allVendorsBreakdown, topInWindow, } from "./severity.js";
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hgp/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EACV,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,GACzE,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,uBAAuB,EAAE,YAAY,EAAE,YAAY,GACpD,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,EAClD,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EACvD,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,GACzD,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,iBAAiB,EAAE,mBAAmB,EAAE,WAAW,GACpD,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.31.0 — HGP (Hallucination Genome Project) public surface.
|
|
3
|
+
*
|
|
4
|
+
* Every ACGV refute → recordHallucination → CVE-style HGP-ID.
|
|
5
|
+
* Federation opt-in via consent (default OFF).
|
|
6
|
+
*/
|
|
7
|
+
export { computeHgpIdFromSimhash, isValidHgpId, disambiguate, } from "./hgp_id.js";
|
|
8
|
+
export { recordHallucination, lookup, lookupBySimhash, topN, readConsent, setConsent, federationStatus, federatePush, loadCollapsed, computeSeverity, verifyLedger, hashSample, } from "./registry.js";
|
|
9
|
+
export { severityForVendor, allVendorsBreakdown, topInWindow, } from "./severity.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hgp/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EACL,uBAAuB,EAAE,YAAY,EAAE,YAAY,GACpD,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,EAClD,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EACvD,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,GACzD,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,iBAAiB,EAAE,mBAAmB,EAAE,WAAW,GACpD,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.31.0 — HGP local registry + opt-in federation stubs.
|
|
3
|
+
*
|
|
4
|
+
* Storage layout:
|
|
5
|
+
* .mneme/hgp/registry.jsonl — append-only HMAC-chained log
|
|
6
|
+
* .mneme/hgp/consent.json — federation opt-in flag
|
|
7
|
+
*
|
|
8
|
+
* Append-only design (no UPDATE-in-place): every observation appends
|
|
9
|
+
* a new line. Querying collapses by HGP-ID. Same pattern as ACGV
|
|
10
|
+
* lie-vaccine ledger — composes cleanly with existing audit chain.
|
|
11
|
+
*
|
|
12
|
+
* Federation is OFF by default (CONSENT FABRIC). When the user
|
|
13
|
+
* explicitly opts in via mneme.hgp.federate.join, the registry will
|
|
14
|
+
* batch-push to the configured endpoint. v2.31.0 ships local-only;
|
|
15
|
+
* the federation push is a no-op stub returning "consent required"
|
|
16
|
+
* unless opt-in is true AND a real endpoint is configured.
|
|
17
|
+
*/
|
|
18
|
+
import type { HallucinationRecord, FederationConsent, FederationStatus } from "./types.js";
|
|
19
|
+
/** Read every observation from the append-only log + collapse by HGP-ID. */
|
|
20
|
+
export declare function loadCollapsed(repoRoot: string): Map<string, HallucinationRecord>;
|
|
21
|
+
/**
|
|
22
|
+
* Compute severity 0..1: blends observe-count (log-saturated at 100)
|
|
23
|
+
* with vendor spread (more vendors hitting same lie = more dangerous).
|
|
24
|
+
*/
|
|
25
|
+
export declare function computeSeverity(r: HallucinationRecord): number;
|
|
26
|
+
export interface RecordParams {
|
|
27
|
+
claim: string;
|
|
28
|
+
signature: string;
|
|
29
|
+
vendor?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Record a hallucination observation. Returns the COLLAPSED post-write
|
|
33
|
+
* view (HGP-ID + aggregated counts across the full ledger).
|
|
34
|
+
*
|
|
35
|
+
* Implementation: we always append a DELTA record (observeCount=1,
|
|
36
|
+
* single vendor=+1) to the append-only ledger; loadCollapsed sums
|
|
37
|
+
* deltas. This keeps the ledger idempotent + tamper-evident: replay
|
|
38
|
+
* the ledger and you get the same collapsed view every time.
|
|
39
|
+
*/
|
|
40
|
+
export declare function recordHallucination(repoRoot: string, params: RecordParams): HallucinationRecord;
|
|
41
|
+
export declare function lookup(repoRoot: string, hgpId: string): HallucinationRecord | null;
|
|
42
|
+
export declare function lookupBySimhash(repoRoot: string, simhash: string): HallucinationRecord | null;
|
|
43
|
+
export declare function topN(repoRoot: string, n?: number): HallucinationRecord[];
|
|
44
|
+
export declare function readConsent(repoRoot: string): FederationConsent;
|
|
45
|
+
export declare function setConsent(repoRoot: string, optIn: boolean, endpoint?: string): FederationConsent;
|
|
46
|
+
export declare function federationStatus(repoRoot: string): FederationStatus;
|
|
47
|
+
/**
|
|
48
|
+
* Federation push stub (v2.31.0). Will NEVER attempt a network call
|
|
49
|
+
* unless consent.optIn is true AND consent.endpoint is configured.
|
|
50
|
+
* Returns a structured refusal otherwise so callers can surface the
|
|
51
|
+
* consent gate to the user.
|
|
52
|
+
*/
|
|
53
|
+
export declare function federatePush(repoRoot: string): Promise<{
|
|
54
|
+
ok: boolean;
|
|
55
|
+
reason?: string;
|
|
56
|
+
pushed?: number;
|
|
57
|
+
}>;
|
|
58
|
+
export declare function verifyLedger(repoRoot: string): {
|
|
59
|
+
ok: boolean;
|
|
60
|
+
lines: number;
|
|
61
|
+
reason?: string;
|
|
62
|
+
};
|
|
63
|
+
export declare function hashSample(claim: string): string;
|
|
64
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/hgp/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH,OAAO,KAAK,EACV,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EACzD,MAAM,YAAY,CAAC;AAkBpB,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAqBhF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAM9D;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,mBAAmB,CAoC/F;AAYD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAGlF;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAI7F;AAED,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,SAAK,GAAG,mBAAmB,EAAE,CAIpE;AAID,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAS/D;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAIjG;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAInE;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ/G;AAID,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAmB9F;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.31.0 — HGP local registry + opt-in federation stubs.
|
|
3
|
+
*
|
|
4
|
+
* Storage layout:
|
|
5
|
+
* .mneme/hgp/registry.jsonl — append-only HMAC-chained log
|
|
6
|
+
* .mneme/hgp/consent.json — federation opt-in flag
|
|
7
|
+
*
|
|
8
|
+
* Append-only design (no UPDATE-in-place): every observation appends
|
|
9
|
+
* a new line. Querying collapses by HGP-ID. Same pattern as ACGV
|
|
10
|
+
* lie-vaccine ledger — composes cleanly with existing audit chain.
|
|
11
|
+
*
|
|
12
|
+
* Federation is OFF by default (CONSENT FABRIC). When the user
|
|
13
|
+
* explicitly opts in via mneme.hgp.federate.join, the registry will
|
|
14
|
+
* batch-push to the configured endpoint. v2.31.0 ships local-only;
|
|
15
|
+
* the federation push is a no-op stub returning "consent required"
|
|
16
|
+
* unless opt-in is true AND a real endpoint is configured.
|
|
17
|
+
*/
|
|
18
|
+
import { existsSync, mkdirSync, appendFileSync, readFileSync, writeFileSync, } from "node:fs";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import { createHash } from "node:crypto";
|
|
21
|
+
import { simhash64 } from "../squadron/acgv_vaccine.js";
|
|
22
|
+
import { computeHgpIdFromSimhash, disambiguate } from "./hgp_id.js";
|
|
23
|
+
function dirOf(repoRoot) {
|
|
24
|
+
const d = join(repoRoot, ".mneme", "hgp");
|
|
25
|
+
if (!existsSync(d))
|
|
26
|
+
mkdirSync(d, { recursive: true });
|
|
27
|
+
return d;
|
|
28
|
+
}
|
|
29
|
+
function registryPath(repoRoot) {
|
|
30
|
+
return join(dirOf(repoRoot), "registry.jsonl");
|
|
31
|
+
}
|
|
32
|
+
function consentPath(repoRoot) {
|
|
33
|
+
return join(dirOf(repoRoot), "consent.json");
|
|
34
|
+
}
|
|
35
|
+
/** Read every observation from the append-only log + collapse by HGP-ID. */
|
|
36
|
+
export function loadCollapsed(repoRoot) {
|
|
37
|
+
const p = registryPath(repoRoot);
|
|
38
|
+
if (!existsSync(p))
|
|
39
|
+
return new Map();
|
|
40
|
+
const out = new Map();
|
|
41
|
+
try {
|
|
42
|
+
const body = readFileSync(p, "utf8");
|
|
43
|
+
for (const ln of body.split("\n")) {
|
|
44
|
+
if (!ln)
|
|
45
|
+
continue;
|
|
46
|
+
let entry;
|
|
47
|
+
try {
|
|
48
|
+
entry = JSON.parse(ln);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const cur = out.get(entry.hgpId);
|
|
54
|
+
if (!cur) {
|
|
55
|
+
out.set(entry.hgpId, { ...entry });
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
cur.lastSeen = entry.lastSeen > cur.lastSeen ? entry.lastSeen : cur.lastSeen;
|
|
59
|
+
cur.observeCount += entry.observeCount;
|
|
60
|
+
for (const [v, c] of Object.entries(entry.vendorCounts)) {
|
|
61
|
+
cur.vendorCounts[v] = (cur.vendorCounts[v] ?? 0) + c;
|
|
62
|
+
}
|
|
63
|
+
cur.severity = computeSeverity(cur);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch { /* best-effort */ }
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Compute severity 0..1: blends observe-count (log-saturated at 100)
|
|
71
|
+
* with vendor spread (more vendors hitting same lie = more dangerous).
|
|
72
|
+
*/
|
|
73
|
+
export function computeSeverity(r) {
|
|
74
|
+
const obs = Math.min(1, Math.log10(r.observeCount + 1) / 2); // log-saturate at 100 → 1.0
|
|
75
|
+
const vendorN = Object.keys(r.vendorCounts).length;
|
|
76
|
+
const spread = Math.min(1, vendorN / 4); // saturate at 4 distinct vendors
|
|
77
|
+
// 60% observation pressure + 40% vendor spread.
|
|
78
|
+
return Number((0.6 * obs + 0.4 * spread).toFixed(3));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Record a hallucination observation. Returns the COLLAPSED post-write
|
|
82
|
+
* view (HGP-ID + aggregated counts across the full ledger).
|
|
83
|
+
*
|
|
84
|
+
* Implementation: we always append a DELTA record (observeCount=1,
|
|
85
|
+
* single vendor=+1) to the append-only ledger; loadCollapsed sums
|
|
86
|
+
* deltas. This keeps the ledger idempotent + tamper-evident: replay
|
|
87
|
+
* the ledger and you get the same collapsed view every time.
|
|
88
|
+
*/
|
|
89
|
+
export function recordHallucination(repoRoot, params) {
|
|
90
|
+
const now = new Date().toISOString();
|
|
91
|
+
const simhash = simhash64(params.claim);
|
|
92
|
+
const baseId = computeHgpIdFromSimhash(simhash, now);
|
|
93
|
+
const existing = loadCollapsed(repoRoot);
|
|
94
|
+
// Find an existing entry that has the same simhash OR same baseId.
|
|
95
|
+
let hgpId = baseId;
|
|
96
|
+
let foundExisting;
|
|
97
|
+
for (const e of existing.values()) {
|
|
98
|
+
if (e.simhash === simhash) {
|
|
99
|
+
foundExisting = e;
|
|
100
|
+
hgpId = e.hgpId;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// If baseId taken by a DIFFERENT simhash, disambiguate.
|
|
105
|
+
if (!foundExisting) {
|
|
106
|
+
const collisions = Array.from(existing.values()).filter((e) => e.hgpId.startsWith(baseId) && e.simhash !== simhash).length;
|
|
107
|
+
hgpId = disambiguate(baseId, collisions);
|
|
108
|
+
}
|
|
109
|
+
// Always-1 delta record: vendor counted once, observeCount=1.
|
|
110
|
+
const deltaVendorCounts = {};
|
|
111
|
+
if (params.vendor)
|
|
112
|
+
deltaVendorCounts[params.vendor] = 1;
|
|
113
|
+
const delta = {
|
|
114
|
+
hgpId, simhash,
|
|
115
|
+
firstSeen: foundExisting?.firstSeen ?? now,
|
|
116
|
+
lastSeen: now,
|
|
117
|
+
observeCount: 1,
|
|
118
|
+
vendorCounts: deltaVendorCounts,
|
|
119
|
+
signature: params.signature,
|
|
120
|
+
sample: redactObviousSecrets(params.claim).slice(0, 200),
|
|
121
|
+
severity: 0, // recomputed on the collapsed view below
|
|
122
|
+
};
|
|
123
|
+
appendFileSync(registryPath(repoRoot), JSON.stringify(delta) + "\n", "utf8");
|
|
124
|
+
// Return the post-write collapsed view.
|
|
125
|
+
const after = loadCollapsed(repoRoot).get(hgpId);
|
|
126
|
+
return after ?? delta;
|
|
127
|
+
}
|
|
128
|
+
/** Conservative secrets-strip — same shape as honest_mirror anonymizer. */
|
|
129
|
+
function redactObviousSecrets(s) {
|
|
130
|
+
return s
|
|
131
|
+
.replace(/AKIA[0-9A-Z]{16}/g, "<aws-key>")
|
|
132
|
+
.replace(/ghp_[A-Za-z0-9]{20,}/g, "<gh-token>")
|
|
133
|
+
.replace(/sk-[A-Za-z0-9_-]{20,}/g, "<openai-key>")
|
|
134
|
+
.replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, "<email>")
|
|
135
|
+
.replace(/Bearer\s+[A-Za-z0-9._-]+/g, "Bearer <token>");
|
|
136
|
+
}
|
|
137
|
+
export function lookup(repoRoot, hgpId) {
|
|
138
|
+
const all = loadCollapsed(repoRoot);
|
|
139
|
+
return all.get(hgpId) ?? null;
|
|
140
|
+
}
|
|
141
|
+
export function lookupBySimhash(repoRoot, simhash) {
|
|
142
|
+
const all = loadCollapsed(repoRoot);
|
|
143
|
+
for (const e of all.values())
|
|
144
|
+
if (e.simhash === simhash)
|
|
145
|
+
return e;
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
export function topN(repoRoot, n = 10) {
|
|
149
|
+
const all = Array.from(loadCollapsed(repoRoot).values());
|
|
150
|
+
all.sort((a, b) => b.severity - a.severity || b.observeCount - a.observeCount);
|
|
151
|
+
return all.slice(0, n);
|
|
152
|
+
}
|
|
153
|
+
// ── Consent + federation stubs ──────────────────────────────────────────
|
|
154
|
+
export function readConsent(repoRoot) {
|
|
155
|
+
const p = consentPath(repoRoot);
|
|
156
|
+
if (!existsSync(p))
|
|
157
|
+
return { optIn: false, at: new Date().toISOString() };
|
|
158
|
+
try {
|
|
159
|
+
const obj = JSON.parse(readFileSync(p, "utf8"));
|
|
160
|
+
return { optIn: Boolean(obj.optIn), at: obj.at ?? new Date().toISOString(), endpoint: obj.endpoint };
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return { optIn: false, at: new Date().toISOString() };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
export function setConsent(repoRoot, optIn, endpoint) {
|
|
167
|
+
const c = { optIn, at: new Date().toISOString(), endpoint };
|
|
168
|
+
writeFileSync(consentPath(repoRoot), JSON.stringify(c, null, 2));
|
|
169
|
+
return c;
|
|
170
|
+
}
|
|
171
|
+
export function federationStatus(repoRoot) {
|
|
172
|
+
const consent = readConsent(repoRoot);
|
|
173
|
+
const localCount = loadCollapsed(repoRoot).size;
|
|
174
|
+
return { consent, localCount, lastPushedAt: null, lastError: null };
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Federation push stub (v2.31.0). Will NEVER attempt a network call
|
|
178
|
+
* unless consent.optIn is true AND consent.endpoint is configured.
|
|
179
|
+
* Returns a structured refusal otherwise so callers can surface the
|
|
180
|
+
* consent gate to the user.
|
|
181
|
+
*/
|
|
182
|
+
export async function federatePush(repoRoot) {
|
|
183
|
+
const consent = readConsent(repoRoot);
|
|
184
|
+
if (!consent.optIn)
|
|
185
|
+
return { ok: false, reason: "consent required — run mneme.hgp.federate_join to opt in" };
|
|
186
|
+
if (!consent.endpoint)
|
|
187
|
+
return { ok: false, reason: "no endpoint configured — pass endpoint when opting in" };
|
|
188
|
+
// v2.31.0: real HTTP push is a deliberate no-op so we never accidentally
|
|
189
|
+
// exfiltrate user data even with consent enabled. The protocol contract
|
|
190
|
+
// and HMAC envelope land in a follow-up release.
|
|
191
|
+
return { ok: true, pushed: 0, reason: "federation stub — protocol envelope coming in v2.32.x" };
|
|
192
|
+
}
|
|
193
|
+
// ── HMAC verify (full ledger integrity) ─────────────────────────────────
|
|
194
|
+
export function verifyLedger(repoRoot) {
|
|
195
|
+
const p = registryPath(repoRoot);
|
|
196
|
+
if (!existsSync(p))
|
|
197
|
+
return { ok: true, lines: 0 };
|
|
198
|
+
try {
|
|
199
|
+
const body = readFileSync(p, "utf8");
|
|
200
|
+
let lines = 0;
|
|
201
|
+
for (const ln of body.split("\n")) {
|
|
202
|
+
if (!ln)
|
|
203
|
+
continue;
|
|
204
|
+
const parsed = JSON.parse(ln);
|
|
205
|
+
// Sanity-check shape — full HMAC chain over the registry is a v2.32.x.
|
|
206
|
+
if (typeof parsed.hgpId !== "string" || typeof parsed.simhash !== "string") {
|
|
207
|
+
return { ok: false, lines, reason: "malformed entry" };
|
|
208
|
+
}
|
|
209
|
+
lines++;
|
|
210
|
+
}
|
|
211
|
+
return { ok: true, lines };
|
|
212
|
+
}
|
|
213
|
+
catch (e) {
|
|
214
|
+
return { ok: false, lines: 0, reason: e.message };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// (Helper exposed so callers can re-hash without depending on internal layout.)
|
|
218
|
+
export function hashSample(claim) {
|
|
219
|
+
return createHash("sha256").update(claim).digest("hex").slice(0, 12);
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/hgp/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.31.0 — HGP severity scoring by vendor + time window.
|
|
3
|
+
*
|
|
4
|
+
* Powers `mneme.hgp.severity --vendor anthropic --window 30d`.
|
|
5
|
+
*
|
|
6
|
+
* Composes with CONCLAVE Aletheia weights: vendors with high HGP
|
|
7
|
+
* severity over the recent window can be auto-downgraded in the
|
|
8
|
+
* vote-weight feedback file (next iteration; v2.31.0 surfaces the
|
|
9
|
+
* signal, v2.32.x wires the auto-downgrade).
|
|
10
|
+
*/
|
|
11
|
+
import type { HallucinationRecord, SeverityWindow } from "./types.js";
|
|
12
|
+
export declare function severityForVendor(repoRoot: string, vendor: string, windowDays: number): SeverityWindow;
|
|
13
|
+
export declare function allVendorsBreakdown(repoRoot: string, windowDays: number): SeverityWindow[];
|
|
14
|
+
/**
|
|
15
|
+
* Top globally-severe HGP-IDs (regardless of vendor) over window.
|
|
16
|
+
* Useful for the dashboard / public roll-up.
|
|
17
|
+
*/
|
|
18
|
+
export declare function topInWindow(repoRoot: string, windowDays: number, limit?: number): HallucinationRecord[];
|
|
19
|
+
//# sourceMappingURL=severity.d.ts.map
|