@mneme-ai/core 1.99.0 → 2.0.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/bloodline/bloodline.test.d.ts +2 -0
- package/dist/bloodline/bloodline.test.d.ts.map +1 -0
- package/dist/bloodline/bloodline.test.js +96 -0
- package/dist/bloodline/bloodline.test.js.map +1 -0
- package/dist/bloodline/index.d.ts +124 -0
- package/dist/bloodline/index.d.ts.map +1 -0
- package/dist/bloodline/index.js +179 -0
- package/dist/bloodline/index.js.map +1 -0
- package/dist/dream/dream.test.d.ts +2 -0
- package/dist/dream/dream.test.d.ts.map +1 -0
- package/dist/dream/dream.test.js +61 -0
- package/dist/dream/dream.test.js.map +1 -0
- package/dist/dream/index.d.ts +59 -0
- package/dist/dream/index.d.ts.map +1 -0
- package/dist/dream/index.js +117 -0
- package/dist/dream/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/mutiny/index.d.ts +55 -0
- package/dist/mutiny/index.d.ts.map +1 -0
- package/dist/mutiny/index.js +67 -0
- package/dist/mutiny/index.js.map +1 -0
- package/dist/mutiny/mutiny.test.d.ts +2 -0
- package/dist/mutiny/mutiny.test.d.ts.map +1 -0
- package/dist/mutiny/mutiny.test.js +59 -0
- package/dist/mutiny/mutiny.test.js.map +1 -0
- package/dist/prophecy/index.d.ts +88 -0
- package/dist/prophecy/index.d.ts.map +1 -0
- package/dist/prophecy/index.js +94 -0
- package/dist/prophecy/index.js.map +1 -0
- package/dist/prophecy/prophecy.test.d.ts +2 -0
- package/dist/prophecy/prophecy.test.d.ts.map +1 -0
- package/dist/prophecy/prophecy.test.js +112 -0
- package/dist/prophecy/prophecy.test.js.map +1 -0
- package/dist/xray/index.d.ts +44 -0
- package/dist/xray/index.d.ts.map +1 -0
- package/dist/xray/index.js +139 -0
- package/dist/xray/index.js.map +1 -0
- package/dist/xray/xray.test.d.ts +2 -0
- package/dist/xray/xray.test.d.ts.map +1 -0
- package/dist/xray/xray.test.js +57 -0
- package/dist/xray/xray.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.0.0 -- PROPHECY LETTERS · time-locked cross-version messages
|
|
3
|
+
*
|
|
4
|
+
* Mneme v2.0 writes a letter to its future self (or to a different
|
|
5
|
+
* machine running a different Mneme version). The letter is sealed
|
|
6
|
+
* with the user's HMAC secret + a target-version gate. When a future
|
|
7
|
+
* Mneme version that meets the gate opens the letter, it can grade
|
|
8
|
+
* its past self's predictions:
|
|
9
|
+
*
|
|
10
|
+
* "Past Mneme (v2.0, 2026-05-13) predicted: 'by v2.5 we'll have
|
|
11
|
+
* real IBM Quantum wiring.' Current Mneme (v2.5, 2026-09-01) checks
|
|
12
|
+
* its own state: TRUE. Time-consistency score updated."
|
|
13
|
+
*
|
|
14
|
+
* Pure function. Deterministic. Composable with PASSPORT + audit log.
|
|
15
|
+
*/
|
|
16
|
+
import { createHmac, createHash } from "node:crypto";
|
|
17
|
+
function fpSecret(secret) {
|
|
18
|
+
return createHash("sha256").update(secret).digest("hex").slice(0, 16);
|
|
19
|
+
}
|
|
20
|
+
function computeSig(p, secret) {
|
|
21
|
+
const h = createHmac("sha256", secret);
|
|
22
|
+
h.update([p.fromVersion, p.toMinVersion, p.sealedAt, p.earliestOpenAt, p.text, JSON.stringify(p.predictions)].join("|"));
|
|
23
|
+
return h.digest("hex");
|
|
24
|
+
}
|
|
25
|
+
export function sealProphecy(input) {
|
|
26
|
+
const sealedAt = Date.now();
|
|
27
|
+
const earliestOpenAt = input.earliestOpenAt ?? sealedAt + 30 * 24 * 60 * 60 * 1000;
|
|
28
|
+
const base = {
|
|
29
|
+
fromVersion: input.fromVersion,
|
|
30
|
+
toMinVersion: input.toMinVersion,
|
|
31
|
+
sealedAt,
|
|
32
|
+
earliestOpenAt,
|
|
33
|
+
text: input.text,
|
|
34
|
+
predictions: input.predictions,
|
|
35
|
+
};
|
|
36
|
+
const signature = computeSig(base, input.secret);
|
|
37
|
+
const id = createHash("sha256").update(`${input.fromVersion}|${sealedAt}|${signature.slice(0, 16)}`).digest("hex").slice(0, 12);
|
|
38
|
+
return { id, ...base, signature, keyFingerprint: fpSecret(input.secret) };
|
|
39
|
+
}
|
|
40
|
+
function semverGe(a, b) {
|
|
41
|
+
const pa = a.split(".").map((n) => parseInt(n, 10));
|
|
42
|
+
const pb = b.split(".").map((n) => parseInt(n, 10));
|
|
43
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
44
|
+
const ai = pa[i] ?? 0;
|
|
45
|
+
const bi = pb[i] ?? 0;
|
|
46
|
+
if (ai > bi)
|
|
47
|
+
return true;
|
|
48
|
+
if (ai < bi)
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
export function unsealProphecy(input) {
|
|
54
|
+
const now = input.now ?? Date.now();
|
|
55
|
+
if (fpSecret(input.secret) !== input.prophecy.keyFingerprint) {
|
|
56
|
+
return { verdict: "WRONG_KEY", reason: `secret fingerprint mismatch` };
|
|
57
|
+
}
|
|
58
|
+
if (!semverGe(input.currentVersion, input.prophecy.toMinVersion)) {
|
|
59
|
+
return { verdict: "SEALED", reason: `current version ${input.currentVersion} < required ${input.prophecy.toMinVersion}` };
|
|
60
|
+
}
|
|
61
|
+
if (now < input.prophecy.earliestOpenAt) {
|
|
62
|
+
return { verdict: "SEALED", reason: `time-lock not expired (open at ${new Date(input.prophecy.earliestOpenAt).toISOString()})` };
|
|
63
|
+
}
|
|
64
|
+
const { signature: _drop, id: _drop2, keyFingerprint: _drop3, ...rest } = input.prophecy;
|
|
65
|
+
void _drop;
|
|
66
|
+
void _drop2;
|
|
67
|
+
void _drop3;
|
|
68
|
+
const expected = computeSig(rest, input.secret);
|
|
69
|
+
if (expected !== input.prophecy.signature) {
|
|
70
|
+
return { verdict: "TAMPERED", reason: `signature mismatch` };
|
|
71
|
+
}
|
|
72
|
+
return { verdict: "OPENABLE", reason: "all checks pass", prophecy: input.prophecy };
|
|
73
|
+
}
|
|
74
|
+
export function gradeProphecy(input) {
|
|
75
|
+
const obsByTopic = new Map();
|
|
76
|
+
for (const o of input.observations)
|
|
77
|
+
obsByTopic.set(o.topic, o.cameTrue);
|
|
78
|
+
const byTopic = input.prophecy.predictions.map((p) => ({
|
|
79
|
+
topic: p.topic,
|
|
80
|
+
predicted: p.claim,
|
|
81
|
+
cameTrue: obsByTopic.get(p.topic) ?? false,
|
|
82
|
+
}));
|
|
83
|
+
const correct = byTopic.filter((b) => b.cameTrue).length;
|
|
84
|
+
return {
|
|
85
|
+
total: byTopic.length,
|
|
86
|
+
correct,
|
|
87
|
+
consistency: byTopic.length > 0 ? correct / byTopic.length : 0,
|
|
88
|
+
byTopic,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export function formatProphecyPulseLine(p) {
|
|
92
|
+
return `PROPHECY · ${p.id} · ${p.fromVersion}→${p.toMinVersion} · ${p.predictions.length} predictions`;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prophecy/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prophecy.test.d.ts","sourceRoot":"","sources":["../../src/prophecy/prophecy.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { sealProphecy, unsealProphecy, gradeProphecy, formatProphecyPulseLine } from "./index.js";
|
|
4
|
+
describe("v2.0 PROPHECY LETTERS · time-locked cross-version", () => {
|
|
5
|
+
const secret = randomBytes(32);
|
|
6
|
+
it("seal returns envelope with id + signature + keyFingerprint", () => {
|
|
7
|
+
const p = sealProphecy({
|
|
8
|
+
fromVersion: "2.0.0",
|
|
9
|
+
toMinVersion: "2.5.0",
|
|
10
|
+
text: "By v2.5 we'll have IBM Quantum wired.",
|
|
11
|
+
predictions: [{ topic: "ibm-quantum", claim: "wired by v2.5", verifyHint: "check qx_bridge providers.ts for runIbm impl" }],
|
|
12
|
+
secret,
|
|
13
|
+
});
|
|
14
|
+
expect(p.id).toMatch(/^[a-f0-9]{12}$/);
|
|
15
|
+
expect(p.signature.length).toBe(64);
|
|
16
|
+
expect(p.keyFingerprint).toBeTruthy();
|
|
17
|
+
});
|
|
18
|
+
it("SEALED verdict when current version < required", () => {
|
|
19
|
+
const p = sealProphecy({
|
|
20
|
+
fromVersion: "2.0.0",
|
|
21
|
+
toMinVersion: "2.5.0",
|
|
22
|
+
text: "x",
|
|
23
|
+
predictions: [],
|
|
24
|
+
secret,
|
|
25
|
+
earliestOpenAt: Date.now() - 1000, // time-lock already past
|
|
26
|
+
});
|
|
27
|
+
const r = unsealProphecy({ prophecy: p, currentVersion: "2.0.0", secret });
|
|
28
|
+
expect(r.verdict).toBe("SEALED");
|
|
29
|
+
expect(r.reason).toContain("version");
|
|
30
|
+
});
|
|
31
|
+
it("SEALED verdict when time-lock not yet expired", () => {
|
|
32
|
+
const p = sealProphecy({
|
|
33
|
+
fromVersion: "2.0.0",
|
|
34
|
+
toMinVersion: "2.0.0",
|
|
35
|
+
text: "x",
|
|
36
|
+
predictions: [],
|
|
37
|
+
secret,
|
|
38
|
+
earliestOpenAt: Date.now() + 1000 * 60 * 60,
|
|
39
|
+
});
|
|
40
|
+
const r = unsealProphecy({ prophecy: p, currentVersion: "2.5.0", secret });
|
|
41
|
+
expect(r.verdict).toBe("SEALED");
|
|
42
|
+
expect(r.reason).toContain("time-lock");
|
|
43
|
+
});
|
|
44
|
+
it("OPENABLE verdict when version AND time gate pass + signature valid", () => {
|
|
45
|
+
const p = sealProphecy({
|
|
46
|
+
fromVersion: "2.0.0",
|
|
47
|
+
toMinVersion: "2.0.0",
|
|
48
|
+
text: "x",
|
|
49
|
+
predictions: [],
|
|
50
|
+
secret,
|
|
51
|
+
earliestOpenAt: Date.now() - 1000,
|
|
52
|
+
});
|
|
53
|
+
const r = unsealProphecy({ prophecy: p, currentVersion: "2.5.0", secret });
|
|
54
|
+
expect(r.verdict).toBe("OPENABLE");
|
|
55
|
+
expect(r.prophecy).toBeDefined();
|
|
56
|
+
});
|
|
57
|
+
it("TAMPERED verdict when signature was forged", () => {
|
|
58
|
+
const p = sealProphecy({
|
|
59
|
+
fromVersion: "2.0.0",
|
|
60
|
+
toMinVersion: "2.0.0",
|
|
61
|
+
text: "x",
|
|
62
|
+
predictions: [],
|
|
63
|
+
secret,
|
|
64
|
+
earliestOpenAt: Date.now() - 1000,
|
|
65
|
+
});
|
|
66
|
+
p.signature = "0".repeat(64);
|
|
67
|
+
const r = unsealProphecy({ prophecy: p, currentVersion: "2.5.0", secret });
|
|
68
|
+
expect(r.verdict).toBe("TAMPERED");
|
|
69
|
+
});
|
|
70
|
+
it("WRONG_KEY verdict on wrong secret", () => {
|
|
71
|
+
const p = sealProphecy({
|
|
72
|
+
fromVersion: "2.0.0",
|
|
73
|
+
toMinVersion: "2.0.0",
|
|
74
|
+
text: "x",
|
|
75
|
+
predictions: [],
|
|
76
|
+
secret,
|
|
77
|
+
earliestOpenAt: Date.now() - 1000,
|
|
78
|
+
});
|
|
79
|
+
const wrong = randomBytes(32);
|
|
80
|
+
const r = unsealProphecy({ prophecy: p, currentVersion: "2.5.0", secret: wrong });
|
|
81
|
+
expect(r.verdict).toBe("WRONG_KEY");
|
|
82
|
+
});
|
|
83
|
+
it("gradeProphecy computes consistency 0..1", () => {
|
|
84
|
+
const p = sealProphecy({
|
|
85
|
+
fromVersion: "2.0.0",
|
|
86
|
+
toMinVersion: "2.5.0",
|
|
87
|
+
text: "x",
|
|
88
|
+
predictions: [
|
|
89
|
+
{ topic: "ibm-quantum", claim: "wired", verifyHint: "" },
|
|
90
|
+
{ topic: "dwave-qubo", claim: "wired", verifyHint: "" },
|
|
91
|
+
{ topic: "ggwave-audio", claim: "shipped", verifyHint: "" },
|
|
92
|
+
],
|
|
93
|
+
secret,
|
|
94
|
+
});
|
|
95
|
+
const r = gradeProphecy({
|
|
96
|
+
prophecy: p,
|
|
97
|
+
observations: [
|
|
98
|
+
{ topic: "ibm-quantum", cameTrue: true },
|
|
99
|
+
{ topic: "dwave-qubo", cameTrue: false },
|
|
100
|
+
{ topic: "ggwave-audio", cameTrue: true },
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
expect(r.total).toBe(3);
|
|
104
|
+
expect(r.correct).toBe(2);
|
|
105
|
+
expect(r.consistency).toBeCloseTo(2 / 3, 3);
|
|
106
|
+
});
|
|
107
|
+
it("formatProphecyPulseLine produces compact summary", () => {
|
|
108
|
+
const p = sealProphecy({ fromVersion: "2.0.0", toMinVersion: "2.5.0", text: "x", predictions: [], secret });
|
|
109
|
+
expect(formatProphecyPulseLine(p)).toContain("PROPHECY");
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=prophecy.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prophecy.test.js","sourceRoot":"","sources":["../../src/prophecy/prophecy.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.0.0 -- X-RAY of AI's own reasoning
|
|
3
|
+
*
|
|
4
|
+
* AI answers with confident prose. User believes it. But the prose
|
|
5
|
+
* itself often contains TELLS: hedge density, absolute claims without
|
|
6
|
+
* citation, contradictions, hand-waving. X-RAY scans the AI's reply
|
|
7
|
+
* BEFORE the user sees it and reports the structural confidence.
|
|
8
|
+
*
|
|
9
|
+
* Output is composable with FLASH (v1.99): X-RAY = surface-text audit,
|
|
10
|
+
* FLASH = source-grounded audit. Together = double check.
|
|
11
|
+
*
|
|
12
|
+
* Pure function. Regex-only. No LLM in the hot path.
|
|
13
|
+
*/
|
|
14
|
+
export interface XrayResult {
|
|
15
|
+
/** Token estimate of the response. */
|
|
16
|
+
tokens: number;
|
|
17
|
+
/** Hedge phrases (maybe, possibly, I think, ...). */
|
|
18
|
+
hedges: string[];
|
|
19
|
+
hedgeRatio: number;
|
|
20
|
+
/** Absolute phrases (always, never, definitely, ...). */
|
|
21
|
+
absolutes: string[];
|
|
22
|
+
absoluteRatio: number;
|
|
23
|
+
/** Citation candidates (commit SHAs, file paths, URLs). */
|
|
24
|
+
citations: string[];
|
|
25
|
+
citationDensity: number;
|
|
26
|
+
/** Pairs of phrases that contradict each other within the same reply. */
|
|
27
|
+
contradictions: Array<{
|
|
28
|
+
a: string;
|
|
29
|
+
b: string;
|
|
30
|
+
}>;
|
|
31
|
+
/** Long-prose-no-citation streaks (potential hand-waving). */
|
|
32
|
+
handWaveStreaks: number;
|
|
33
|
+
/** Final structural confidence 0..1. */
|
|
34
|
+
structuralConfidence: number;
|
|
35
|
+
/** Verdict bucket. */
|
|
36
|
+
verdict: "HIGH" | "MIXED" | "LOW" | "WEAK";
|
|
37
|
+
/** Top weak spots to highlight. */
|
|
38
|
+
weakSpots: string[];
|
|
39
|
+
}
|
|
40
|
+
/** Run the X-ray scan on an AI's response text. Returns structural
|
|
41
|
+
* confidence + weak spots. */
|
|
42
|
+
export declare function xrayResponse(text: string): XrayResult;
|
|
43
|
+
export declare function formatXrayPulseLine(r: XrayResult): string;
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/xray/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,cAAc,EAAE,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,8DAA8D;IAC9D,eAAe,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB;IACtB,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IAC3C,mCAAmC;IACnC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAkDD;+BAC+B;AAC/B,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAsErD;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.0.0 -- X-RAY of AI's own reasoning
|
|
3
|
+
*
|
|
4
|
+
* AI answers with confident prose. User believes it. But the prose
|
|
5
|
+
* itself often contains TELLS: hedge density, absolute claims without
|
|
6
|
+
* citation, contradictions, hand-waving. X-RAY scans the AI's reply
|
|
7
|
+
* BEFORE the user sees it and reports the structural confidence.
|
|
8
|
+
*
|
|
9
|
+
* Output is composable with FLASH (v1.99): X-RAY = surface-text audit,
|
|
10
|
+
* FLASH = source-grounded audit. Together = double check.
|
|
11
|
+
*
|
|
12
|
+
* Pure function. Regex-only. No LLM in the hot path.
|
|
13
|
+
*/
|
|
14
|
+
const HEDGE_PATTERNS = [
|
|
15
|
+
/\bmaybe\b/gi, /\bperhaps\b/gi, /\bpossibly\b/gi, /\bpotentially\b/gi,
|
|
16
|
+
/\bI think\b/gi, /\bI believe\b/gi, /\bI guess\b/gi, /\bseem(s?|ed)\b/gi,
|
|
17
|
+
/\b(might|may|could)\b/gi, /\bappears? to\b/gi, /\barguably\b/gi,
|
|
18
|
+
/\bsort of\b/gi, /\bkind of\b/gi, /\bgenerally\b/gi, /\btypically\b/gi,
|
|
19
|
+
];
|
|
20
|
+
const ABSOLUTE_PATTERNS = [
|
|
21
|
+
/\balways\b/gi, /\bnever\b/gi, /\bdefinitely\b/gi, /\bcertainly\b/gi,
|
|
22
|
+
/\babsolutely\b/gi, /\bguaranteed\b/gi, /\bimpossible\b/gi,
|
|
23
|
+
/\bcompletely\b/gi, /\bentirely\b/gi, /\bperfectly\b/gi,
|
|
24
|
+
/\bno (way|doubt)\b/gi, /\b100\s*%\b/gi,
|
|
25
|
+
];
|
|
26
|
+
const CITATION_PATTERNS = [
|
|
27
|
+
/\bcommit\s+[a-f0-9]{7,40}\b/gi,
|
|
28
|
+
/\b[a-f0-9]{7,12}\b/g, // bare SHAs
|
|
29
|
+
/\b[A-Za-z0-9_./-]+\.(ts|tsx|js|jsx|py|go|rs|java|md|json|yaml|yml|toml|sh)\b/g,
|
|
30
|
+
/https?:\/\/[^\s)]+/g,
|
|
31
|
+
/\bPR\s*#\d+\b/gi,
|
|
32
|
+
/\bissue\s*#\d+\b/gi,
|
|
33
|
+
];
|
|
34
|
+
const CONTRADICTION_PAIRS = [
|
|
35
|
+
[/\bsafe\b/i, /\bunsafe\b/i],
|
|
36
|
+
[/\brecommend\b/i, /\bdiscourage\b/i],
|
|
37
|
+
[/\balways\b/i, /\bnever\b/i],
|
|
38
|
+
[/\bsupports?\b/i, /\bdoes not support\b/i],
|
|
39
|
+
[/\brequires?\b/i, /\bdoes not require\b/i],
|
|
40
|
+
[/\bworks?\b/i, /\bdoes not work\b/i],
|
|
41
|
+
[/\bavailable\b/i, /\bunavailable\b/i],
|
|
42
|
+
];
|
|
43
|
+
function sentencesOf(text) {
|
|
44
|
+
return text.split(/(?<=[.!?])\s+/).filter((s) => s.trim().length > 0);
|
|
45
|
+
}
|
|
46
|
+
function findAll(text, patterns) {
|
|
47
|
+
const out = [];
|
|
48
|
+
for (const p of patterns) {
|
|
49
|
+
// Reset stateful regex
|
|
50
|
+
const re = new RegExp(p.source, p.flags);
|
|
51
|
+
const m = text.match(re);
|
|
52
|
+
if (m)
|
|
53
|
+
for (const hit of m)
|
|
54
|
+
out.push(hit);
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
/** Run the X-ray scan on an AI's response text. Returns structural
|
|
59
|
+
* confidence + weak spots. */
|
|
60
|
+
export function xrayResponse(text) {
|
|
61
|
+
const tokens = Math.ceil(text.length / 3.5);
|
|
62
|
+
const sentences = sentencesOf(text);
|
|
63
|
+
const sentenceCount = Math.max(1, sentences.length);
|
|
64
|
+
const hedges = findAll(text, HEDGE_PATTERNS);
|
|
65
|
+
const absolutes = findAll(text, ABSOLUTE_PATTERNS);
|
|
66
|
+
const citations = findAll(text, CITATION_PATTERNS);
|
|
67
|
+
const hedgeRatio = hedges.length / sentenceCount;
|
|
68
|
+
const absoluteRatio = absolutes.length / sentenceCount;
|
|
69
|
+
const citationDensity = (citations.length / Math.max(1, tokens)) * 100;
|
|
70
|
+
// Find contradictions: scan sentence pairs
|
|
71
|
+
const contradictions = [];
|
|
72
|
+
for (let i = 0; i < sentences.length; i++) {
|
|
73
|
+
for (let j = i + 1; j < sentences.length; j++) {
|
|
74
|
+
for (const [a, b] of CONTRADICTION_PAIRS) {
|
|
75
|
+
if (a.test(sentences[i]) && b.test(sentences[j])) {
|
|
76
|
+
contradictions.push({ a: sentences[i].slice(0, 80), b: sentences[j].slice(0, 80) });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Hand-wave streaks: count sentences with NO citation
|
|
82
|
+
let handWaveStreak = 0;
|
|
83
|
+
let maxHandWave = 0;
|
|
84
|
+
for (const s of sentences) {
|
|
85
|
+
const hasCitation = CITATION_PATTERNS.some((p) => new RegExp(p.source, p.flags).test(s));
|
|
86
|
+
if (hasCitation)
|
|
87
|
+
handWaveStreak = 0;
|
|
88
|
+
else {
|
|
89
|
+
handWaveStreak++;
|
|
90
|
+
maxHandWave = Math.max(maxHandWave, handWaveStreak);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Score: start at 1.0, subtract for weak signals
|
|
94
|
+
let confidence = 1.0;
|
|
95
|
+
confidence -= Math.min(0.30, hedgeRatio * 0.40); // hedges drop confidence (uncertainty)
|
|
96
|
+
confidence -= Math.min(0.30, absoluteRatio * 0.50); // absolutes WITHOUT citation are bad
|
|
97
|
+
confidence += Math.min(0.20, citationDensity / 10); // citations boost
|
|
98
|
+
confidence -= contradictions.length * 0.10;
|
|
99
|
+
confidence -= Math.min(0.20, Math.max(0, maxHandWave - 5) * 0.03);
|
|
100
|
+
confidence = Math.max(0, Math.min(1, confidence));
|
|
101
|
+
let verdict;
|
|
102
|
+
if (confidence >= 0.75)
|
|
103
|
+
verdict = "HIGH";
|
|
104
|
+
else if (confidence >= 0.50)
|
|
105
|
+
verdict = "MIXED";
|
|
106
|
+
else if (confidence >= 0.25)
|
|
107
|
+
verdict = "LOW";
|
|
108
|
+
else
|
|
109
|
+
verdict = "WEAK";
|
|
110
|
+
const weakSpots = [];
|
|
111
|
+
if (hedgeRatio > 0.30)
|
|
112
|
+
weakSpots.push(`high hedge density (${hedges.length} hedges / ${sentenceCount} sentences)`);
|
|
113
|
+
if (absoluteRatio > 0.15 && citationDensity < 1)
|
|
114
|
+
weakSpots.push(`${absolutes.length} absolute claim(s) without citation`);
|
|
115
|
+
if (contradictions.length > 0)
|
|
116
|
+
weakSpots.push(`${contradictions.length} contradiction pair(s) detected`);
|
|
117
|
+
if (maxHandWave > 5)
|
|
118
|
+
weakSpots.push(`${maxHandWave} consecutive sentences without any citation`);
|
|
119
|
+
if (citationDensity === 0 && tokens > 50)
|
|
120
|
+
weakSpots.push("zero citations across the entire response");
|
|
121
|
+
return {
|
|
122
|
+
tokens,
|
|
123
|
+
hedges,
|
|
124
|
+
hedgeRatio: Math.round(hedgeRatio * 1000) / 1000,
|
|
125
|
+
absolutes,
|
|
126
|
+
absoluteRatio: Math.round(absoluteRatio * 1000) / 1000,
|
|
127
|
+
citations,
|
|
128
|
+
citationDensity: Math.round(citationDensity * 100) / 100,
|
|
129
|
+
contradictions,
|
|
130
|
+
handWaveStreaks: maxHandWave,
|
|
131
|
+
structuralConfidence: Math.round(confidence * 1000) / 1000,
|
|
132
|
+
verdict,
|
|
133
|
+
weakSpots,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
export function formatXrayPulseLine(r) {
|
|
137
|
+
return `X-RAY · ${r.verdict} · confidence=${r.structuralConfidence} · hedges=${r.hedges.length} absolutes=${r.absolutes.length} citations=${r.citations.length} contradictions=${r.contradictions.length}`;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/xray/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xray.test.d.ts","sourceRoot":"","sources":["../../src/xray/xray.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { xrayResponse, formatXrayPulseLine } from "./index.js";
|
|
3
|
+
describe("v2.0 X-RAY · reasoning audit", () => {
|
|
4
|
+
it("detects hedge phrases", () => {
|
|
5
|
+
const r = xrayResponse("I think this might be the right answer. Perhaps you could try it.");
|
|
6
|
+
expect(r.hedges.length).toBeGreaterThanOrEqual(3);
|
|
7
|
+
expect(r.hedgeRatio).toBeGreaterThan(0);
|
|
8
|
+
});
|
|
9
|
+
it("detects absolutes", () => {
|
|
10
|
+
const r = xrayResponse("This is ALWAYS the case. Definitely. 100% guaranteed.");
|
|
11
|
+
expect(r.absolutes.length).toBeGreaterThanOrEqual(3);
|
|
12
|
+
expect(r.absoluteRatio).toBeGreaterThan(0);
|
|
13
|
+
});
|
|
14
|
+
it("detects citations (commit SHAs / file paths / URLs)", () => {
|
|
15
|
+
const r = xrayResponse("See commit a3f9b21 in packages/core/src/index.ts and the issue at https://github.com/x/y/issues/42.");
|
|
16
|
+
expect(r.citations.length).toBeGreaterThanOrEqual(2);
|
|
17
|
+
expect(r.citationDensity).toBeGreaterThan(0);
|
|
18
|
+
});
|
|
19
|
+
it("detects contradictions across sentences", () => {
|
|
20
|
+
const r = xrayResponse("This API is safe to use. The same API is actually unsafe in production.");
|
|
21
|
+
expect(r.contradictions.length).toBeGreaterThanOrEqual(1);
|
|
22
|
+
});
|
|
23
|
+
it("HIGH verdict on well-cited grounded response", () => {
|
|
24
|
+
const text = "Per commit a3f9b21 the JWT tolerance was set to 5 min. The file packages/auth/jwt.ts contains the validator. See PR #214 for the rollout plan.";
|
|
25
|
+
const r = xrayResponse(text);
|
|
26
|
+
expect(r.verdict).toBe("HIGH");
|
|
27
|
+
expect(r.structuralConfidence).toBeGreaterThanOrEqual(0.75);
|
|
28
|
+
});
|
|
29
|
+
it("LOW or WEAK verdict on hand-wavy hedge-heavy reply", () => {
|
|
30
|
+
const text = "I think this might generally work in most cases. Perhaps. Maybe. It could be the right approach. Possibly. Seems reasonable to me. Generally speaking. Arguably.";
|
|
31
|
+
const r = xrayResponse(text);
|
|
32
|
+
expect(["LOW", "WEAK", "MIXED"]).toContain(r.verdict);
|
|
33
|
+
expect(r.weakSpots.length).toBeGreaterThan(0);
|
|
34
|
+
});
|
|
35
|
+
it("flags absolute claims without citation", () => {
|
|
36
|
+
const r = xrayResponse("This is always the best approach. Never use the alternative. Definitely the right call.");
|
|
37
|
+
expect(r.weakSpots.some((w) => w.includes("absolute"))).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
it("flags zero-citation responses over 50 tokens", () => {
|
|
40
|
+
const text = "Lorem ipsum dolor sit amet ".repeat(15); // ~75 tokens of nothing
|
|
41
|
+
const r = xrayResponse(text);
|
|
42
|
+
expect(r.weakSpots.some((w) => w.includes("zero citations"))).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
it("structuralConfidence stays in 0..1", () => {
|
|
45
|
+
for (const text of ["", "a.", "the cat sat", "always never always"]) {
|
|
46
|
+
const r = xrayResponse(text);
|
|
47
|
+
expect(r.structuralConfidence).toBeGreaterThanOrEqual(0);
|
|
48
|
+
expect(r.structuralConfidence).toBeLessThanOrEqual(1);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
it("formatXrayPulseLine produces compact summary", () => {
|
|
52
|
+
const r = xrayResponse("commit a3f9b21 explains why.");
|
|
53
|
+
expect(formatXrayPulseLine(r)).toContain("X-RAY");
|
|
54
|
+
expect(formatXrayPulseLine(r)).toContain("confidence=");
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=xray.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xray.test.js","sourceRoot":"","sources":["../../src/xray/xray.test.ts"],"names":[],"mappings":"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"}
|