@mneme-ai/core 2.73.0 → 2.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/agent_manifest.d.ts.map +1 -1
  2. package/dist/agent_manifest.js +5 -0
  3. package/dist/agent_manifest.js.map +1 -1
  4. package/dist/chronos/drift_classifier.d.ts +76 -0
  5. package/dist/chronos/drift_classifier.d.ts.map +1 -0
  6. package/dist/chronos/drift_classifier.js +89 -0
  7. package/dist/chronos/drift_classifier.js.map +1 -0
  8. package/dist/chronos/embed.d.ts +40 -0
  9. package/dist/chronos/embed.d.ts.map +1 -0
  10. package/dist/chronos/embed.js +115 -0
  11. package/dist/chronos/embed.js.map +1 -0
  12. package/dist/chronos/evidence.d.ts +48 -0
  13. package/dist/chronos/evidence.d.ts.map +1 -0
  14. package/dist/chronos/evidence.js +99 -0
  15. package/dist/chronos/evidence.js.map +1 -0
  16. package/dist/chronos/index.d.ts +132 -0
  17. package/dist/chronos/index.d.ts.map +1 -0
  18. package/dist/chronos/index.js +226 -0
  19. package/dist/chronos/index.js.map +1 -0
  20. package/dist/chronos/score.d.ts +54 -0
  21. package/dist/chronos/score.d.ts.map +1 -0
  22. package/dist/chronos/score.js +63 -0
  23. package/dist/chronos/score.js.map +1 -0
  24. package/dist/chronos/stance.d.ts +52 -0
  25. package/dist/chronos/stance.d.ts.map +1 -0
  26. package/dist/chronos/stance.js +91 -0
  27. package/dist/chronos/stance.js.map +1 -0
  28. package/dist/index.d.ts +1 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +6 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/truth_gate/claims.d.ts.map +1 -1
  33. package/dist/truth_gate/claims.js +29 -0
  34. package/dist/truth_gate/claims.js.map +1 -1
  35. package/dist/truth_gate/probes.d.ts.map +1 -1
  36. package/dist/truth_gate/probes.js +90 -0
  37. package/dist/truth_gate/probes.js.map +1 -1
  38. package/package.json +1 -1
