@mneme-ai/core 3.77.0 → 3.79.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,188 @@
1
+ /**
2
+ * ARCHITECTURAL INVARIANTS — design-by-contract for your cross-layer architecture, PROVEN.
3
+ *
4
+ * A type system proves invariants about values. Nothing proves invariants about your ARCHITECTURE: "the
5
+ * `payments` table has exactly one writer", "`credentials` is never reachable from an HTTP endpoint",
6
+ * "no endpoint writes a sensitive table without auth", "`POST /v1/charge` exists". Teams hold these
7
+ * rules in their heads and break them silently. This lets a team DECLARE such invariants in a tiny DSL
8
+ * and, every PR, get a deterministic verdict per rule — HOLDS, or VIOLATED with the exact counterexample
9
+ * (the second writer, the endpoint that reaches the private table) — derived from the cross-layer graph,
10
+ * never guessed. It is the rarest composition: custom, declarative, machine-checked architectural
11
+ * contracts with proof-carrying counterexamples.
12
+ *
13
+ * ★HONEST (DIAKRISIS): the invariants are checked against the structural contract the deterministic
14
+ * extractors see (measured precision 1.0); a VIOLATED carries a real cited counterexample, an UNKNOWN
15
+ * (e.g. a single-writer rule for a table with zero detected writers) is reported as such, never a false
16
+ * HOLDS. It proves what the graph can prove — a CI gate over architecture, not a runtime guarantee.
17
+ */
18
+ import { buildCrossLayerGraph } from "../cross_layer_graph/index.js";
19
+ import { authzGaps } from "../authz_gap/index.js";
20
+ import { reachesProof } from "../graph_logic/index.js";
21
+ import { normPath } from "../cross_service/index.js";
22
+ const lc = (s) => String(s ?? "").toLowerCase();
23
+ /** Parse the invariant DSL. Lines: `table <T> single-writer|guarded|private` · `endpoint [METHOD] <path> exists` · `# comment`. */
24
+ export function parseInvariants(text) {
25
+ const out = [];
26
+ for (const raw0 of String(text ?? "").split(/\r?\n/)) {
27
+ const raw = raw0.replace(/#.*$/, "").trim();
28
+ if (!raw)
29
+ continue;
30
+ let m;
31
+ if ((m = raw.match(/^table\s+([A-Za-z_]\w*)\s+(single-writer|guarded|private)$/i))) {
32
+ out.push({ raw, kind: m[2].toLowerCase(), table: m[1] });
33
+ continue;
34
+ }
35
+ if ((m = raw.match(/^endpoint\s+(?:(GET|POST|PUT|PATCH|DELETE|ANY|RPC)\s+)?(\S+)\s+exists$/i))) {
36
+ out.push({ raw, kind: "exists", method: m[1] ? m[1].toUpperCase() : "", path: m[2] });
37
+ continue;
38
+ }
39
+ out.push({ raw, kind: "invalid" });
40
+ }
41
+ return out;
42
+ }
43
+ function writersOf(g, table) {
44
+ const byId = new Map(g.nodes.map((n) => [n.id, n]));
45
+ const tbl = g.nodes.find((n) => n.type === "db_table" && lc(n.name) === lc(table));
46
+ if (!tbl)
47
+ return [];
48
+ return [...new Set(g.edges.filter((e) => e.relation === "WRITES_TO" && e.target === tbl.id).map((e) => byId.get(e.source)?.name || "").filter(Boolean))];
49
+ }
50
+ /** Check each invariant against the repo → HOLDS / VIOLATED (with counterexample) / UNKNOWN. */
51
+ export function checkInvariants(files, invariants) {
52
+ const g = buildCrossLayerGraph((files ?? []));
53
+ const endpoints = g.nodes.filter((n) => n.type === "api_endpoint");
54
+ const gaps = authzGaps(g);
55
+ const results = [];
56
+ for (const inv of invariants ?? []) {
57
+ if (inv.kind === "invalid") {
58
+ results.push({ invariant: inv, status: "UNKNOWN", reason: `unrecognized invariant: "${inv.raw}"` });
59
+ continue;
60
+ }
61
+ if (inv.kind === "single-writer") {
62
+ const w = writersOf(g, inv.table);
63
+ if (w.length === 1)
64
+ results.push({ invariant: inv, status: "HOLDS", reason: `'${inv.table}' has exactly one writer: ${w[0]}` });
65
+ else if (w.length > 1)
66
+ results.push({ invariant: inv, status: "VIOLATED", counterexample: w.join(", "), reason: `'${inv.table}' has ${w.length} writers: ${w.join(", ")}` });
67
+ else
68
+ results.push({ invariant: inv, status: "UNKNOWN", reason: `no writer of '${inv.table}' detected in the scanned code` });
69
+ }
70
+ else if (inv.kind === "guarded") {
71
+ const bad = gaps.find((x) => x.sensitiveTables.some((t) => lc(t) === lc(inv.table)));
72
+ if (bad)
73
+ results.push({ invariant: inv, status: "VIOLATED", counterexample: `${bad.method} ${bad.endpoint} → ${bad.handler}`, reason: `'${inv.table}' has an unguarded write path: ${bad.method} ${bad.endpoint} via ${bad.handler}` });
74
+ else
75
+ results.push({ invariant: inv, status: "HOLDS", reason: `no unguarded sensitive-write path to '${inv.table}' detected` });
76
+ }
77
+ else if (inv.kind === "private") {
78
+ let hit = null;
79
+ for (const ep of endpoints) {
80
+ const r = reachesProof(g, `${ep.method || ""} ${ep.name}`.trim(), inv.table);
81
+ if (r.reachable) {
82
+ hit = `${ep.method || ""} ${ep.name}`.trim();
83
+ break;
84
+ }
85
+ }
86
+ if (hit)
87
+ results.push({ invariant: inv, status: "VIOLATED", counterexample: hit, reason: `'${inv.table}' is reachable from endpoint ${hit} (should be internal-only)` });
88
+ else
89
+ results.push({ invariant: inv, status: "HOLDS", reason: `no endpoint reaches '${inv.table}' — it stays internal` });
90
+ }
91
+ else if (inv.kind === "exists") {
92
+ const want = normPath(inv.path);
93
+ const found = endpoints.some((ep) => normPath(ep.name) === want && (!inv.method || (ep.method || "") === inv.method));
94
+ results.push(found ? { invariant: inv, status: "HOLDS", reason: `endpoint ${inv.method || ""} ${inv.path} exists` } : { invariant: inv, status: "VIOLATED", reason: `endpoint ${inv.method || ""} ${inv.path} is NOT in the API surface` });
95
+ }
96
+ }
97
+ const violated = results.filter((r) => r.status === "VIOLATED").length;
98
+ return { results, allHold: violated === 0, violated };
99
+ }
100
+ // ── INVARIANT MINING — induce the architectural contract the codebase ALREADY upholds ──────────────
101
+ const SENSITIVE_RE = /\b(account|payment|wallet|password|credential|secret|token|admin|role|permission|balance|transaction|billing|card|user|order|invoice|subscription)\b/i;
102
+ /**
103
+ * Discover the invariants that PROVABLY hold in the repo right now — every table with exactly one writer
104
+ * (single-writer), every sensitive table with no unguarded write path (guarded), every table no endpoint
105
+ * reaches (private). Each mined rule is true at mine-time by construction, so checkInvariants on the same
106
+ * repo returns all-HOLD. The team reviews + keeps the ones that reflect intent; thereafter any PR that
107
+ * breaks one is caught. ★HONEST: mined invariants are DESCRIPTIVE (what holds now) proposed as
108
+ * candidates — not every currently-true fact is an intended rule (a 1-writer table may gain a 2nd by
109
+ * design), so it proposes, a human curates; the rarity is the INDUCTION + proven-at-mine-time.
110
+ */
111
+ export function mineInvariants(files) {
112
+ const g = buildCrossLayerGraph((files ?? []));
113
+ const tables = g.nodes.filter((n) => n.type === "db_table");
114
+ const endpoints = g.nodes.filter((n) => n.type === "api_endpoint");
115
+ const gaps = authzGaps(g);
116
+ const gappedTables = new Set(gaps.flatMap((x) => x.sensitiveTables.map(lc)));
117
+ const byId = new Map(g.nodes.map((n) => [n.id, n]));
118
+ const touched = (t) => g.edges.some((e) => (e.relation === "READS" || e.relation === "WRITES_TO") && e.target === t.id);
119
+ const out = [];
120
+ for (const t of tables) {
121
+ const writers = [...new Set(g.edges.filter((e) => e.relation === "WRITES_TO" && e.target === t.id).map((e) => byId.get(e.source)?.name || "").filter(Boolean))];
122
+ if (writers.length === 1)
123
+ out.push({ rule: `table ${t.name} single-writer`, kind: "single-writer", confidence: "high", rationale: `only ${writers[0]} writes it today` });
124
+ if (SENSITIVE_RE.test(t.name) && !gappedTables.has(lc(t.name)) && touched(t))
125
+ out.push({ rule: `table ${t.name} guarded`, kind: "guarded", confidence: "medium", rationale: `sensitive table with no unguarded write path today` });
126
+ if (touched(t) && !endpoints.some((ep) => reachesProof(g, `${ep.method || ""} ${ep.name}`.trim(), t.name).reachable))
127
+ out.push({ rule: `table ${t.name} private`, kind: "private", confidence: "medium", rationale: `used internally; no endpoint reaches it today` });
128
+ }
129
+ // stable order, de-duped
130
+ const seen = new Set();
131
+ return out.filter((m) => (seen.has(m.rule) ? false : (seen.add(m.rule), true))).sort((a, b) => a.rule.localeCompare(b.rule));
132
+ }
133
+ /** Render mined invariants as a ready-to-commit .mneme/invariants.txt (each rule + its rationale). */
134
+ export function renderMined(mined) {
135
+ const head = "# Architectural invariants — mined by Mneme (each held at mine-time). Review + keep the ones that reflect intent.\n";
136
+ return head + (mined ?? []).map((m) => `${m.rule} # ${m.confidence}: ${m.rationale}`).join("\n") + "\n";
137
+ }
138
+ export function invariantsGauntlet() {
139
+ const files = [
140
+ { path: "schema.prisma", content: "model Payment { id Int @id }\nmodel Audit { id Int @id }\nmodel Secret { id Int @id }\nmodel Account { id Int @id }" },
141
+ { path: "routes.ts", content: "router.post(\"/v1/charge\", charge);\nrouter.get(\"/v1/secret\", leakSecret);\nrouter.post(\"/v1/xfer\", xfer);" },
142
+ { path: "h.ts", content: "export function charge(req){ requireAuth(req); return prisma.payment.create({data:{}}); }\nexport function requireAuth(r){ return r.user; }\nexport function leakSecret(){ return prisma.secret.findMany(); }\nexport function xfer(){ return prisma.account.update({where:{}}); }\nexport function aw(){ return prisma.audit.create({data:{}}); }\nexport function aw2(){ return prisma.audit.update({where:{}}); }" },
143
+ ];
144
+ const inv = parseInvariants([
145
+ "table Payment single-writer", // 1 writer (charge) → HOLDS
146
+ "table Audit single-writer", // 2 writers (aw, aw2) → VIOLATED
147
+ "table Secret private", // reached by GET /v1/secret → VIOLATED
148
+ "table Audit private", // no endpoint reaches Audit → HOLDS
149
+ "table Account guarded", // xfer writes account with no auth → VIOLATED
150
+ "endpoint POST /v1/charge exists", // HOLDS
151
+ "endpoint GET /v1/nope exists", // VIOLATED
152
+ ].join("\n"));
153
+ const r = checkInvariants(files, inv);
154
+ const by = (raw) => r.results.find((x) => x.invariant.raw === raw);
155
+ const swHold = by("table Payment single-writer").status === "HOLDS";
156
+ const swViol = by("table Audit single-writer").status === "VIOLATED" && (by("table Audit single-writer").counterexample || "").includes("aw");
157
+ const privViol = by("table Secret private").status === "VIOLATED";
158
+ const privHold = by("table Audit private").status === "HOLDS";
159
+ const guardViol = by("table Account guarded").status === "VIOLATED";
160
+ const existHold = by("endpoint POST /v1/charge exists").status === "HOLDS";
161
+ const existViol = by("endpoint GET /v1/nope exists").status === "VIOLATED";
162
+ // MINING: induce the invariants the repo upholds; they must all HOLD on the same repo (proven-at-mine-time).
163
+ const mined = mineInvariants(files);
164
+ const minedHold = checkInvariants(files, parseInvariants(renderMined(mined)));
165
+ const mineAllHold = mined.length >= 3 && minedHold.violated === 0 && minedHold.results.every((r) => r.status === "HOLDS");
166
+ const mineExcludesViolations = !mined.some((m) => m.rule === "table Audit single-writer"); // Audit has 2 writers → never mined as single-writer
167
+ const total = (() => { try {
168
+ checkInvariants(null, null);
169
+ parseInvariants(null);
170
+ mineInvariants(null);
171
+ renderMined(null);
172
+ return true;
173
+ }
174
+ catch {
175
+ return false;
176
+ } })();
177
+ const checks = [
178
+ { name: "SINGLE-WRITER", pass: swHold && swViol, detail: "single-writer HOLDS for one writer; VIOLATED (names the writers) for two" },
179
+ { name: "PRIVATE-TABLE", pass: privViol && privHold, detail: "private VIOLATED when an endpoint reaches the table (counterexample), HOLDS when none does" },
180
+ { name: "GUARDED-TABLE", pass: guardViol, detail: "guarded VIOLATED when there is an unguarded sensitive-write path" },
181
+ { name: "ENDPOINT-EXISTS", pass: existHold && existViol, detail: "exists HOLDS when the endpoint is in the API surface, VIOLATED when absent" },
182
+ { name: "MINING-PROVEN-AT-MINE-TIME", pass: mineAllHold, detail: "mined invariants (≥3) all HOLD on the same repo by construction — induced, not guessed" },
183
+ { name: "MINING-EXCLUDES-VIOLATIONS", pass: mineExcludesViolations, detail: "a table with 2 writers is NEVER mined as single-writer (only true invariants are induced)" },
184
+ { name: "TOTAL", pass: total, detail: "null/garbage never throws" },
185
+ ];
186
+ return { score: checks.every((c) => c.pass) ? 100 : 0, checks };
187
+ }
188
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/invariants/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=invariants.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariants.test.d.ts","sourceRoot":"","sources":["../../src/invariants/invariants.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { parseInvariants, checkInvariants, invariantsGauntlet, mineInvariants, renderMined } from "./index.js";
3
+ const files = [
4
+ { path: "schema.prisma", content: "model Payment { id Int @id }\nmodel Audit { id Int @id }\nmodel Secret { id Int @id }\nmodel Account { id Int @id }" },
5
+ { path: "routes.ts", content: "router.post(\"/v1/charge\", charge);\nrouter.get(\"/v1/secret\", leakSecret);\nrouter.post(\"/v1/xfer\", xfer);" },
6
+ { path: "h.ts", content: "export function charge(req){ requireAuth(req); return prisma.payment.create({data:{}}); }\nexport function requireAuth(r){ return r.user; }\nexport function leakSecret(){ return prisma.secret.findMany(); }\nexport function xfer(){ return prisma.account.update({where:{}}); }\nexport function aw(){ return prisma.audit.create({data:{}}); }\nexport function aw2(){ return prisma.audit.update({where:{}}); }" },
7
+ ];
8
+ describe("invariants", () => {
9
+ it("gauntlet is 100", () => expect(invariantsGauntlet().score).toBe(100));
10
+ it("parses the DSL", () => {
11
+ const inv = parseInvariants("table users single-writer\ntable creds private\nendpoint POST /x exists\n# comment\ngarbage line");
12
+ expect(inv.map((i) => i.kind)).toEqual(["single-writer", "private", "exists", "invalid"]);
13
+ });
14
+ it("single-writer: HOLDS for 1, VIOLATED (names writers) for 2", () => {
15
+ const r = checkInvariants(files, parseInvariants("table Payment single-writer\ntable Audit single-writer"));
16
+ expect(r.results[0].status).toBe("HOLDS");
17
+ expect(r.results[1].status).toBe("VIOLATED");
18
+ expect(r.results[1].counterexample).toMatch(/aw/);
19
+ });
20
+ it("private: VIOLATED when an endpoint reaches it, HOLDS when none", () => {
21
+ const r = checkInvariants(files, parseInvariants("table Secret private\ntable Audit private"));
22
+ expect(r.results[0].status).toBe("VIOLATED");
23
+ expect(r.results[1].status).toBe("HOLDS");
24
+ });
25
+ it("guarded VIOLATED on an unguarded sensitive write; exists HOLDS/VIOLATED", () => {
26
+ const r = checkInvariants(files, parseInvariants("table Account guarded\nendpoint POST /v1/charge exists\nendpoint GET /nope exists"));
27
+ expect(r.results[0].status).toBe("VIOLATED");
28
+ expect(r.results[1].status).toBe("HOLDS");
29
+ expect(r.results[2].status).toBe("VIOLATED");
30
+ expect(r.allHold).toBe(false);
31
+ });
32
+ it("MINING: induced invariants all HOLD on the same repo (proven at mine-time)", () => {
33
+ const mined = mineInvariants(files);
34
+ expect(mined.length).toBeGreaterThanOrEqual(3);
35
+ const r = checkInvariants(files, parseInvariants(renderMined(mined)));
36
+ expect(r.violated).toBe(0);
37
+ expect(r.results.every((x) => x.status === "HOLDS")).toBe(true);
38
+ });
39
+ it("MINING never induces a false single-writer (Audit has 2 writers)", () => {
40
+ expect(mineInvariants(files).some((m) => m.rule === "table Audit single-writer")).toBe(false);
41
+ });
42
+ it("never throws on garbage", () => {
43
+ expect(() => checkInvariants(null, null)).not.toThrow();
44
+ expect(() => parseInvariants(null)).not.toThrow();
45
+ expect(() => mineInvariants(null)).not.toThrow();
46
+ });
47
+ });
48
+ //# sourceMappingURL=invariants.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariants.test.js","sourceRoot":"","sources":["../../src/invariants/invariants.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mneme-ai/core",
3
- "version": "3.77.0",
3
+ "version": "3.79.0",
4
4
  "description": "Core indexing, retrieval, and graph engine for Mneme",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",