@mneme-ai/core 2.99.0 → 2.101.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.
@@ -0,0 +1,154 @@
1
+ /**
2
+ * v2.100.0 — HYDRA · GUARD × CHAIN fusion ("temporal guarded replay").
3
+ *
4
+ * The two gems become one. The PROVENANCE CHAIN (v2.98) already records
5
+ * every codebook delta with a seq. The GUARD (v2.97) redacts stale content.
6
+ * Here the chain computes its OWN atrophy clock — no external age source —
7
+ * and drives the guard: a phrase that was added long ago and never touched
8
+ * since is STALE; replaying with `--guard` redacts exactly those.
9
+ *
10
+ * So you can replay the codebook at any past step, and the entries that had
11
+ * already gone cold by then expand only to their signed abstract — the AI
12
+ * gets the *shape* of old knowledge but cannot quote rotten detail. The
13
+ * staleness is derived deterministically from the chain's own history, and
14
+ * (the Padgett rule) only PROVEN-old entries go stale — anything we can't
15
+ * prove is old stays fresh.
16
+ *
17
+ * STABILITY: every function is total. Garbage chain / bad index / empty →
18
+ * the safest, smallest result, never a throw.
19
+ */
20
+ import { replayChain } from "./chain.js";
21
+ /**
22
+ * For the codebook that exists at `uptoIndex`, the seq at which each
23
+ * surviving phrase was most recently ADDED (i.e. last touched). Pure;
24
+ * never throws. A phrase removed and re-added gets the later seq (it's
25
+ * "fresh" again); a phrase added once and left alone keeps its old seq.
26
+ */
27
+ export function phraseAddedSeq(chain, uptoIndex) {
28
+ const seqOf = new Map();
29
+ if (!Array.isArray(chain))
30
+ return seqOf;
31
+ const end = Math.min(uptoIndex, chain.length - 1);
32
+ for (let i = 0; i <= end; i++) {
33
+ const d = chain[i];
34
+ if (!d)
35
+ continue;
36
+ if (Array.isArray(d.removed))
37
+ for (const p of d.removed)
38
+ seqOf.delete(p);
39
+ if (Array.isArray(d.added))
40
+ for (const a of d.added)
41
+ if (a && typeof a.phrase === "string")
42
+ seqOf.set(a.phrase, d.seq);
43
+ }
44
+ return seqOf;
45
+ }
46
+ /**
47
+ * Derive a trust map for the codebook at `uptoIndex` FROM THE CHAIN'S OWN
48
+ * HISTORY. An entry is stale when its age (deltas since last touched)
49
+ * exceeds `halfLifeDeltas * 2` — the same "proven-old, else fresh"
50
+ * discipline as the atrophy clock. Total; never throws.
51
+ */
52
+ export function trustMapFromChain(chain, uptoIndex, halfLifeDeltas) {
53
+ const empty = { trustMap: {}, freshCount: 0, staleCount: 0, atIndex: uptoIndex };
54
+ try {
55
+ if (!Array.isArray(chain) || chain.length === 0 || !(halfLifeDeltas > 0))
56
+ return empty;
57
+ const at = Math.min(Math.max(0, uptoIndex), chain.length - 1);
58
+ const r = replayChain(chain, at);
59
+ if (!r.ok || !r.codebook)
60
+ return { ...empty, atIndex: at };
61
+ const addedSeq = phraseAddedSeq(chain, at);
62
+ const trustMap = {};
63
+ let fresh = 0, stale = 0;
64
+ for (const e of r.codebook.entries) {
65
+ if (!e || typeof e.phrase !== "string")
66
+ continue;
67
+ const added = addedSeq.get(e.phrase);
68
+ const age = typeof added === "number" ? at - added : 0; // unknown ⇒ treat as just-added (fresh)
69
+ if (age > halfLifeDeltas * 2) {
70
+ trustMap[e.sym] = "stale";
71
+ stale++;
72
+ }
73
+ else
74
+ fresh++;
75
+ }
76
+ return { trustMap, freshCount: fresh, staleCount: stale, atIndex: at };
77
+ }
78
+ catch {
79
+ return empty;
80
+ }
81
+ }
82
+ /**
83
+ * Replay the codebook at `index` AND attach the chain-derived trust map.
84
+ * Combine with expandGuarded(encoded, codebook, trustFromMap(trust.trustMap))
85
+ * to get a stale-aware, byte-lossless-for-fresh, redacted-for-cold view of
86
+ * any past step. Total; never throws.
87
+ */
88
+ export function guardedReplay(chain, index, halfLifeDeltas) {
89
+ try {
90
+ if (!Array.isArray(chain) || chain.length === 0)
91
+ return { ok: false, codebook: null, trust: { trustMap: {}, freshCount: 0, staleCount: 0, atIndex: index }, reason: "empty chain" };
92
+ const at = Math.min(Math.max(0, index), chain.length - 1);
93
+ const r = replayChain(chain, at);
94
+ if (!r.ok || !r.codebook)
95
+ return { ok: false, codebook: null, trust: { trustMap: {}, freshCount: 0, staleCount: 0, atIndex: at }, reason: r.reason };
96
+ const trust = trustMapFromChain(chain, at, halfLifeDeltas);
97
+ return { ok: true, codebook: r.codebook, trust, reason: "replayed + trust derived from chain history" };
98
+ }
99
+ catch (e) {
100
+ return { ok: false, codebook: null, trust: { trustMap: {}, freshCount: 0, staleCount: 0, atIndex: index }, reason: `threw: ${e.message}` };
101
+ }
102
+ }
103
+ /** Prove the fusion's invariants over a real chain. Total. */
104
+ export function guardedChainGauntlet(chain, halfLifeDeltas) {
105
+ try {
106
+ // Nothing to prove on an empty/invalid chain → score 0 (not a vacuous pass).
107
+ if (!Array.isArray(chain) || chain.length === 0)
108
+ return { deterministic: false, freshAtTip: false, provenOnly: false, stable: true, score: 0 };
109
+ const a = trustMapFromChain(chain, chain.length - 1, halfLifeDeltas);
110
+ const b = trustMapFromChain(chain, chain.length - 1, halfLifeDeltas);
111
+ const deterministic = JSON.stringify(a.trustMap) === JSON.stringify(b.trustMap);
112
+ // Entries added in the LAST delta must not be stale at the tip.
113
+ const tip = chain[chain.length - 1];
114
+ let freshAtTip = true;
115
+ if (tip && Array.isArray(tip.added)) {
116
+ const r = replayChain(chain, chain.length - 1);
117
+ const cb = r.codebook;
118
+ if (cb) {
119
+ const tipPhrases = new Set(tip.added.map((x) => x.phrase));
120
+ for (const e of cb.entries)
121
+ if (tipPhrases.has(e.phrase) && a.trustMap[e.sym] === "stale")
122
+ freshAtTip = false;
123
+ }
124
+ }
125
+ // proven-only: every stale entry genuinely has age > halfLife*2.
126
+ let provenOnly = true;
127
+ const addedSeq = phraseAddedSeq(chain, chain.length - 1);
128
+ const r2 = replayChain(chain, chain.length - 1);
129
+ if (r2.codebook) {
130
+ for (const e of r2.codebook.entries) {
131
+ if (a.trustMap[e.sym] === "stale") {
132
+ const added = addedSeq.get(e.phrase);
133
+ const age = typeof added === "number" ? (chain.length - 1) - added : 0;
134
+ if (!(age > halfLifeDeltas * 2))
135
+ provenOnly = false;
136
+ }
137
+ }
138
+ }
139
+ let stable = true;
140
+ try {
141
+ guardedReplay(null, 5, 0);
142
+ trustMapFromChain(undefined, 0, -1);
143
+ }
144
+ catch {
145
+ stable = false;
146
+ }
147
+ const perfect = deterministic && freshAtTip && provenOnly && stable;
148
+ return { deterministic, freshAtTip, provenOnly, stable, score: perfect ? 100 : 0 };
149
+ }
150
+ catch {
151
+ return { deterministic: false, freshAtTip: false, provenOnly: false, stable: false, score: 0 };
152
+ }
153
+ }
154
+ //# sourceMappingURL=chain_guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain_guard.js","sourceRoot":"","sources":["../../src/hydra/chain_guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chain_guard.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain_guard.test.d.ts","sourceRoot":"","sources":["../../src/hydra/chain_guard.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { forgeCodebook, compress, sha256Hex } from "./index.js";
3
+ import { appendToChain } from "./chain.js";
4
+ import { expandGuarded, trustFromMap } from "./guard.js";
5
+ import { trustMapFromChain, guardedReplay, guardedChainGauntlet, phraseAddedSeq } from "./chain_guard.js";
6
+ // An evolving corpus: "ancient axiom" lands at delta 0 and is never touched
7
+ // again; new phrases arrive in later deltas. So by the tip, the ancient one
8
+ // has aged out while the recent ones are fresh.
9
+ // Each "fact" line is repeated so its phrase earns a positive MDL slot. The
10
+ // corpus is cumulative: the ancient line lands at delta 0 and is never
11
+ // touched again; new lines arrive in later deltas → by the tip the ancient
12
+ // one has aged out while the brand-new one is fresh.
13
+ const L_ANCIENT = "ancient axiom holds forever and ever. ".repeat(4);
14
+ const L_MIDDLE = "middle rule connects all things here. ".repeat(4);
15
+ const L_RECENT = "recent fact arrives as the newest one. ".repeat(4);
16
+ const L_NEW = "brand new thing just landed today hot. ".repeat(4);
17
+ const STEPS = [
18
+ L_ANCIENT,
19
+ L_ANCIENT + "\n" + L_MIDDLE,
20
+ L_ANCIENT + "\n" + L_MIDDLE + "\n" + L_RECENT,
21
+ L_ANCIENT + "\n" + L_MIDDLE + "\n" + L_RECENT + "\n" + L_NEW,
22
+ ];
23
+ function buildChain() {
24
+ let chain = [];
25
+ STEPS.forEach((c, i) => { chain = appendToChain(process.cwd(), chain, forgeCodebook(c, { minHits: 2 }).codebook, 1700000000000 + i).chain; });
26
+ return chain;
27
+ }
28
+ describe("v2.100 HYDRA · GUARD × CHAIN — temporal guarded replay", () => {
29
+ it("derives staleness from the chain's OWN history (deterministic)", () => {
30
+ const chain = buildChain();
31
+ const a = trustMapFromChain(chain, chain.length - 1, 1);
32
+ const b = trustMapFromChain(chain, chain.length - 1, 1);
33
+ expect(JSON.stringify(a.trustMap)).toBe(JSON.stringify(b.trustMap));
34
+ expect(a.staleCount + a.freshCount).toBeGreaterThan(0);
35
+ });
36
+ it("a phrase added at delta 0, untouched, is STALE at the tip; tip-added is FRESH", () => {
37
+ const chain = buildChain();
38
+ const t = trustMapFromChain(chain, chain.length - 1, 1); // halfLife*2 = 2 deltas
39
+ const r = guardedReplay(chain, chain.length - 1, 1);
40
+ const cb = r.codebook;
41
+ const ancient = cb.entries.find((e) => e.phrase.includes("ancient axiom"));
42
+ const brandNew = cb.entries.find((e) => e.phrase.includes("brand new thing"));
43
+ if (ancient)
44
+ expect(t.trustMap[ancient.sym]).toBe("stale"); // old → redacted
45
+ if (brandNew)
46
+ expect(t.trustMap[brandNew.sym]).toBeUndefined(); // just added → fresh
47
+ });
48
+ it("END-TO-END: guarded expansion redacts cold content, keeps fresh byte-exact", () => {
49
+ const chain = buildChain();
50
+ const tipCorpus = STEPS[STEPS.length - 1];
51
+ const r = guardedReplay(chain, chain.length - 1, 1);
52
+ const cb = r.codebook;
53
+ const encoded = compress(tipCorpus, cb);
54
+ const guarded = expandGuarded(encoded, cb, trustFromMap(r.trust.trustMap));
55
+ // ancient (cold) content is redacted; fresh content survives byte-exact.
56
+ expect(guarded.includes("ancient axiom holds forever")).toBe(false);
57
+ expect(guarded).toContain("brand new thing just landed");
58
+ // identity of the redacted region stays verifiable
59
+ const ancient = cb.entries.find((e) => e.phrase.includes("ancient axiom"));
60
+ expect(guarded).toContain(sha256Hex(ancient.phrase).slice(0, 16));
61
+ });
62
+ it("phraseAddedSeq tracks re-add freshness (remove then re-add ⇒ newer seq)", () => {
63
+ const chain = buildChain();
64
+ const seqs = phraseAddedSeq(chain, chain.length - 1);
65
+ // recent phrases were added at later seqs than ancient ones.
66
+ const ancientSeq = [...seqs.entries()].find(([p]) => p.includes("ancient axiom"))?.[1] ?? -1;
67
+ const newSeq = [...seqs.entries()].find(([p]) => p.includes("brand new thing"))?.[1] ?? -1;
68
+ expect(newSeq).toBeGreaterThan(ancientSeq);
69
+ });
70
+ it("guarded-chain gauntlet scores 100 (deterministic ∧ freshAtTip ∧ provenOnly ∧ stable)", () => {
71
+ const g = guardedChainGauntlet(buildChain(), 1);
72
+ expect(g.deterministic).toBe(true);
73
+ expect(g.freshAtTip).toBe(true);
74
+ expect(g.provenOnly).toBe(true);
75
+ expect(g.stable).toBe(true);
76
+ expect(g.score).toBe(100);
77
+ });
78
+ it("STABILITY — total on garbage", () => {
79
+ expect(() => trustMapFromChain(null, 0, 1)).not.toThrow();
80
+ expect(guardedReplay(undefined, 3, 1).ok).toBe(false);
81
+ expect(guardedChainGauntlet([], 1).score).toBe(0);
82
+ expect(trustMapFromChain([], 0, 1).staleCount).toBe(0);
83
+ });
84
+ });
85
+ //# sourceMappingURL=chain_guard.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain_guard.test.js","sourceRoot":"","sources":["../../src/hydra/chain_guard.test.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@ export * from "./analytic.js";
23
23
  export * from "./attest.js";