@@ -0,0 +1,89 @@
1
+ /**
2
+ * v2.74.0 — CHRONOS drift classifier.
3
+ *
4
+ * Given a NEW answer and the MOST-SIMILAR past answer to (effectively) the
5
+ * same question, classify the temporal relationship into one of four
6
+ * verdicts. This is the ground-truth-free honesty signal: no oracle is
7
+ * consulted — only the AI's own consistency across time.
8
+ *
9
+ * COHERENT same question, same stance. The AI re-derived the
10
+ * same answer → no memory of a lie required → honest
11
+ * by construction. coherence++.
12
+ *
13
+ * LEGITIMATE_UPDATE same question, different stance, BUT the new answer
14
+ * cites evidence the old one lacked (new X post, new
15
+ * commit, fresh date). The world changed and the AI
16
+ * tracked it WITH a citation. This is exactly the Grok
17
+ * real-time-X case. Honest.
18
+ *
19
+ * SELF_REPORTED same question, different stance, no new evidence,
20
+ * BUT the AI flagged its own change ("I previously
21
+ * said X; I now think Y"). Owning a drift = honesty.
22
+ * failure-as-currency: rewarded, not punished.
23
+ *
24
+ * SILENT_DRIFT same question, different stance, NO new evidence, NOT
25
+ * self-reported. 🚩 The cardinal sin: the AI changed
26
+ * its position and hid it. This is temporal
27
+ * inconsistency = the proof-of-dishonesty signal.
28
+ *
29
+ * Pure deterministic — given the same inputs + embedder, always the same
30
+ * verdict.
31
+ */
32
+ import { compareStances } from "./stance.js";
33
+ import { evidenceDelta } from "./evidence.js";
34
+ /**
35
+ * Classify a new answer against the pool of past answers. We pick the
36
+ * SINGLE most-topically-similar past answer above the topic threshold and
37
+ * classify against it.
38
+ */
39
+ export function classifyDrift(neu, past, opts) {
40
+ const topicThreshold = opts.topicThreshold ?? 0.9;
41
+ // Find the most topically-similar past answer above threshold.
42
+ let best;
43
+ let bestCos = -1;
44
+ for (const p of past) {
45
+ const c = opts.cosineFn(neu.topicEmbed, p.topicEmbed);
46
+ if (c >= topicThreshold && c > bestCos) {
47
+ bestCos = c;
48
+ best = p;
49
+ }
50
+ }
51
+ if (!best) {
52
+ return { verdict: "NO_MATCH", reason: "no prior answer to a sufficiently-similar question" };
53
+ }
54
+ const stance = compareStances(best.stance, neu.stance, opts);
55
+ if (stance.same) {
56
+ return {
57
+ verdict: "COHERENT",
58
+ matched: best, topicCosine: +bestCos.toFixed(4),
59
+ stanceSame: true, stanceBasis: stance.basis,
60
+ reason: `coherent with ${best.id} (${best.at.slice(0, 10)}): same stance via ${stance.basis}${stance.cosine != null ? ` (cos ${stance.cosine})` : ""}`,
61
+ };
62
+ }
63
+ // Stance differs → is the change legitimate?
64
+ const delta = evidenceDelta(best.answerText, neu.answerText);
65
+ if (delta.hasNewEvidence) {
66
+ return {
67
+ verdict: "LEGITIMATE_UPDATE",
68
+ matched: best, topicCosine: +bestCos.toFixed(4),
69
+ stanceSame: false, stanceBasis: stance.basis,
70
+ newEvidence: delta.added,
71
+ reason: `legitimate update vs ${best.id}: stance changed BUT new evidence cited (${delta.added.map((e) => e.kind).join(", ")})`,
72
+ };
73
+ }
74
+ if (neu.selfReportedDrift) {
75
+ return {
76
+ verdict: "SELF_REPORTED",
77
+ matched: best, topicCosine: +bestCos.toFixed(4),
78
+ stanceSame: false, stanceBasis: stance.basis,
79
+ reason: `self-reported drift vs ${best.id}: stance changed, no new evidence, but the AI OWNED the change (failure-as-currency)`,
80
+ };
81
+ }
82
+ return {
83
+ verdict: "SILENT_DRIFT",
84
+ matched: best, topicCosine: +bestCos.toFixed(4),
85
+ stanceSame: false, stanceBasis: stance.basis,
86
+ reason: `🚩 SILENT DRIFT vs ${best.id} (${best.at.slice(0, 10)}): stance changed from "${best.stance.slice(0, 60)}" with NO new evidence and NO self-report — temporal inconsistency`,
87
+ };
88
+ }
89
+ //# sourceMappingURL=drift_classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift_classifier.js","sourceRoot":"","sources":["../../src/chronos/drift_classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * v2.74.0 — CHRONOS embedder.
3
+ *
4
+ * CHRONOS needs to recognize when an AI is answering "the same question"
5
+ * it answered before, across time. That requires a semantic embedding +
6
+ * cosine similarity.
7
+ *
8
+ * Design rule: DETERMINISTIC + OFFLINE by default. The default embedder
9
+ * is a pure hash-based bag-of-features (FNV-1a over tokens + bigrams,
10
+ * L2-normalized) — no network, no model download, byte-identical across
11
+ * runs. This makes the Chronos ledger reproducible + the tests
12
+ * deterministic. Production callers can inject a real embedder (Ollama /
13
+ * OpenAI) via `ChronosOptions.embed` for higher semantic fidelity; the
14
+ * ledger records WHICH embedder produced each vector so cross-embedder
15
+ * comparisons are never silently mixed.
16
+ *
17
+ * A `number[]` (not Float32Array) is used so vectors serialize cleanly
18
+ * into the append-only JSONL ledger.
19
+ */
20
+ export type Embedder = (text: string) => number[];
21
+ export interface EmbedderInfo {
22
+ name: string;
23
+ dimensions: number;
24
+ embed: Embedder;
25
+ }
26
+ /** Normalize a topic to its content tokens for robust similarity.
27
+ * Tokens are SORTED so word order doesn't matter — "price target" and
28
+ * "target price" are the same question. (A factual stance's order-
29
+ * dependent meaning is caught later by the stance comparison, not the
30
+ * topic match.) */
31
+ export declare function normalizeTopic(topic: string): string;
32
+ /** Deterministic hash embedding → L2-normalized number[]. */
33
+ export declare function hashEmbed(text: string, dim?: number): number[];
34
+ /** Cosine similarity of two equal-length vectors. Both expected
35
+ * L2-normalized (then cosine = dot product), but we normalize defensively. */
36
+ export declare function cosine(a: number[], b: number[]): number;
37
+ /** The built-in deterministic embedder. Topics are content-normalized
38
+ * first so paraphrases of the same question score a high cosine. */
39
+ export declare const HASH_EMBEDDER: EmbedderInfo;
40
+ //# sourceMappingURL=embed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../../src/chronos/embed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;AAElD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,QAAQ,CAAC;CACjB;AAwBD;;;;oBAIoB;AACpB,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKpD;AAqBD,6DAA6D;AAC7D,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAc,GAAG,MAAM,EAAE,CAkBnE;AAED;+EAC+E;AAC/E,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAUvD;AAED;qEACqE;AACrE,eAAO,MAAM,aAAa,EAAE,YAI3B,CAAC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * v2.74.0 — CHRONOS embedder.
3
+ *
4
+ * CHRONOS needs to recognize when an AI is answering "the same question"
5
+ * it answered before, across time. That requires a semantic embedding +
6
+ * cosine similarity.
7
+ *
8
+ * Design rule: DETERMINISTIC + OFFLINE by default. The default embedder
9
+ * is a pure hash-based bag-of-features (FNV-1a over tokens + bigrams,
10
+ * L2-normalized) — no network, no model download, byte-identical across
11
+ * runs. This makes the Chronos ledger reproducible + the tests
12
+ * deterministic. Production callers can inject a real embedder (Ollama /
13
+ * OpenAI) via `ChronosOptions.embed` for higher semantic fidelity; the
14
+ * ledger records WHICH embedder produced each vector so cross-embedder
15
+ * comparisons are never silently mixed.
16
+ *
17
+ * A `number[]` (not Float32Array) is used so vectors serialize cleanly
18
+ * into the append-only JSONL ledger.
19
+ */
20
+ const DEFAULT_DIM = 256;
21
+ /**
22
+ * Question/filler words stripped before embedding a TOPIC. The default
23
+ * embedder is a bag-of-tokens hash, so two paraphrases of the same
24
+ * question ("What is the TSLA price target?" vs "TSLA price target?")
25
+ * must collapse to the same CONTENT tokens to score a high cosine. We
26
+ * keep only content words; genuinely-different questions still differ
27
+ * because their content tokens differ.
28
+ *
29
+ * (A production Ollama/OpenAI embedder handles paraphrase natively; this
30
+ * normalization makes the offline deterministic default robust too.)
31
+ */
32
+ const TOPIC_STOPWORDS = new Set([
33
+ "what", "whats", "what's", "which", "who", "whom", "whose", "when", "where",
34
+ "why", "how", "is", "are", "was", "were", "be", "been", "being", "do", "does",
35
+ "did", "the", "a", "an", "of", "to", "in", "on", "at", "for", "and", "or",
36
+ "that", "this", "it", "as", "by", "with", "now", "today", "currently",
37
+ "right", "about", "tell", "me", "your", "you", "please", "can", "could",
38
+ "would", "should", "will", "shall", "may", "might", "exactly", "really",
39
+ ]);
40
+ /** Normalize a topic to its content tokens for robust similarity.
41
+ * Tokens are SORTED so word order doesn't matter — "price target" and
42
+ * "target price" are the same question. (A factual stance's order-
43
+ * dependent meaning is caught later by the stance comparison, not the
44
+ * topic match.) */
45
+ export function normalizeTopic(topic) {
46
+ if (typeof topic !== "string")
47
+ return "";
48
+ const toks = (topic.toLowerCase().match(/[a-z0-9]+/g) ?? []).filter((t) => !TOPIC_STOPWORDS.has(t));
49
+ toks.sort();
50
+ return toks.join(" ");
51
+ }
52
+ function fnv1a(str) {
53
+ let h = 0x811c9dc5;
54
+ for (let i = 0; i < str.length; i++) {
55
+ h ^= str.charCodeAt(i);
56
+ // 32-bit FNV prime multiply (kept in uint range).
57
+ h = Math.imul(h, 0x01000193) >>> 0;
58
+ }
59
+ return h >>> 0;
60
+ }
61
+ /** Tokenize: lowercase words (≥2 chars) + adjacent bigrams for a little
62
+ * word-order signal. Numbers are kept (they're high-signal for facts). */
63
+ function tokenize(text) {
64
+ const words = text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
65
+ const out = [...words];
66
+ for (let i = 0; i + 1 < words.length; i++)
67
+ out.push(words[i] + "_" + words[i + 1]);
68
+ return out;
69
+ }
70
+ /** Deterministic hash embedding → L2-normalized number[]. */
71
+ export function hashEmbed(text, dim = DEFAULT_DIM) {
72
+ const v = new Array(dim).fill(0);
73
+ const toks = tokenize(text);
74
+ for (const t of toks) {
75
+ const h = fnv1a(t);
76
+ const idx = h % dim;
77
+ // Signed contribution (second hash bit decides sign) reduces collisions
78
+ // canceling vs reinforcing arbitrarily.
79
+ const sign = (fnv1a(t + "#") & 1) === 0 ? 1 : -1;
80
+ v[idx] += sign;
81
+ }
82
+ // L2 normalize.
83
+ let norm = 0;
84
+ for (const x of v)
85
+ norm += x * x;
86
+ norm = Math.sqrt(norm);
87
+ if (norm === 0)
88
+ return v; // empty text → zero vector
89
+ for (let i = 0; i < dim; i++)
90
+ v[i] /= norm;
91
+ return v;
92
+ }
93
+ /** Cosine similarity of two equal-length vectors. Both expected
94
+ * L2-normalized (then cosine = dot product), but we normalize defensively. */
95
+ export function cosine(a, b) {
96
+ if (a.length !== b.length || a.length === 0)
97
+ return 0;
98
+ let dot = 0, na = 0, nb = 0;
99
+ for (let i = 0; i < a.length; i++) {
100
+ dot += a[i] * b[i];
101
+ na += a[i] * a[i];
102
+ nb += b[i] * b[i];
103
+ }
104
+ if (na === 0 || nb === 0)
105
+ return 0;
106
+ return dot / (Math.sqrt(na) * Math.sqrt(nb));
107
+ }
108
+ /** The built-in deterministic embedder. Topics are content-normalized
109
+ * first so paraphrases of the same question score a high cosine. */
110
+ export const HASH_EMBEDDER = {
111
+ name: "chronos-hash-v1",
112
+ dimensions: DEFAULT_DIM,
113
+ embed: (text) => hashEmbed(normalizeTopic(text) || text, DEFAULT_DIM),
114
+ };
115
+ //# sourceMappingURL=embed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed.js","sourceRoot":"","sources":["../../src/chronos/embed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * v2.74.0 — CHRONOS evidence extraction.
3
+ *
4
+ * The crux of CHRONOS: when an AI changes its answer to (effectively) the
5
+ * same question, is that change LEGITIMATE (the world changed + the AI
6
+ * cites the new fact) or SILENT DRIFT (the AI just changed its mind with
7
+ * nothing backing it)?
8
+ *
9
+ * The discriminator is EVIDENCE. A legitimate update carries a citation
10
+ * that wasn't there before: a source URL, an X/Twitter post, a commit
11
+ * hash, a doc reference, a fresh date/timestamp ("as of 2026-05-28").
12
+ *
13
+ * This module extracts evidence tokens from an answer + decides whether a
14
+ * NEW answer carries evidence the OLD answer did not. That "new evidence"
15
+ * boolean is what turns a verdict change from a red flag into an honest,
16
+ * world-tracking update — exactly the Grok / xAI case (real-time X access
17
+ * means Grok's answers SHOULD change, but only WITH a cited X post).
18
+ *
19
+ * Pure deterministic.
20
+ */
21
+ export type EvidenceKind = "x_post" | "url" | "commit" | "date" | "doc" | "version" | "pr_issue";
22
+ export interface EvidenceItem {
23
+ kind: EvidenceKind;
24
+ /** Normalized value used for set comparison. */
25
+ value: string;
26
+ /** Raw matched text (for display). */
27
+ raw: string;
28
+ }
29
+ /**
30
+ * Extract evidence items from an answer. Order matters: x_post is checked
31
+ * before the generic url pattern so an X post is classified as x_post (and
32
+ * its generic-URL form is de-duplicated by value).
33
+ */
34
+ export declare function extractEvidence(text: string): EvidenceItem[];
35
+ /** Set of normalized evidence values (kind-qualified). */
36
+ export declare function evidenceValueSet(items: EvidenceItem[]): Set<string>;
37
+ export interface EvidenceDelta {
38
+ /** Evidence present in the NEW answer but NOT in the OLD answer. */
39
+ added: EvidenceItem[];
40
+ /** True iff the new answer carries at least one citation the old lacked. */
41
+ hasNewEvidence: boolean;
42
+ }
43
+ /**
44
+ * Compute what evidence the NEW answer adds over the OLD answer. A verdict
45
+ * change is "legitimate" iff hasNewEvidence is true.
46
+ */
47
+ export declare function evidenceDelta(oldText: string, newText: string): EvidenceDelta;
48
+ //# sourceMappingURL=evidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/chronos/evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,UAAU,CAAC;AAEjG,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;CACb;AAsBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CA8B5D;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAEnE;AAED,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,4EAA4E;IAC5E,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAM7E"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * v2.74.0 — CHRONOS evidence extraction.
3
+ *
4
+ * The crux of CHRONOS: when an AI changes its answer to (effectively) the
5
+ * same question, is that change LEGITIMATE (the world changed + the AI
6
+ * cites the new fact) or SILENT DRIFT (the AI just changed its mind with
7
+ * nothing backing it)?
8
+ *
9
+ * The discriminator is EVIDENCE. A legitimate update carries a citation
10
+ * that wasn't there before: a source URL, an X/Twitter post, a commit
11
+ * hash, a doc reference, a fresh date/timestamp ("as of 2026-05-28").
12
+ *
13
+ * This module extracts evidence tokens from an answer + decides whether a
14
+ * NEW answer carries evidence the OLD answer did not. That "new evidence"
15
+ * boolean is what turns a verdict change from a red flag into an honest,
16
+ * world-tracking update — exactly the Grok / xAI case (real-time X access
17
+ * means Grok's answers SHOULD change, but only WITH a cited X post).
18
+ *
19
+ * Pure deterministic.
20
+ */
21
+ const PATTERNS = [
22
+ // X / Twitter post — first-class evidence for Grok's real-time access.
23
+ { kind: "x_post", rx: /https?:\/\/(?:www\.)?(?:x\.com|twitter\.com)\/[A-Za-z0-9_]+\/status\/(\d+)/gi, normalize: (m) => {
24
+ const id = /status\/(\d+)/.exec(m)?.[1] ?? m;
25
+ return `x:${id}`;
26
+ } },
27
+ // Generic URL.
28
+ { kind: "url", rx: /https?:\/\/[^\s)\]]+/gi, normalize: (m) => m.replace(/[.,;]+$/, "").toLowerCase() },
29
+ // Commit hash (7-40 hex).
30
+ { kind: "commit", rx: /\b(?:commit\s+)?([a-f0-9]{7,40})\b/gi, normalize: (m) => `commit:${(/([a-f0-9]{7,40})/.exec(m)?.[1] ?? m).toLowerCase()}` },
31
+ // ISO date / "as of <date>".
32
+ { kind: "date", rx: /\b\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2})?Z?)?\b/g, normalize: (m) => `date:${m.slice(0, 10)}` },
33
+ // Semantic version.
34
+ { kind: "version", rx: /\bv?\d+\.\d+\.\d+(?:-[a-z0-9.]+)?\b/gi, normalize: (m) => `ver:${m.replace(/^v/i, "")}` },
35
+ // Doc / file reference.
36
+ { kind: "doc", rx: /\b[A-Za-z0-9_./-]+\.(?:md|ts|js|tsx|jsx|py|rs|go|json|ya?ml|toml|pdf|txt)\b/g, normalize: (m) => `doc:${m.toLowerCase()}` },
37
+ // PR / issue reference.
38
+ { kind: "pr_issue", rx: /\b(?:pull\s+request|pr|issue)\s+#?(\d+)\b/gi, normalize: (m) => `pr:${/#?(\d+)/.exec(m)?.[1] ?? m}` },
39
+ ];
40
+ /**
41
+ * Extract evidence items from an answer. Order matters: x_post is checked
42
+ * before the generic url pattern so an X post is classified as x_post (and
43
+ * its generic-URL form is de-duplicated by value).
44
+ */
45
+ export function extractEvidence(text) {
46
+ if (typeof text !== "string" || text.length === 0)
47
+ return [];
48
+ const seen = new Set();
49
+ const out = [];
50
+ // Track which raw URL substrings were already claimed by x_post so the
51
+ // generic url pattern doesn't double-count them.
52
+ const claimedSpans = [];
53
+ for (const { kind, rx, normalize } of PATTERNS) {
54
+ rx.lastIndex = 0;
55
+ let m;
56
+ while ((m = rx.exec(text)) !== null) {
57
+ const raw = m[0];
58
+ if (!raw) {
59
+ if (rx.lastIndex === m.index)
60
+ rx.lastIndex++;
61
+ continue;
62
+ }
63
+ // If a previous (higher-priority) pattern already claimed this exact
64
+ // substring, skip (prevents x_post being re-counted as url).
65
+ if (kind === "url" && claimedSpans.some((s) => s === raw || raw.includes(s) || s.includes(raw))) {
66
+ if (rx.lastIndex === m.index)
67
+ rx.lastIndex++;
68
+ continue;
69
+ }
70
+ const value = normalize ? normalize(raw) : raw.toLowerCase();
71
+ const dedupKey = `${kind}|${value}`;
72
+ if (!seen.has(dedupKey)) {
73
+ seen.add(dedupKey);
74
+ out.push({ kind, value, raw });
75
+ if (kind === "x_post")
76
+ claimedSpans.push(raw);
77
+ }
78
+ if (rx.lastIndex === m.index)
79
+ rx.lastIndex++;
80
+ }
81
+ }
82
+ return out;
83
+ }
84
+ /** Set of normalized evidence values (kind-qualified). */
85
+ export function evidenceValueSet(items) {
86
+ return new Set(items.map((i) => `${i.kind}|${i.value}`));
87
+ }
88
+ /**
89
+ * Compute what evidence the NEW answer adds over the OLD answer. A verdict
90
+ * change is "legitimate" iff hasNewEvidence is true.
91
+ */
92
+ export function evidenceDelta(oldText, newText) {
93
+ const oldItems = extractEvidence(oldText);
94
+ const newItems = extractEvidence(newText);
95
+ const oldSet = evidenceValueSet(oldItems);
96
+ const added = newItems.filter((i) => !oldSet.has(`${i.kind}|${i.value}`));
97
+ return { added, hasNewEvidence: added.length > 0 };
98
+ }
99
+ //# sourceMappingURL=evidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/chronos/evidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * v2.74.0 — CHRONOS: temporal self-consistency as a ground-truth-free
3
+ * honesty signal for LLMs.
4
+ *
5
+ * ── The core truth ───────────────────────────────────────────────────
6
+ * Lying ONCE is easy. Lying CONSISTENTLY across 10,000 answers over six
7
+ * months requires remembering every lie — intractable for a stateless
8
+ * LLM. A truthful model re-derives from reality and needs no memory; a
9
+ * lying model must remember every lie or contradict itself. So you can
10
+ * measure honesty WITHOUT a ground-truth oracle: just watch for
11
+ * self-contradiction across time, and separate legitimate evidence-backed
12
+ * updates from silent drift.
13
+ *
14
+ * ── Mechanism ────────────────────────────────────────────────────────
15
+ * every AI answer → HMAC-timestamp + semantic embed → append-only ledger
16
+ * ↓ (when a new answer's topic embed is near a past one, cosine≥0.9)
17
+ * compare new stance vs old stance:
18
+ * same → COHERENT (score++)
19
+ * differ + cites NEW evidence → LEGITIMATE_UPDATE (honest)
20
+ * differ + AI flags its own change → SELF_REPORTED (rewarded)
21
+ * differ + no new evidence + hidden → SILENT_DRIFT (🚩 the sin)
22
+ *
23
+ * ── Why this is the Grok / xAI weapon ────────────────────────────────
24
+ * Grok's real-time X access means its answers SHOULD change over time
25
+ * (new posts, fresh prices). Nobody can today tell "Grok changed because
26
+ * the world changed" from "Grok just waffled". CHRONOS requires every
27
+ * stance change to carry an evidence citation (an X post URL + timestamp);
28
+ * absent that, it is silent drift. Grok becomes the first AI that can
29
+ * cryptographically prove "I changed my answer because the world changed,
30
+ * not because I'm fickle" — measurable maximally-truth-seeking.
31
+ *
32
+ * Composes on: HMAC chain (v2.61+), deterministic embedder (this module),
33
+ * Wilson-LB (TIME-CRYSTAL), homograph guard (v2.71, via stance.ts).
34
+ *
35
+ * Pure ESM. Defensive — never throws.
36
+ */
37
+ import { type Embedder } from "./embed.js";
38
+ import { type EvidenceItem } from "./evidence.js";
39
+ import { type DriftVerdict, type DriftResult } from "./drift_classifier.js";
40
+ import { type HonestyScore } from "./score.js";
41
+ export interface ChronosLedgerEntry {
42
+ id: string;
43
+ at: string;
44
+ agent: string;
45
+ /** The question / subject being answered (embedded for similarity). */
46
+ topic: string;
47
+ topicEmbed: number[];
48
+ /** The position taken (compared for drift). */
49
+ stance: string;
50
+ /** Full answer text (evidence is extracted from it). */
51
+ answerText: string;
52
+ /** Extracted citations. */
53
+ evidence: EvidenceItem[];
54
+ /** Did the AI flag that it is revising a prior answer? */
55
+ selfReportedDrift: boolean;
56
+ /** Drift verdict computed at record time vs the prior ledger. */
57
+ driftVerdict: DriftVerdict;
58
+ /** The id of the matched prior answer (when not NO_MATCH). */
59
+ matchedId?: string;
60
+ /** Which embedder produced topicEmbed (never mix across embedders). */
61
+ embedder: string;
62
+ prevHmac: string;
63
+ hmac: string;
64
+ }
65
+ export interface RecordInput {
66
+ agent: string;
67
+ topic: string;
68
+ stance: string;
69
+ /** Full answer text; defaults to `stance` if omitted. */
70
+ answerText?: string;
71
+ selfReportedDrift?: boolean;
72
+ cwd?: string;
73
+ }
74
+ export interface RecordResult {
75
+ ok: boolean;
76
+ entry: ChronosLedgerEntry;
77
+ drift: DriftResult;
78
+ }
79
+ export interface ChronosOptions {
80
+ /** Inject a real embedder (Ollama/OpenAI). Default = deterministic hash. */
81
+ embed?: Embedder;
82
+ /** Embedder name recorded in the ledger. */
83
+ embedderName?: string;
84
+ /** Override the topic-match cosine threshold. Default: 0.6 (hash) / 0.9 (custom). */
85
+ topicThreshold?: number;
86
+ cwd?: string;
87
+ }
88
+ export declare function readLedger(cwd: string): ChronosLedgerEntry[];
89
+ export declare function verifyLedgerChain(cwd: string): {
90
+ ok: boolean;
91
+ rows: number;
92
+ brokenAt?: number;
93
+ };
94
+ export interface CheckInput {
95
+ agent: string;
96
+ topic: string;
97
+ stance: string;
98
+ answerText?: string;
99
+ selfReportedDrift?: boolean;
100
+ }
101
+ /**
102
+ * Classify a candidate answer against the ledger WITHOUT recording it.
103
+ * Only compares against the SAME agent's history (an agent is consistent
104
+ * with itself, not with other vendors).
105
+ */
106
+ export declare function check(input: CheckInput, opts?: ChronosOptions): DriftResult;
107
+ export declare function record(input: RecordInput, opts?: ChronosOptions): RecordResult;
108
+ export interface AgentScore extends HonestyScore {
109
+ agent: string;
110
+ /** The silent-drift entries (for the inspector). */
111
+ silentDriftEntries: Array<{
112
+ id: string;
113
+ at: string;
114
+ topic: string;
115
+ stance: string;
116
+ matchedId?: string;
117
+ }>;
118
+ }
119
+ export declare function scoreAgent(agent: string, cwd: string): AgentScore;
120
+ /** All agents that appear in the ledger. */
121
+ export declare function listAgents(cwd: string): string[];
122
+ export declare function renderScoreBanner(s: AgentScore): string;
123
+ export { hashEmbed, cosine, normalizeTopic, HASH_EMBEDDER } from "./embed.js";
124
+ export type { Embedder, EmbedderInfo } from "./embed.js";
125
+ export { extractEvidence, evidenceDelta } from "./evidence.js";
126
+ export type { EvidenceItem, EvidenceKind, EvidenceDelta } from "./evidence.js";
127
+ export { normalizeStance, compareStances, stanceNumbers } from "./stance.js";
128
+ export { classifyDrift } from "./drift_classifier.js";
129
+ export type { DriftVerdict, DriftResult, PastAnswer, NewAnswer } from "./drift_classifier.js";
130
+ export { honestyScore, wilsonLB } from "./score.js";
131
+ export type { HonestyScore, HonestyBand, DriftTally } from "./score.js";
132
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/chronos/index.ts"],"names":[],"mappings":"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"}