@mneme-ai/core 2.95.0 → 2.97.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.map +1 -1
- package/dist/agent_manifest.js +1 -0
- package/dist/agent_manifest.js.map +1 -1
- package/dist/hydra/analytic.d.ts +103 -0
- package/dist/hydra/analytic.d.ts.map +1 -0
- package/dist/hydra/analytic.js +161 -0
- package/dist/hydra/analytic.js.map +1 -0
- package/dist/hydra/attest.d.ts +60 -0
- package/dist/hydra/attest.d.ts.map +1 -0
- package/dist/hydra/attest.js +84 -0
- package/dist/hydra/attest.js.map +1 -0
- package/dist/hydra/engine.d.ts +84 -0
- package/dist/hydra/engine.d.ts.map +1 -0
- package/dist/hydra/engine.js +108 -0
- package/dist/hydra/engine.js.map +1 -0
- package/dist/hydra/guard.d.ts +75 -0
- package/dist/hydra/guard.d.ts.map +1 -0
- package/dist/hydra/guard.js +171 -0
- package/dist/hydra/guard.js.map +1 -0
- package/dist/hydra/guard.test.d.ts +2 -0
- package/dist/hydra/guard.test.d.ts.map +1 -0
- package/dist/hydra/guard.test.js +79 -0
- package/dist/hydra/guard.test.js.map +1 -0
- package/dist/hydra/hydra.test.d.ts +2 -0
- package/dist/hydra/hydra.test.d.ts.map +1 -0
- package/dist/hydra/hydra.test.js +90 -0
- package/dist/hydra/hydra.test.js.map +1 -0
- package/dist/hydra/index.d.ts +77 -0
- package/dist/hydra/index.d.ts.map +1 -0
- package/dist/hydra/index.js +62 -0
- package/dist/hydra/index.js.map +1 -0
- package/dist/hydra/mine.d.ts +42 -0
- package/dist/hydra/mine.d.ts.map +1 -0
- package/dist/hydra/mine.js +72 -0
- package/dist/hydra/mine.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/truth_gate/probes.d.ts.map +1 -1
- package/dist/truth_gate/probes.js +58 -0
- package/dist/truth_gate/probes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.97.0 — HYDRA · GUARDED EXPANSION ("Time-To-Trust").
|
|
3
|
+
*
|
|
4
|
+
* The fusion gem: HYDRA codebook × the knowledge-atrophy clock × NOTARY.
|
|
5
|
+
* A normal expand() is byte-lossless. A GUARDED expand is lossless for
|
|
6
|
+
* TRUSTED content but provably REDACTS stale/quarantined content down to a
|
|
7
|
+
* signed abstract (sha256 + byte-count) — so an AI literally cannot
|
|
8
|
+
* hallucinate from expired memory, yet can still verify the redacted
|
|
9
|
+
* region's identity and request re-hydration.
|
|
10
|
+
*
|
|
11
|
+
* Prior-art research (v2.96) found no signed + lossless + TTL-guarded
|
|
12
|
+
* codebook anywhere. This is that unfilled lane, made measurable:
|
|
13
|
+
* - all-fresh ⟹ guarded output is BYTE-IDENTICAL to the original (boolean)
|
|
14
|
+
* - any stale entry ⟹ its raw phrase NEVER appears, its sha256 DOES,
|
|
15
|
+
* fresh entries stay byte-exact (boolean)
|
|
16
|
+
* - deterministic: same input → same bytes (boolean)
|
|
17
|
+
*
|
|
18
|
+
* STABILITY: every function is total — it never throws. Malformed input,
|
|
19
|
+
* a missing field, an unknown trust level → the SAFEST outcome (redact).
|
|
20
|
+
* The 108-error rule: when in doubt, guard, don't crash and don't leak.
|
|
21
|
+
*/
|
|
22
|
+
import { sha256Hex } from "./engine.js";
|
|
23
|
+
export function trustFromMap(map) {
|
|
24
|
+
return (sym) => (map && Object.prototype.hasOwnProperty.call(map, sym) ? map[sym] ?? "fresh" : "fresh");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The deterministic redaction placeholder for a guarded entry. Carries the
|
|
28
|
+
* sha256 of the original phrase (identity-verifiable) + byte count + the
|
|
29
|
+
* reason — but NOT the content. Re-hydration replaces it with the real
|
|
30
|
+
* phrase once the symbol is re-verified.
|
|
31
|
+
*/
|
|
32
|
+
export function guardedPlaceholder(phrase, level) {
|
|
33
|
+
const sha = sha256Hex(phrase).slice(0, 16);
|
|
34
|
+
const bytes = Buffer.byteLength(phrase, "utf8");
|
|
35
|
+
return `[mneme:redacted trust=${level} sha256=${sha} bytes=${bytes} — re-verify to access]`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* GUARDED EXPAND. Fresh symbols expand to their phrase (byte-exact); stale
|
|
39
|
+
* or quarantined symbols expand to a signed abstract. Total: never throws;
|
|
40
|
+
* a bad entry is treated as quarantined (fail-closed, never leak).
|
|
41
|
+
*/
|
|
42
|
+
export function expandGuarded(encoded, cb, trustOf) {
|
|
43
|
+
if (typeof encoded !== "string")
|
|
44
|
+
return "";
|
|
45
|
+
if (!cb || !Array.isArray(cb.entries))
|
|
46
|
+
return encoded;
|
|
47
|
+
let out = encoded;
|
|
48
|
+
for (const e of cb.entries) {
|
|
49
|
+
if (!e || typeof e.sym !== "string" || typeof e.phrase !== "string" || e.phrase.length === 0)
|
|
50
|
+
continue;
|
|
51
|
+
let level;
|
|
52
|
+
try {
|
|
53
|
+
level = trustOf(e.sym) ?? "fresh";
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
level = "quarantined";
|
|
57
|
+
}
|
|
58
|
+
const replacement = level === "fresh" ? e.phrase : guardedPlaceholder(e.phrase, level);
|
|
59
|
+
out = out.split(e.sym).join(replacement);
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* RE-HYDRATE a guarded output: given the set of symbols whose access has
|
|
65
|
+
* been re-verified, replace their placeholders with the real phrase. Total:
|
|
66
|
+
* unknown symbols / malformed input are left untouched (no throw, no leak).
|
|
67
|
+
*/
|
|
68
|
+
export function rehydrate(encoded, cb, approvedSyms, trustOf) {
|
|
69
|
+
if (typeof encoded !== "string")
|
|
70
|
+
return "";
|
|
71
|
+
if (!cb || !Array.isArray(cb.entries))
|
|
72
|
+
return encoded;
|
|
73
|
+
const approved = new Set();
|
|
74
|
+
try {
|
|
75
|
+
for (const s of approvedSyms)
|
|
76
|
+
approved.add(s);
|
|
77
|
+
}
|
|
78
|
+
catch { /* leave empty */ }
|
|
79
|
+
const t = (sym) => (approved.has(sym) ? "fresh" : (() => { try {
|
|
80
|
+
return trustOf(sym) ?? "fresh";
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return "quarantined";
|
|
84
|
+
} })());
|
|
85
|
+
return expandGuarded(encoded, cb, t);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The guarded gauntlet — proves the four Time-To-Trust invariants over a
|
|
89
|
+
* concrete trust assignment. Total + deterministic. `compressFn` lets the
|
|
90
|
+
* caller pass the engine's compress to avoid an import cycle; if omitted we
|
|
91
|
+
* verify directly against the codebook entries.
|
|
92
|
+
*/
|
|
93
|
+
export function guardedGauntlet(original, encoded, cb, trustMap) {
|
|
94
|
+
try {
|
|
95
|
+
const allFresh = () => "fresh";
|
|
96
|
+
const resolver = trustFromMap(trustMap);
|
|
97
|
+
const freshOut = expandGuarded(encoded, cb, allFresh);
|
|
98
|
+
const freshLossless = sha256Hex(freshOut) === sha256Hex(original);
|
|
99
|
+
const guarded1 = expandGuarded(encoded, cb, resolver);
|
|
100
|
+
const guarded2 = expandGuarded(encoded, cb, resolver);
|
|
101
|
+
const deterministic = sha256Hex(guarded1) === sha256Hex(guarded2);
|
|
102
|
+
let redactionSound = true;
|
|
103
|
+
let freshPreserved = true;
|
|
104
|
+
let redactedCount = 0;
|
|
105
|
+
let freshCount = 0;
|
|
106
|
+
for (const e of cb.entries) {
|
|
107
|
+
if (!e || typeof e.phrase !== "string" || e.phrase.length === 0)
|
|
108
|
+
continue;
|
|
109
|
+
const level = trustMap[e.sym] ?? "fresh";
|
|
110
|
+
if (level === "fresh") {
|
|
111
|
+
freshCount++;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
redactedCount++;
|
|
115
|
+
// Correct, honest invariant — per OCCURRENCE, not per text:
|
|
116
|
+
// - the stale SYMBOL must be fully consumed (no un-redacted
|
|
117
|
+
// expansion survives), and
|
|
118
|
+
// - IF the symbol actually occurs in the encoded stream, its
|
|
119
|
+
// identity sha must appear (proof the redaction happened).
|
|
120
|
+
// A "dead" symbol (its phrase was nested-consumed by a longer phrase
|
|
121
|
+
// during compress, so it never appears in `encoded`) has nothing to
|
|
122
|
+
// redact → vacuously sound. We do NOT require the phrase TEXT to be
|
|
123
|
+
// globally absent: identical text inside a FRESH entry the caller
|
|
124
|
+
// trusts is not a leak of the stale source.
|
|
125
|
+
if (guarded1.includes(e.sym))
|
|
126
|
+
redactionSound = false;
|
|
127
|
+
if (encoded.includes(e.sym)) {
|
|
128
|
+
const sha = sha256Hex(e.phrase).slice(0, 16);
|
|
129
|
+
if (!guarded1.includes(sha))
|
|
130
|
+
redactionSound = false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Fresh-preserved: redacting some entries must not corrupt the fresh
|
|
134
|
+
// ones. We check by re-hydrating ALL symbols → must equal fresh output.
|
|
135
|
+
const rehydrated = rehydrate(encoded, cb, cb.entries.map((e) => e.sym), resolver);
|
|
136
|
+
freshPreserved = sha256Hex(rehydrated) === sha256Hex(freshOut);
|
|
137
|
+
const perfect = freshLossless && redactionSound && freshPreserved && deterministic;
|
|
138
|
+
return { freshLossless, redactionSound, freshPreserved, deterministic, redactedCount, freshCount, score: perfect ? 100 : 0 };
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Total: any unexpected failure → score 0, never throw.
|
|
142
|
+
return { freshLossless: false, redactionSound: false, freshPreserved: false, deterministic: false, redactedCount: 0, freshCount: 0, score: 0 };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Compose the ATROPHY clock: mark a codebook's entries stale when the
|
|
147
|
+
* caller's age map says their source region is older than the half-life.
|
|
148
|
+
* `ageMsOf` returns the age (ms) of the source behind a symbol, or
|
|
149
|
+
* undefined if unknown (unknown ⇒ fresh, the least-surprising default —
|
|
150
|
+
* we only redact what we can PROVE is stale). Total; never throws.
|
|
151
|
+
*/
|
|
152
|
+
export function trustByAtrophy(cb, ageMsOf, halfLifeMs) {
|
|
153
|
+
const out = {};
|
|
154
|
+
if (!cb || !Array.isArray(cb.entries) || !(halfLifeMs > 0))
|
|
155
|
+
return out;
|
|
156
|
+
for (const e of cb.entries) {
|
|
157
|
+
if (!e || typeof e.sym !== "string")
|
|
158
|
+
continue;
|
|
159
|
+
let age;
|
|
160
|
+
try {
|
|
161
|
+
age = ageMsOf(e.sym);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
age = undefined;
|
|
165
|
+
}
|
|
166
|
+
if (typeof age === "number" && Number.isFinite(age) && age > halfLifeMs * 2)
|
|
167
|
+
out[e.sym] = "stale";
|
|
168
|
+
}
|
|
169
|
+
return out;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/hydra/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAiB,SAAS,EAAE,MAAM,aAAa,CAAC;AAOvD,MAAM,UAAU,YAAY,CAAC,GAA+B;IAC1D,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC1G,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,KAAiB;IAClE,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,OAAO,yBAAyB,KAAK,WAAW,GAAG,UAAU,KAAK,yBAAyB,CAAC;AAC9F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,EAAY,EAAE,OAAsB;IACjF,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC3C,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACtD,IAAI,GAAG,GAAG,OAAO,CAAC;IAClB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACvG,IAAI,KAAiB,CAAC;QACtB,IAAI,CAAC;YAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,KAAK,GAAG,aAAa,CAAC;QAAC,CAAC;QAC3E,MAAM,WAAW,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACvF,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,EAAY,EAAE,YAA8B,EAAE,OAAsB;IAC7G,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC3C,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,IAAI,CAAC;QAAC,KAAK,MAAM,CAAC,IAAI,YAAY;YAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAClF,MAAM,CAAC,GAAkB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAAC,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,aAAa,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxJ,OAAO,aAAa,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC;AAiBD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,OAAe,EACf,EAAY,EACZ,QAAoC;IAEpC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAkB,GAAG,EAAE,CAAC,OAAO,CAAC;QAC9C,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC,QAAQ,CAAC,CAAC;QAElE,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC,QAAQ,CAAC,CAAC;QAElE,IAAI,cAAc,GAAG,IAAI,CAAC;QAC1B,IAAI,cAAc,GAAG,IAAI,CAAC;QAC1B,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAC1E,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC;YACzC,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;gBACtB,UAAU,EAAE,CAAC;gBACb,SAAS;YACX,CAAC;YACD,aAAa,EAAE,CAAC;YAChB,4DAA4D;YAC5D,8DAA8D;YAC9D,+BAA+B;YAC/B,+DAA+D;YAC/D,+DAA+D;YAC/D,qEAAqE;YACrE,oEAAoE;YACpE,oEAAoE;YACpE,kEAAkE;YAClE,4CAA4C;YAC5C,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;gBAAE,cAAc,GAAG,KAAK,CAAC;YACrD,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;oBAAE,cAAc,GAAG,KAAK,CAAC;YACtD,CAAC;QACH,CAAC;QACD,qEAAqE;QACrE,wEAAwE;QACxE,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;QAClF,cAAc,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,SAAS,CAAC,QAAQ,CAAC,CAAC;QAE/D,MAAM,OAAO,GAAG,aAAa,IAAI,cAAc,IAAI,cAAc,IAAI,aAAa,CAAC;QACnF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/H,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;QACxD,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IACjJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,EAAY,EAAE,OAA4C,EAAE,UAAkB;IAC3G,MAAM,GAAG,GAA+B,EAAE,CAAC;IAC3C,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;QAAE,OAAO,GAAG,CAAC;IACvE,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ;YAAE,SAAS;QAC9C,IAAI,GAAuB,CAAC;QAC5B,IAAI,CAAC;YAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,GAAG,GAAG,SAAS,CAAC;QAAC,CAAC;QACxD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,UAAU,GAAG,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;IACpG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.test.d.ts","sourceRoot":"","sources":["../../src/hydra/guard.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { forgeCodebook, compress, sha256Hex } from "./index.js";
|
|
3
|
+
import { expandGuarded, rehydrate, guardedGauntlet, trustFromMap, trustByAtrophy, guardedPlaceholder } from "./guard.js";
|
|
4
|
+
const CORPUS = [
|
|
5
|
+
"fresh module does the new thing. fresh module is current.",
|
|
6
|
+
"legacy helper is ancient and stale. legacy helper has not changed in years.",
|
|
7
|
+
].join("\n").repeat(6);
|
|
8
|
+
function setup() {
|
|
9
|
+
const { codebook } = forgeCodebook(CORPUS, { minHits: 2 });
|
|
10
|
+
const encoded = compress(CORPUS, codebook);
|
|
11
|
+
return { codebook, encoded };
|
|
12
|
+
}
|
|
13
|
+
describe("v2.97 HYDRA GUARD · Time-To-Trust", () => {
|
|
14
|
+
it("all-fresh guarded expand is byte-identical to the original", () => {
|
|
15
|
+
const { codebook, encoded } = setup();
|
|
16
|
+
const out = expandGuarded(encoded, codebook, () => "fresh");
|
|
17
|
+
expect(out).toBe(CORPUS);
|
|
18
|
+
});
|
|
19
|
+
it("a stale entry is redacted: raw phrase gone, sha present, fresh untouched", () => {
|
|
20
|
+
const { codebook, encoded } = setup();
|
|
21
|
+
const stale = codebook.entries[0];
|
|
22
|
+
const map = { [stale.sym]: "stale" };
|
|
23
|
+
const out = expandGuarded(encoded, codebook, trustFromMap(map));
|
|
24
|
+
expect(out.includes(stale.phrase)).toBe(false); // raw content gone
|
|
25
|
+
expect(out).toContain(sha256Hex(stale.phrase).slice(0, 16)); // identity still verifiable
|
|
26
|
+
// fresh preserved: a fresh entry that lives OUTSIDE the stale region
|
|
27
|
+
// still expands byte-exact.
|
|
28
|
+
const other = codebook.entries.find((e) => e.sym !== stale.sym && !stale.phrase.includes(e.phrase) && CORPUS.split(stale.phrase).join("").includes(e.phrase));
|
|
29
|
+
if (other)
|
|
30
|
+
expect(out).toContain(other.phrase); // fresh preserved
|
|
31
|
+
});
|
|
32
|
+
it("re-hydration restores a redacted entry once approved", () => {
|
|
33
|
+
const { codebook, encoded } = setup();
|
|
34
|
+
const stale = codebook.entries[0];
|
|
35
|
+
const map = { [stale.sym]: "stale" };
|
|
36
|
+
const guarded = expandGuarded(encoded, codebook, trustFromMap(map));
|
|
37
|
+
expect(guarded.includes(stale.phrase)).toBe(false);
|
|
38
|
+
const restored = rehydrate(encoded, codebook, [stale.sym], trustFromMap(map));
|
|
39
|
+
expect(restored).toContain(stale.phrase); // disclosed after approval
|
|
40
|
+
});
|
|
41
|
+
it("guarded gauntlet scores 100 on a sound trust assignment", () => {
|
|
42
|
+
const { codebook, encoded } = setup();
|
|
43
|
+
const map = {};
|
|
44
|
+
if (codebook.entries[0])
|
|
45
|
+
map[codebook.entries[0].sym] = "stale";
|
|
46
|
+
const g = guardedGauntlet(CORPUS, encoded, codebook, map);
|
|
47
|
+
expect(g.freshLossless).toBe(true);
|
|
48
|
+
expect(g.redactionSound).toBe(true);
|
|
49
|
+
expect(g.freshPreserved).toBe(true);
|
|
50
|
+
expect(g.deterministic).toBe(true);
|
|
51
|
+
expect(g.score).toBe(100);
|
|
52
|
+
});
|
|
53
|
+
it("STABILITY — total functions never throw on malformed input", () => {
|
|
54
|
+
const bad = { v: 1, open: "", close: "", corpusHash: "", entries: [null, { sym: "x", phrase: "y" }] };
|
|
55
|
+
expect(() => expandGuarded("anything", bad, () => { throw new Error("boom"); })).not.toThrow();
|
|
56
|
+
expect(expandGuarded(null, bad, () => "fresh")).toBe("");
|
|
57
|
+
expect(guardedGauntlet("", "", bad, {}).score).toBe(0);
|
|
58
|
+
expect(rehydrate(undefined, bad, ["x"], () => "fresh")).toBe("");
|
|
59
|
+
});
|
|
60
|
+
it("ATROPHY composition — only PROVEN-old entries go stale (unknown ⇒ fresh)", () => {
|
|
61
|
+
const { codebook } = setup();
|
|
62
|
+
const halfLife = 1000;
|
|
63
|
+
const old = codebook.entries[0]?.sym;
|
|
64
|
+
const map = trustByAtrophy(codebook, (sym) => (sym === old ? halfLife * 10 : undefined), halfLife);
|
|
65
|
+
if (old)
|
|
66
|
+
expect(map[old]).toBe("stale");
|
|
67
|
+
// unknown age → NOT in the map → treated fresh (we only redact proven-stale)
|
|
68
|
+
const other = codebook.entries.find((e) => e.sym !== old);
|
|
69
|
+
if (other)
|
|
70
|
+
expect(map[other.sym]).toBeUndefined();
|
|
71
|
+
});
|
|
72
|
+
it("placeholder carries identity but not content", () => {
|
|
73
|
+
const ph = guardedPlaceholder("super secret phrase", "stale");
|
|
74
|
+
expect(ph).not.toContain("super secret phrase");
|
|
75
|
+
expect(ph).toContain(sha256Hex("super secret phrase").slice(0, 16));
|
|
76
|
+
expect(ph).toContain("trust=stale");
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=guard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.test.js","sourceRoot":"","sources":["../../src/hydra/guard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydra.test.d.ts","sourceRoot":"","sources":["../../src/hydra/hydra.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { forgeCodebook, collisions, compress, expand, proveLossless, chooseMarkers, sha256Hex, mineCandidates, hydraForge, verifyCodebook, } from "./index.js";
|
|
3
|
+
const CORPUS = [
|
|
4
|
+
"HMAC-chained ledger is tamper-evident. The HMAC-chained ledger signs each row.",
|
|
5
|
+
"Ed25519-signed receipt verifies offline. Another Ed25519-signed receipt chains.",
|
|
6
|
+
"HMAC-chained ledger plus Ed25519-signed receipt equals tamper-evident provenance.",
|
|
7
|
+
].join("\n").repeat(4);
|
|
8
|
+
describe("v2.96 HYDRA · L3+L4 lossless engine", () => {
|
|
9
|
+
it("round-trips byte-identical (lossless proof is true)", () => {
|
|
10
|
+
const { codebook } = forgeCodebook(CORPUS, { minHits: 2 });
|
|
11
|
+
const p = proveLossless(CORPUS, codebook);
|
|
12
|
+
expect(p.lossless).toBe(true);
|
|
13
|
+
expect(p.originalHash).toBe(p.roundTripHash);
|
|
14
|
+
expect(expand(compress(CORPUS, codebook), codebook)).toBe(CORPUS);
|
|
15
|
+
});
|
|
16
|
+
it("markers are PUA chars absent from the corpus", () => {
|
|
17
|
+
const [o, c] = chooseMarkers(CORPUS, []);
|
|
18
|
+
expect(CORPUS.includes(o)).toBe(false);
|
|
19
|
+
expect(CORPUS.includes(c)).toBe(false);
|
|
20
|
+
expect(o.charCodeAt(0)).toBeGreaterThanOrEqual(0xe000);
|
|
21
|
+
});
|
|
22
|
+
it("does NOT munge a corpus that already contains a candidate marker — falls back", () => {
|
|
23
|
+
const tricky = String.fromCharCode(0xe000) + " " + CORPUS; // corpus carries the first marker
|
|
24
|
+
const { codebook } = forgeCodebook(tricky, { minHits: 2 });
|
|
25
|
+
expect(proveLossless(tricky, codebook).lossless).toBe(true); // still lossless via fallback marker
|
|
26
|
+
expect(codebook.open).not.toBe(String.fromCharCode(0xe000));
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe("v2.96 HYDRA · L7 collision-free (can't hold two meanings)", () => {
|
|
30
|
+
it("a forged codebook has zero collisions", () => {
|
|
31
|
+
const { codebook } = forgeCodebook(CORPUS, { minHits: 2 });
|
|
32
|
+
expect(collisions(codebook).collisions).toBe(0);
|
|
33
|
+
});
|
|
34
|
+
it("detects an injected duplicate symbol / phrase", () => {
|
|
35
|
+
const { codebook } = forgeCodebook(CORPUS, { minHits: 2 });
|
|
36
|
+
const dup = { v: 1, open: codebook.open, close: codebook.close, corpusHash: codebook.corpusHash,
|
|
37
|
+
entries: [...codebook.entries, codebook.entries[0]] };
|
|
38
|
+
expect(collisions(dup).collisions).toBeGreaterThan(0);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe("v2.96 HYDRA · L9 self-refining forge converges + L6 portable", () => {
|
|
42
|
+
it("converges with a perfect gauntlet (score 100)", () => {
|
|
43
|
+
const r = forgeCodebook(CORPUS, { minHits: 2 });
|
|
44
|
+
expect(r.converged).toBe(true);
|
|
45
|
+
expect(r.gauntlet.score).toBe(100);
|
|
46
|
+
expect(r.gauntlet.lossless).toBe(true);
|
|
47
|
+
expect(r.gauntlet.collisions).toBe(0);
|
|
48
|
+
expect(r.gauntlet.portable).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
it("is deterministic — same corpus → identical codebook hash", () => {
|
|
51
|
+
const a = forgeCodebook(CORPUS, { minHits: 2 });
|
|
52
|
+
const b = forgeCodebook(CORPUS, { minHits: 2 });
|
|
53
|
+
expect(sha256Hex(JSON.stringify(a.codebook.entries))).toBe(sha256Hex(JSON.stringify(b.codebook.entries)));
|
|
54
|
+
});
|
|
55
|
+
it("reports an HONEST net ratio (never claims single-shot magic)", () => {
|
|
56
|
+
const r = forgeCodebook(CORPUS, { minHits: 2 });
|
|
57
|
+
expect(r.gauntlet.netRatio).toBeGreaterThan(0);
|
|
58
|
+
expect(typeof r.gauntlet.codebookBytes).toBe("number");
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe("v2.96 HYDRA · L5 signed + L8 energy (offline-verifiable)", () => {
|
|
62
|
+
it("signs the codebook and verifies offline; catches tampering", () => {
|
|
63
|
+
const f = hydraForge(process.cwd(), CORPUS, 1700000000000, { minHits: 2 });
|
|
64
|
+
expect(verifyCodebook(f.receipt, f.forge.codebook).bound).toBe(true);
|
|
65
|
+
const tampered = JSON.parse(JSON.stringify(f.forge.codebook));
|
|
66
|
+
tampered.entries[0].phrase += "X";
|
|
67
|
+
expect(verifyCodebook(f.receipt, tampered).bound).toBe(false); // swap-after-sign caught
|
|
68
|
+
});
|
|
69
|
+
it("mints an energy certificate and binds axioms (L7/L8)", () => {
|
|
70
|
+
const f = hydraForge(process.cwd(), CORPUS, 1700000000000, { minHits: 2 });
|
|
71
|
+
expect(f.energy.bytesSaved).toBeGreaterThanOrEqual(0);
|
|
72
|
+
expect(f.axioms.length).toBe(f.forge.codebook.entries.length);
|
|
73
|
+
expect(f.axioms[0]?.claim).toContain("expands to");
|
|
74
|
+
});
|
|
75
|
+
it("L6 portable artifact carries a self-describing grammar", () => {
|
|
76
|
+
const f = hydraForge(process.cwd(), CORPUS, 1700000000000, { minHits: 2 });
|
|
77
|
+
expect(f.portable.kind).toBe("hydra/portable-codebook");
|
|
78
|
+
expect(f.portable.grammar.rule).toContain("replace");
|
|
79
|
+
expect(f.portable.codebookHash).toHaveLength(64);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe("v2.96 HYDRA · L1/L2 mining is MDL-positive", () => {
|
|
83
|
+
it("only mines phrases that pay back more than they cost", () => {
|
|
84
|
+
const cands = mineCandidates(CORPUS, { minHits: 2 });
|
|
85
|
+
expect(cands.length).toBeGreaterThan(0);
|
|
86
|
+
for (const c of cands)
|
|
87
|
+
expect(c.gain).toBeGreaterThan(0);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=hydra.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydra.test.js","sourceRoot":"","sources":["../../src/hydra/hydra.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.96.0 — HYDRA · public surface. Signed, deterministic, provably-
|
|
3
|
+
* lossless, vendor-neutral context codebook that Mneme forges from its own
|
|
4
|
+
* corpus. The 9 facets of the gem:
|
|
5
|
+
*
|
|
6
|
+
* L1 semantic mining ········· mine.ts (mineCandidates)
|
|
7
|
+
* L2 MDL-optimal selection ··· mine.ts (gain scoring)
|
|
8
|
+
* L3 deterministic expansion · engine.ts (compress/expand)
|
|
9
|
+
* L4 lossless proof ·········· engine.ts (proveLossless — boolean)
|
|
10
|
+
* L5 signed codebook ········· attest.ts (signCodebook — NOTARY)
|
|
11
|
+
* L6 vendor-neutral ·········· this file (portableArtifact)
|
|
12
|
+
* L7 axiom-lattice binding ··· analytic.ts+here(collisions + bindAxioms)
|
|
13
|
+
* L8 energy certificate ······ attest.ts (mintEnergyCert)
|
|
14
|
+
* L9 self-refining forge ····· analytic.ts (forgeCodebook — converges)
|
|
15
|
+
*
|
|
16
|
+
* The super-bot analytic engine (forgeCodebook) keeps improving until it
|
|
17
|
+
* cannot add a byte of value, gating every step on lossless ∧ no-collision
|
|
18
|
+
* so it can never ship a lie.
|
|
19
|
+
*/
|
|
20
|
+
export * from "./engine.js";
|
|
21
|
+
export * from "./mine.js";
|
|
22
|
+
export * from "./analytic.js";
|
|
23
|
+
export * from "./attest.js";
|
|
24
|
+
export * from "./guard.js";
|
|
25
|
+
import type { Codebook } from "./engine.js";
|
|
26
|
+
import { type ForgeOpts, type ForgeResult, type Gauntlet } from "./analytic.js";
|
|
27
|
+
import { type EnergyCert } from "./attest.js";
|
|
28
|
+
import type { NotaryReceipt } from "../notary/receipt.js";
|
|
29
|
+
/**
|
|
30
|
+
* L6 — the VENDOR-NEUTRAL portable artifact. Because a deterministic engine
|
|
31
|
+
* expands this BEFORE any LLM sees it, the artifact is tokenizer-independent
|
|
32
|
+
* BY CONSTRUCTION — it works identically for Claude / GPT / Gemini / open
|
|
33
|
+
* models. The bundle carries everything a third party needs to expand +
|
|
34
|
+
* verify offline: the codebook, its signature, and the expansion grammar
|
|
35
|
+
* (which is simply "replace sym → phrase"; no model required).
|
|
36
|
+
*/
|
|
37
|
+
export interface PortableArtifact {
|
|
38
|
+
kind: "hydra/portable-codebook";
|
|
39
|
+
v: 1;
|
|
40
|
+
codebook: Codebook;
|
|
41
|
+
/** NOTARY receipt binding the codebook (L5). */
|
|
42
|
+
receipt: NotaryReceipt;
|
|
43
|
+
/** Self-describing expansion grammar so ANY engine can rehydrate. */
|
|
44
|
+
grammar: {
|
|
45
|
+
rule: string;
|
|
46
|
+
markerOpen: string;
|
|
47
|
+
markerClose: string;
|
|
48
|
+
};
|
|
49
|
+
codebookHash: string;
|
|
50
|
+
}
|
|
51
|
+
export declare function portableArtifact(cb: Codebook, receipt: NotaryReceipt): PortableArtifact;
|
|
52
|
+
/**
|
|
53
|
+
* L7 — bind each codebook entry as a signed "axiom": `sym ⇒ phrase`. These
|
|
54
|
+
* compose with Mneme's truth-kernel lattice (each is a deterministic,
|
|
55
|
+
* collision-checked fact). Returned as a list ready for assertClaim/lattice
|
|
56
|
+
* recording; emitted here so HYDRA stays decoupled from lattice I/O.
|
|
57
|
+
*/
|
|
58
|
+
export interface CodebookAxiom {
|
|
59
|
+
claim: string;
|
|
60
|
+
sym: string;
|
|
61
|
+
phrase: string;
|
|
62
|
+
}
|
|
63
|
+
export declare function bindAxioms(cb: Codebook): CodebookAxiom[];
|
|
64
|
+
export interface HydraForgeResult {
|
|
65
|
+
forge: ForgeResult;
|
|
66
|
+
gauntlet: Gauntlet;
|
|
67
|
+
receipt: NotaryReceipt;
|
|
68
|
+
energy: EnergyCert;
|
|
69
|
+
portable: PortableArtifact;
|
|
70
|
+
axioms: CodebookAxiom[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* THE FULL PIPELINE — L1→L9 in one deterministic call. `at` is the issue
|
|
74
|
+
* timestamp (CLI passes Date.now(); tests pass a fixed value).
|
|
75
|
+
*/
|
|
76
|
+
export declare function hydraForge(repoRoot: string, corpus: string, at: number, opts?: ForgeOpts): HydraForgeResult;
|
|
77
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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;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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.96.0 — HYDRA · public surface. Signed, deterministic, provably-
|
|
3
|
+
* lossless, vendor-neutral context codebook that Mneme forges from its own
|
|
4
|
+
* corpus. The 9 facets of the gem:
|
|
5
|
+
*
|
|
6
|
+
* L1 semantic mining ········· mine.ts (mineCandidates)
|
|
7
|
+
* L2 MDL-optimal selection ··· mine.ts (gain scoring)
|
|
8
|
+
* L3 deterministic expansion · engine.ts (compress/expand)
|
|
9
|
+
* L4 lossless proof ·········· engine.ts (proveLossless — boolean)
|
|
10
|
+
* L5 signed codebook ········· attest.ts (signCodebook — NOTARY)
|
|
11
|
+
* L6 vendor-neutral ·········· this file (portableArtifact)
|
|
12
|
+
* L7 axiom-lattice binding ··· analytic.ts+here(collisions + bindAxioms)
|
|
13
|
+
* L8 energy certificate ······ attest.ts (mintEnergyCert)
|
|
14
|
+
* L9 self-refining forge ····· analytic.ts (forgeCodebook — converges)
|
|
15
|
+
*
|
|
16
|
+
* The super-bot analytic engine (forgeCodebook) keeps improving until it
|
|
17
|
+
* cannot add a byte of value, gating every step on lossless ∧ no-collision
|
|
18
|
+
* so it can never ship a lie.
|
|
19
|
+
*/
|
|
20
|
+
export * from "./engine.js";
|
|
21
|
+
export * from "./mine.js";
|
|
22
|
+
export * from "./analytic.js";
|
|
23
|
+
export * from "./attest.js";
|
|
24
|
+
export * from "./guard.js";
|
|
25
|
+
import { sha256Hex } from "./engine.js";
|
|
26
|
+
import { forgeCodebook, gauntlet } from "./analytic.js";
|
|
27
|
+
import { signCodebook, mintEnergyCert, canonicalizeCodebook } from "./attest.js";
|
|
28
|
+
export function portableArtifact(cb, receipt) {
|
|
29
|
+
return {
|
|
30
|
+
kind: "hydra/portable-codebook",
|
|
31
|
+
v: 1,
|
|
32
|
+
codebook: cb,
|
|
33
|
+
receipt,
|
|
34
|
+
grammar: {
|
|
35
|
+
rule: "for each entry, replace every occurrence of `sym` with `phrase` (single deterministic pass; phrases never contain markers)",
|
|
36
|
+
markerOpen: cb.open,
|
|
37
|
+
markerClose: cb.close,
|
|
38
|
+
},
|
|
39
|
+
codebookHash: sha256Hex(canonicalizeCodebook(cb)),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function bindAxioms(cb) {
|
|
43
|
+
return cb.entries.map((e) => ({
|
|
44
|
+
claim: `hydra-symbol ${JSON.stringify(e.sym)} expands to ${JSON.stringify(e.phrase)}`,
|
|
45
|
+
sym: e.sym,
|
|
46
|
+
phrase: e.phrase,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* THE FULL PIPELINE — L1→L9 in one deterministic call. `at` is the issue
|
|
51
|
+
* timestamp (CLI passes Date.now(); tests pass a fixed value).
|
|
52
|
+
*/
|
|
53
|
+
export function hydraForge(repoRoot, corpus, at, opts = {}) {
|
|
54
|
+
const forge = forgeCodebook(corpus, opts);
|
|
55
|
+
const g = gauntlet(corpus, forge.codebook);
|
|
56
|
+
const receipt = signCodebook(repoRoot, forge.codebook, g, at);
|
|
57
|
+
const energy = mintEnergyCert(repoRoot, forge.codebook, g, at);
|
|
58
|
+
const portable = portableArtifact(forge.codebook, receipt);
|
|
59
|
+
const axioms = bindAxioms(forge.codebook);
|
|
60
|
+
return { forge, gauntlet: g, receipt, energy, portable, axioms };
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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;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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.96.0 — HYDRA · L1 semantic mining + L2 MDL-optimal selection.
|
|
3
|
+
*
|
|
4
|
+
* The codebook Mneme mines from its OWN corpus — "the rarest gem the
|
|
5
|
+
* system forges itself". Different from BPE (subword) and LZ (byte): we
|
|
6
|
+
* mine over SEMANTIC token-windows (whole recurring phrases like
|
|
7
|
+
* "HMAC-chained ledger", "Ed25519-signed", "tamper-evident") so the
|
|
8
|
+
* symbols carry meaning, and we keep them as EXACT corpus substrings so
|
|
9
|
+
* the round-trip stays byte-lossless by construction.
|
|
10
|
+
*
|
|
11
|
+
* Selection is L2 MDL-optimal: a phrase earns its place only if it pays
|
|
12
|
+
* back more bytes than it costs to store — an information-theoretic
|
|
13
|
+
* objective (Rissanen's Minimum Description Length), not a heuristic.
|
|
14
|
+
*
|
|
15
|
+
* Pure + deterministic: same corpus → same candidates → same ranking.
|
|
16
|
+
*/
|
|
17
|
+
export interface PhraseCandidate {
|
|
18
|
+
phrase: string;
|
|
19
|
+
hits: number;
|
|
20
|
+
/** MDL net byte gain if this phrase becomes a symbol. */
|
|
21
|
+
gain: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Tokenize into an alternating stream of word-runs and whitespace-runs.
|
|
25
|
+
* `tokens.join("")` reconstructs the input EXACTLY — that exactness is
|
|
26
|
+
* what keeps every mined phrase a real substring (→ lossless).
|
|
27
|
+
*/
|
|
28
|
+
export declare function tokenize(text: string): string[];
|
|
29
|
+
/**
|
|
30
|
+
* L1 — generate candidate phrases as windows of consecutive tokens. Odd
|
|
31
|
+
* window sizes straddle word·space·word so a candidate is always an exact
|
|
32
|
+
* substring. L2 — score each by MDL net gain and keep only payers.
|
|
33
|
+
*
|
|
34
|
+
* @param windowSizes token-window widths to consider (default 3..15 odd)
|
|
35
|
+
* @param minHits minimum occurrences to be worth a symbol
|
|
36
|
+
*/
|
|
37
|
+
export declare function mineCandidates(corpus: string, opts?: {
|
|
38
|
+
windowSizes?: number[];
|
|
39
|
+
minHits?: number;
|
|
40
|
+
maxCandidates?: number;
|
|
41
|
+
}): PhraseCandidate[];
|
|
42
|
+
//# sourceMappingURL=mine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mine.d.ts","sourceRoot":"","sources":["../../src/hydra/mine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;CACd;AAOD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/C;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9E,eAAe,EAAE,CAgCnB"}
|