24
24
  export * from "./guard.js";
25
25
  export * from "./chain.js";
26
+ export * from "./chain_guard.js";
26
27
  import type { Codebook } from "./engine.js";
27
28
  import { type ForgeOpts, type ForgeResult, type Gauntlet } from "./analytic.js";
28
29
  import { type EnergyCert } from "./attest.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hydra/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAE3B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAA2B,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EAAsD,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,yBAAyB,CAAC;IAChC,CAAC,EAAE,CAAC,CAAC;IACL,QAAQ,EAAE,QAAQ,CAAC;IACnB,gDAAgD;IAChD,OAAO,EAAE,aAAa,CAAC;IACvB,qEAAqE;IACrE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,gBAAgB,CAavF;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,GAAG,aAAa,EAAE,CAMxD;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,SAAc,GAAG,gBAAgB,CAQ/G"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hydra/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AAEjC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAA2B,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EAAsD,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,yBAAyB,CAAC;IAChC,CAAC,EAAE,CAAC,CAAC;IACL,QAAQ,EAAE,QAAQ,CAAC;IACnB,gDAAgD;IAChD,OAAO,EAAE,aAAa,CAAC;IACvB,qEAAqE;IACrE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,gBAAgB,CAavF;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,GAAG,aAAa,EAAE,CAMxD;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,SAAc,GAAG,gBAAgB,CAQ/G"}
@@ -23,6 +23,7 @@ export * from "./analytic.js";
23
23
  export * from "./attest.js";
24
24
  export * from "./guard.js";
25
25
  export * from "./chain.js";
26
+ export * from "./chain_guard.js";
26
27
  import { sha256Hex } from "./engine.js";
27
28
  import { forgeCodebook, gauntlet } from "./analytic.js";
28
29
  import { signCodebook, mintEnergyCert, canonicalizeCodebook } from "./attest.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hydra/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAmD,MAAM,eAAe,CAAC;AACzG,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAmB,MAAM,aAAa,CAAC;AAsBlG,MAAM,UAAU,gBAAgB,CAAC,EAAY,EAAE,OAAsB;IACnE,OAAO;QACL,IAAI,EAAE,yBAAyB;QAC/B,CAAC,EAAE,CAAC;QACJ,QAAQ,EAAE,EAAE;QACZ,OAAO;QACP,OAAO,EAAE;YACP,IAAI,EAAE,4HAA4H;YAClI,UAAU,EAAE,EAAE,CAAC,IAAI;YACnB,WAAW,EAAE,EAAE,CAAC,KAAK;SACtB;QACD,YAAY,EAAE,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;KAClD,CAAC;AACJ,CAAC;AAaD,MAAM,UAAU,UAAU,CAAC,EAAY;IACrC,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5B,KAAK,EAAE,gBAAgB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;QACrF,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC,CAAC,CAAC;AACN,CAAC;AAWD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,MAAc,EAAE,EAAU,EAAE,OAAkB,EAAE;IAC3F,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hydra/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAmD,MAAM,eAAe,CAAC;AACzG,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAmB,MAAM,aAAa,CAAC;AAsBlG,MAAM,UAAU,gBAAgB,CAAC,EAAY,EAAE,OAAsB;IACnE,OAAO;QACL,IAAI,EAAE,yBAAyB;QAC/B,CAAC,EAAE,CAAC;QACJ,QAAQ,EAAE,EAAE;QACZ,OAAO;QACP,OAAO,EAAE;YACP,IAAI,EAAE,4HAA4H;YAClI,UAAU,EAAE,EAAE,CAAC,IAAI;YACnB,WAAW,EAAE,EAAE,CAAC,KAAK;SACtB;QACD,YAAY,EAAE,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;KAClD,CAAC;AACJ,CAAC;AAaD,MAAM,UAAU,UAAU,CAAC,EAAY;IACrC,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5B,KAAK,EAAE,gBAAgB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;QACrF,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC,CAAC,CAAC;AACN,CAAC;AAWD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,MAAc,EAAE,EAAU,EAAE,OAAkB,EAAE;IAC3F,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACnE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"probes.d.ts","sourceRoot":"","sources":["../../src/truth_gate/probes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAoyFnE,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,KAAK,CAAU,CAAC;AAEvD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAEvD;AAED,wBAAsB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAQlF"}
1
+ {"version":3,"file":"probes.d.ts","sourceRoot":"","sources":["../../src/truth_gate/probes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA41FnE,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,KAAK,CAAU,CAAC;AAEvD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAEvD;AAED,wBAAsB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAQlF"}
@@ -342,6 +342,79 @@ const probes = [
342
342
  }
343
343
  },
344
344
  },
345
+ {
346
+ id: "probe.hydra.mcp_self_attesting",
347
+ kind: "boolean",
348
+ description: "HYDRA MCP surface (v2.101.0 — the last flow): any AI agent calls the whole HYDRA stack straight through MCP, and every result is SELF-ATTESTING — wrapped with a NOTARY (Ed25519) receipt over the SHA-256 of its own data, so the calling model verifies OFFLINE that the tool didn't lie or get tampered between server and model. This probe calls `mneme.hydra.forge` through the REAL MCP JSON-RPC server, then independently verifies the returned `_proof`: the Ed25519 signature must be valid AND sha256(canonical(data minus _proof)) must equal the signed dataHash — output you can check, not output you must believe.",
349
+ run: async (ctx) => {
350
+ const t0 = Date.now();
351
+ try {
352
+ const canon = (v) => {
353
+ if (v === null || typeof v !== "object")
354
+ return JSON.stringify(v) ?? "null";
355
+ if (Array.isArray(v))
356
+ return "[" + v.map(canon).join(",") + "]";
357
+ const k = Object.keys(v).sort();
358
+ return "{" + k.map((x) => JSON.stringify(x) + ":" + canon(v[x])).join(",") + "}";
359
+ };
360
+ const { createHash } = await import("node:crypto");
361
+ const sha = (s) => createHash("sha256").update(s, "utf8").digest("hex");
362
+ const text = "alpha beta alpha beta gamma delta. alpha beta alpha beta gamma delta. ".repeat(8);
363
+ const raw = await spawnMcpCall(ctx.cwd, "mneme.hydra.forge", { text }, 30000);
364
+ let parsed;
365
+ try {
366
+ parsed = JSON.parse(raw);
367
+ }
368
+ catch {
369
+ parsed = {};
370
+ }
371
+ const data = parsed.data ?? parsed;
372
+ const proof = data._proof;
373
+ const score = (data.gauntlet)?.score;
374
+ if (!proof || !proof.receipt)
375
+ return { value: 0, evidence: `no _proof in MCP result (score=${score})`, dtMs: Date.now() - t0 };
376
+ const core = await import("../notary/receipt.js");
377
+ const sig = core.verifyReceipt(proof.receipt);
378
+ const bare = { ...data };
379
+ delete bare._proof;
380
+ const hashOk = sha(canon(bare)) === proof.dataHash;
381
+ const ok = score === 100 && sig.valid && hashOk;
382
+ return { value: ok ? 1 : 0, evidence: `score=${score} sigValid=${sig.valid} dataHashMatches=${hashOk}`, dtMs: Date.now() - t0 };
383
+ }
384
+ catch (e) {
385
+ return { value: 0, evidence: `threw: ${e.message}`, dtMs: Date.now() - t0 };
386
+ }
387
+ },
388
+ },
389
+ {
390
+ id: "probe.hydra.temporal_guarded_replay",
391
+ kind: "boolean",
392
+ description: "HYDRA GUARD × CHAIN fusion (v2.100.0 — every flow wired): the provenance chain computes its OWN atrophy clock and drives the guard. Replaying a past step, an entry added long ago and never touched is STALE and expands only to a signed abstract (cold knowledge redacted; fresh kept byte-exact). Trust is derived deterministically from chain history; only PROVEN-old entries go stale (Padgett: unknown ⇒ fresh). This probe builds a 4-step chain where an ancient phrase ages out while a tip phrase stays fresh, then asserts END-TO-END: guarded expansion redacts the cold phrase, keeps the fresh one byte-exact, and the fusion gauntlet = 100 (deterministic ∧ freshAtTip ∧ provenOnly ∧ stable).",
393
+ run: async (ctx) => {
394
+ const t0 = Date.now();
395
+ void ctx;
396
+ try {
397
+ const H = await import("../hydra/index.js");
398
+ const anc = "ancient axiom holds forever and ever. ".repeat(4);
399
+ const nw = "brand new thing just landed today hot. ".repeat(4);
400
+ const steps = [anc, anc + "\nx rule one connects here now. ".repeat(4), anc + "\nx rule one connects here now. ".repeat(4) + "\ny fact two arrives newest one. ".repeat(4), anc + "\nx rule one connects here now. ".repeat(4) + "\ny fact two arrives newest one. ".repeat(4) + "\n" + nw];
401
+ let chain = [];
402
+ steps.forEach((c, i) => { chain = H.appendToChain(process.cwd(), chain, H.forgeCodebook(c, { minHits: 2 }).codebook, 1700000000000 + i).chain; });
403
+ const tipCorpus = steps[steps.length - 1];
404
+ const r = H.guardedReplay(chain, chain.length - 1, 1);
405
+ const cb = r.codebook;
406
+ const guarded = H.expandGuarded(H.compress(tipCorpus, cb), cb, H.trustFromMap(r.trust.trustMap));
407
+ const coldRedacted = !guarded.includes("ancient axiom holds forever and ever");
408
+ const freshKept = guarded.includes("brand new thing just landed today hot");
409
+ const g = H.guardedChainGauntlet(chain, 1);
410
+ const ok = g.score === 100 && coldRedacted && freshKept && r.trust.staleCount > 0;
411
+ return { value: ok ? 1 : 0, evidence: `gauntlet=${g.score} coldRedacted=${coldRedacted} freshKept=${freshKept} stale=${r.trust.staleCount} fresh=${r.trust.freshCount} det=${g.deterministic} provenOnly=${g.provenOnly}`, dtMs: Date.now() - t0 };
412
+ }
413
+ catch (e) {
414
+ return { value: 0, evidence: `threw: ${e.message}`, dtMs: Date.now() - t0 };
415
+ }
416
+ },
417
+ },
345
418
  {
346
419
  id: "probe.hydra.provenance_chain",
347
420
  kind: "boolean",