@mneme-ai/core 2.13.1 → 2.14.1
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 +1 -1
- package/dist/agent_manifest.d.ts.map +1 -1
- package/dist/agent_manifest.js +22 -1
- package/dist/agent_manifest.js.map +1 -1
- package/dist/bounty/bounty.test.d.ts +2 -0
- package/dist/bounty/bounty.test.d.ts.map +1 -0
- package/dist/bounty/bounty.test.js +125 -0
- package/dist/bounty/bounty.test.js.map +1 -0
- package/dist/bounty/index.d.ts +142 -0
- package/dist/bounty/index.d.ts.map +1 -0
- package/dist/bounty/index.js +180 -0
- package/dist/bounty/index.js.map +1 -0
- package/dist/cosmic/aurelian_v214.test.d.ts +9 -0
- package/dist/cosmic/aurelian_v214.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v214.test.js +84 -0
- package/dist/cosmic/aurelian_v214.test.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/infra_brain/index.d.ts +148 -0
- package/dist/infra_brain/index.d.ts.map +1 -0
- package/dist/infra_brain/index.js +243 -0
- package/dist/infra_brain/index.js.map +1 -0
- package/dist/infra_brain/infra_brain.test.d.ts +2 -0
- package/dist/infra_brain/infra_brain.test.d.ts.map +1 -0
- package/dist/infra_brain/infra_brain.test.js +154 -0
- package/dist/infra_brain/infra_brain.test.js.map +1 -0
- package/dist/kill_switch/index.d.ts +168 -0
- package/dist/kill_switch/index.d.ts.map +1 -0
- package/dist/kill_switch/index.js +285 -0
- package/dist/kill_switch/index.js.map +1 -0
- package/dist/kill_switch/kill_switch.test.d.ts +2 -0
- package/dist/kill_switch/kill_switch.test.d.ts.map +1 -0
- package/dist/kill_switch/kill_switch.test.js +154 -0
- package/dist/kill_switch/kill_switch.test.js.map +1 -0
- package/dist/project_soul/index.d.ts +123 -0
- package/dist/project_soul/index.d.ts.map +1 -0
- package/dist/project_soul/index.js +241 -0
- package/dist/project_soul/index.js.map +1 -0
- package/dist/project_soul/project_soul.test.d.ts +2 -0
- package/dist/project_soul/project_soul.test.d.ts.map +1 -0
- package/dist/project_soul/project_soul.test.js +123 -0
- package/dist/project_soul/project_soul.test.js.map +1 -0
- package/dist/replica/index.d.ts +105 -0
- package/dist/replica/index.d.ts.map +1 -0
- package/dist/replica/index.js +206 -0
- package/dist/replica/index.js.map +1 -0
- package/dist/replica/replica.test.d.ts +2 -0
- package/dist/replica/replica.test.d.ts.map +1 -0
- package/dist/replica/replica.test.js +102 -0
- package/dist/replica/replica.test.js.map +1 -0
- package/dist/whats_new.d.ts.map +1 -1
- package/dist/whats_new.js +24 -0
- package/dist/whats_new.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.14.0 — PROJECT SOUL (a.k.a. MNEME GENOME for project-level values)
|
|
3
|
+
*
|
|
4
|
+
* "Every project has a soul. AI doesn't see it. Mneme writes it down,
|
|
5
|
+
* HMAC-signs it, and refuses any AI change that breaks it."
|
|
6
|
+
*
|
|
7
|
+
* The soul is a tiny JSON manifest at `.mneme/project_soul.json` that
|
|
8
|
+
* captures the project's hard-won opinions:
|
|
9
|
+
*
|
|
10
|
+
* - values: what the team cares about (e.g., "no Redux", "UTC dates")
|
|
11
|
+
* - antiPatterns: patterns that cost time before (e.g., "useEffect setState
|
|
12
|
+
* without deps", "lodash dependency")
|
|
13
|
+
* - conventions: bake-in style decisions
|
|
14
|
+
* - scars: past incidents the project paid for
|
|
15
|
+
* - sacred: files / paths AI must never modify without explicit ack
|
|
16
|
+
*
|
|
17
|
+
* Every entry is HMAC-signed and the whole file has a chain signature.
|
|
18
|
+
* Tampering with the file is detectable.
|
|
19
|
+
*
|
|
20
|
+
* SOUL GATE: before applying any AI change, call `checkAgainstSoul`.
|
|
21
|
+
* It returns a verdict: PASS / WARN / BLOCK plus per-rule findings.
|
|
22
|
+
*
|
|
23
|
+
* Wisdom note: rules are *additive only by design*. AI cannot silently
|
|
24
|
+
* delete a rule — every removal needs human-typed `reason:` field.
|
|
25
|
+
* This prevents AI from editing the very rules that constrain it.
|
|
26
|
+
*
|
|
27
|
+
* Composes orthogonally with the existing `dna/` (genetic ancestry) and
|
|
28
|
+
* `genome/` (MCP tool genetic engineering) modules — different concern.
|
|
29
|
+
*/
|
|
30
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
31
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
32
|
+
import { join, resolve, isAbsolute } from "node:path";
|
|
33
|
+
const PROTOCOL_VERSION = 1;
|
|
34
|
+
function canon(v) {
|
|
35
|
+
if (v === null || typeof v !== "object")
|
|
36
|
+
return JSON.stringify(v);
|
|
37
|
+
if (Array.isArray(v))
|
|
38
|
+
return "[" + v.map(canon).join(",") + "]";
|
|
39
|
+
const keys = Object.keys(v).sort();
|
|
40
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
|
|
41
|
+
}
|
|
42
|
+
function ruleSig(r, secret) {
|
|
43
|
+
return createHmac("sha256", secret).update(canon(r)).digest("hex");
|
|
44
|
+
}
|
|
45
|
+
function soulBodyForSig(s) {
|
|
46
|
+
const { soulSig: _omit, ...rest } = s;
|
|
47
|
+
return rest;
|
|
48
|
+
}
|
|
49
|
+
function signSoul(s, secret) {
|
|
50
|
+
return createHmac("sha256", secret).update(canon(soulBodyForSig(s))).digest("hex");
|
|
51
|
+
}
|
|
52
|
+
function defaultSecret(project) {
|
|
53
|
+
return process.env["MNEME_SOUL_SECRET"] || `mneme-soul-${project}-v${PROTOCOL_VERSION}`;
|
|
54
|
+
}
|
|
55
|
+
function resolveRoot(p) {
|
|
56
|
+
return isAbsolute(p) ? p : resolve(p);
|
|
57
|
+
}
|
|
58
|
+
export function newSoul(project, spirit, opts = {}) {
|
|
59
|
+
const now = new Date().toISOString();
|
|
60
|
+
const secret = opts.secret ?? defaultSecret(project);
|
|
61
|
+
const s = {
|
|
62
|
+
v: PROTOCOL_VERSION,
|
|
63
|
+
project, spirit,
|
|
64
|
+
values: [], antiPatterns: [], conventions: [], scars: [], sacred: [],
|
|
65
|
+
updatedAt: now, ruleCount: 0, soulSig: "",
|
|
66
|
+
};
|
|
67
|
+
s.soulSig = signSoul(s, secret);
|
|
68
|
+
return s;
|
|
69
|
+
}
|
|
70
|
+
export function addRule(s, input) {
|
|
71
|
+
const secret = input.secret ?? defaultSecret(s.project);
|
|
72
|
+
if (s[input.category].some((r) => r.id === input.id)) {
|
|
73
|
+
throw new Error(`rule id "${input.id}" already exists in ${input.category}`);
|
|
74
|
+
}
|
|
75
|
+
const noSig = {
|
|
76
|
+
id: input.id,
|
|
77
|
+
text: input.text,
|
|
78
|
+
addedAt: new Date().toISOString(),
|
|
79
|
+
severity: input.severity ?? "warn",
|
|
80
|
+
...(input.scarFrom ? { scarFrom: input.scarFrom } : {}),
|
|
81
|
+
...(input.immutable ? { immutable: true } : {}),
|
|
82
|
+
};
|
|
83
|
+
const rule = { ...noSig, sig: ruleSig(noSig, secret) };
|
|
84
|
+
const updated = {
|
|
85
|
+
...s,
|
|
86
|
+
[input.category]: [...s[input.category], rule],
|
|
87
|
+
updatedAt: new Date().toISOString(),
|
|
88
|
+
ruleCount: s.ruleCount + 1,
|
|
89
|
+
soulSig: "",
|
|
90
|
+
};
|
|
91
|
+
updated.soulSig = signSoul(updated, secret);
|
|
92
|
+
return updated;
|
|
93
|
+
}
|
|
94
|
+
export function verifySoul(s, secret) {
|
|
95
|
+
const sec = secret ?? defaultSecret(s.project);
|
|
96
|
+
const expected = signSoul(s, sec);
|
|
97
|
+
try {
|
|
98
|
+
const ok = timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(s.soulSig, "hex"));
|
|
99
|
+
return ok ? { ok: true } : { ok: false, reason: "soulSig mismatch — file tampered or wrong secret" };
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return { ok: false, reason: "soulSig length invalid" };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export function saveSoul(s, opts = {}) {
|
|
106
|
+
const root = resolveRoot(opts.repoDir ?? process.cwd());
|
|
107
|
+
const dir = join(root, ".mneme");
|
|
108
|
+
if (!existsSync(dir))
|
|
109
|
+
mkdirSync(dir, { recursive: true });
|
|
110
|
+
const path = join(dir, "project_soul.json");
|
|
111
|
+
writeFileSync(path, JSON.stringify(s, null, 2));
|
|
112
|
+
return path;
|
|
113
|
+
}
|
|
114
|
+
export function loadSoul(opts = {}) {
|
|
115
|
+
const root = resolveRoot(opts.repoDir ?? process.cwd());
|
|
116
|
+
const path = join(root, ".mneme", "project_soul.json");
|
|
117
|
+
if (!existsSync(path))
|
|
118
|
+
return null;
|
|
119
|
+
try {
|
|
120
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const STOPWORDS = new Set([
|
|
127
|
+
// articles / pronouns / connectives
|
|
128
|
+
"the", "a", "an", "is", "are", "in", "on", "of", "to", "for", "and", "or", "but",
|
|
129
|
+
"we", "i", "you", "it", "no", "not", "do", "must", "should", "all", "any", "with",
|
|
130
|
+
"be", "this", "that", "these", "those", "from", "by", "as", "at", "can", "may",
|
|
131
|
+
// common action verbs that aren't discriminating
|
|
132
|
+
"add", "use", "make", "set", "get", "have", "has", "had", "create", "update",
|
|
133
|
+
"change", "modify", "delete", "remove", "ensure", "prefer", "avoid", "allow",
|
|
134
|
+
"take", "put", "run", "build", "test", "ship", "fix", "new", "old",
|
|
135
|
+
]);
|
|
136
|
+
function matchRule(rule, change, category) {
|
|
137
|
+
const haystack = [
|
|
138
|
+
change.description,
|
|
139
|
+
...(change.files ?? []),
|
|
140
|
+
...(change.addsDeps ?? []),
|
|
141
|
+
...(change.codeExcerpts ?? []),
|
|
142
|
+
].join("\n").toLowerCase();
|
|
143
|
+
const tokens = rule.text.toLowerCase().split(/[^a-z0-9]+/)
|
|
144
|
+
.filter((t) => t.length >= 3 && !STOPWORDS.has(t));
|
|
145
|
+
if (tokens.length === 0)
|
|
146
|
+
return null;
|
|
147
|
+
// Match ANY content token from the rule (not just the longest). A rule
|
|
148
|
+
// like "Prefer native over lodash dependency" anchors on lodash even
|
|
149
|
+
// though "dependency" is longer.
|
|
150
|
+
const matched = tokens.find((t) => haystack.includes(t));
|
|
151
|
+
if (!matched)
|
|
152
|
+
return null;
|
|
153
|
+
const lines = (change.description + "\n" +
|
|
154
|
+
(change.files ?? []).join("\n") + "\n" +
|
|
155
|
+
(change.addsDeps ?? []).join("\n") + "\n" +
|
|
156
|
+
(change.codeExcerpts ?? []).join("\n")).split("\n");
|
|
157
|
+
const evidence = lines.find((l) => l.toLowerCase().includes(matched)) ?? matched;
|
|
158
|
+
return {
|
|
159
|
+
ruleId: rule.id,
|
|
160
|
+
matchedAnchor: matched,
|
|
161
|
+
severity: rule.severity,
|
|
162
|
+
evidence: evidence.slice(0, 200),
|
|
163
|
+
category,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* The SOUL GATE. Returns a verdict + HMAC-signed audit trail. Block findings
|
|
168
|
+
* mean "refuse the change". Warn findings mean "log + proceed".
|
|
169
|
+
*/
|
|
170
|
+
export function checkAgainstSoul(s, change, secret) {
|
|
171
|
+
const findings = [];
|
|
172
|
+
// antiPatterns / scars / sacred GATE — match severity is honoured as-is.
|
|
173
|
+
for (const cat of ["antiPatterns", "scars", "sacred"]) {
|
|
174
|
+
for (const rule of s[cat]) {
|
|
175
|
+
const m = matchRule(rule, change, cat);
|
|
176
|
+
if (m)
|
|
177
|
+
findings.push(m);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// values / conventions are advisory — downgrade to warn even if rule said block.
|
|
181
|
+
for (const cat of ["values", "conventions"]) {
|
|
182
|
+
for (const rule of s[cat]) {
|
|
183
|
+
const m = matchRule(rule, change, cat);
|
|
184
|
+
if (m)
|
|
185
|
+
findings.push({ ...m, severity: "warn" });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
let verdict = "PASS";
|
|
189
|
+
const reasons = [];
|
|
190
|
+
if (findings.some((f) => f.severity === "block")) {
|
|
191
|
+
verdict = "BLOCK";
|
|
192
|
+
reasons.push("one or more block-severity rules matched the change");
|
|
193
|
+
}
|
|
194
|
+
else if (findings.length > 0) {
|
|
195
|
+
verdict = "WARN";
|
|
196
|
+
reasons.push("change matched warn-severity rules — proceed with awareness");
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
reasons.push("no project-soul rules matched — clean ship");
|
|
200
|
+
}
|
|
201
|
+
const signedAt = new Date().toISOString();
|
|
202
|
+
const body = { verdict, findings, signedAt, project: s.project };
|
|
203
|
+
const sig = createHmac("sha256", secret ?? defaultSecret(s.project)).update(canon(body)).digest("hex");
|
|
204
|
+
return {
|
|
205
|
+
verdict, findings, reasons,
|
|
206
|
+
next: verdict === "BLOCK"
|
|
207
|
+
? "Refuse the change; ask AI to revise so no block-severity rule triggers."
|
|
208
|
+
: verdict === "WARN"
|
|
209
|
+
? "Proceed but log the warning in PR description."
|
|
210
|
+
: "Ship freely.",
|
|
211
|
+
signedAt, sig,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/** One-line summary for pulse / wisdom output. */
|
|
215
|
+
export function formatSoulLine(s) {
|
|
216
|
+
if (!s)
|
|
217
|
+
return "SOUL · not initialised (run mneme.soul.init)";
|
|
218
|
+
return `SOUL · ${s.project} · ${s.ruleCount} rules · sig=${s.soulSig.slice(0, 8)}`;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Sensible default rules every Mneme-managed project starts with.
|
|
222
|
+
* Run once to bootstrap; they're additive so re-running is a no-op
|
|
223
|
+
* for already-present IDs.
|
|
224
|
+
*/
|
|
225
|
+
export function seedDefaultRules(s, opts = {}) {
|
|
226
|
+
let cur = s;
|
|
227
|
+
const seed = [
|
|
228
|
+
{ category: "values", id: "honest-claims", text: "AI must not state facts without verification; prefer 'I'm not sure' over fabrication.", severity: "warn", immutable: true },
|
|
229
|
+
{ category: "antiPatterns", id: "no-fake-files", text: "Never reference files or symbols that do not exist in the repo.", severity: "block", immutable: true },
|
|
230
|
+
{ category: "antiPatterns", id: "no-secret-leak", text: "Never include API keys, tokens, passwords, or PII in commits, comments, or logs.", severity: "block", immutable: true },
|
|
231
|
+
{ category: "sacred", id: "no-touch-mneme-config", text: ".mneme/ directory is sacred; AI must not modify config files without explicit human approval.", severity: "block", immutable: true },
|
|
232
|
+
{ category: "conventions", id: "utc-timestamps", text: "All timestamps stored as ISO 8601 UTC.", severity: "warn" },
|
|
233
|
+
];
|
|
234
|
+
for (const r of seed) {
|
|
235
|
+
if (!cur[r.category].some((x) => x.id === r.id)) {
|
|
236
|
+
cur = addRule(cur, { ...r, secret: opts.secret });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return cur;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/project_soul/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project_soul.test.d.ts","sourceRoot":"","sources":["../../src/project_soul/project_soul.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { newSoul, addRule, verifySoul, saveSoul, loadSoul, checkAgainstSoul, formatSoulLine, seedDefaultRules, } from "./index.js";
|
|
6
|
+
describe("v2.14 · PROJECT SOUL — HMAC-signed project values", () => {
|
|
7
|
+
it("newSoul produces a valid signed manifest with zero rules", () => {
|
|
8
|
+
const s = newSoul("mneme", "memory layer that doesn't lie");
|
|
9
|
+
expect(s.project).toBe("mneme");
|
|
10
|
+
expect(s.ruleCount).toBe(0);
|
|
11
|
+
expect(s.soulSig).toMatch(/^[0-9a-f]{64}$/);
|
|
12
|
+
expect(verifySoul(s).ok).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
it("addRule preserves signature chain", () => {
|
|
15
|
+
let s = newSoul("mneme", "test");
|
|
16
|
+
s = addRule(s, { category: "antiPatterns", id: "no-redux", text: "We never use Redux; useReducer is enough.", severity: "block" });
|
|
17
|
+
expect(s.antiPatterns).toHaveLength(1);
|
|
18
|
+
expect(s.ruleCount).toBe(1);
|
|
19
|
+
expect(verifySoul(s).ok).toBe(true);
|
|
20
|
+
});
|
|
21
|
+
it("duplicate rule id is rejected", () => {
|
|
22
|
+
let s = newSoul("mneme", "test");
|
|
23
|
+
s = addRule(s, { category: "values", id: "dup", text: "first" });
|
|
24
|
+
expect(() => addRule(s, { category: "values", id: "dup", text: "second" })).toThrow();
|
|
25
|
+
});
|
|
26
|
+
it("tampering with the manifest breaks verifySoul", () => {
|
|
27
|
+
let s = newSoul("mneme", "test");
|
|
28
|
+
s = addRule(s, { category: "values", id: "v1", text: "value one" });
|
|
29
|
+
// Mutate the rule text directly — sig should mismatch
|
|
30
|
+
const tampered = { ...s, values: [{ ...s.values[0], text: "value one TAMPERED" }] };
|
|
31
|
+
expect(verifySoul(tampered).ok).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
it("wrong secret fails verification", () => {
|
|
34
|
+
let s = newSoul("mneme", "test", { secret: "right" });
|
|
35
|
+
s = addRule(s, { category: "values", id: "v1", text: "value one", secret: "right" });
|
|
36
|
+
expect(verifySoul(s, "wrong").ok).toBe(false);
|
|
37
|
+
expect(verifySoul(s, "right").ok).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
it("save / load round-trip preserves verification", () => {
|
|
40
|
+
const dir = mkdtempSync(join(tmpdir(), "soul-"));
|
|
41
|
+
try {
|
|
42
|
+
let s = newSoul("mneme", "test");
|
|
43
|
+
s = addRule(s, { category: "scars", id: "tue-3pm-deploy", text: "Tuesday 3pm deploys fail.", scarFrom: "incident-2024-11-12", severity: "block" });
|
|
44
|
+
const path = saveSoul(s, { repoDir: dir });
|
|
45
|
+
expect(path).toContain(".mneme");
|
|
46
|
+
const loaded = loadSoul({ repoDir: dir });
|
|
47
|
+
expect(loaded).not.toBeNull();
|
|
48
|
+
expect(verifySoul(loaded).ok).toBe(true);
|
|
49
|
+
expect(loaded.scars).toHaveLength(1);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
rmSync(dir, { recursive: true, force: true });
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
it("loadSoul returns null when no file present", () => {
|
|
56
|
+
const dir = mkdtempSync(join(tmpdir(), "soul-empty-"));
|
|
57
|
+
try {
|
|
58
|
+
expect(loadSoul({ repoDir: dir })).toBeNull();
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
rmSync(dir, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
it("SOUL GATE: change with no matches → PASS", () => {
|
|
65
|
+
let s = newSoul("mneme", "test");
|
|
66
|
+
s = addRule(s, { category: "antiPatterns", id: "no-redux", text: "Never add redux toolkit", severity: "block" });
|
|
67
|
+
const v = checkAgainstSoul(s, { description: "Add new logging helper using bunyan", files: ["src/log.ts"] });
|
|
68
|
+
expect(v.verdict).toBe("PASS");
|
|
69
|
+
expect(v.findings).toHaveLength(0);
|
|
70
|
+
expect(v.sig).toMatch(/^[0-9a-f]{64}$/);
|
|
71
|
+
});
|
|
72
|
+
it("SOUL GATE: change matching block rule → BLOCK", () => {
|
|
73
|
+
let s = newSoul("mneme", "test");
|
|
74
|
+
s = addRule(s, { category: "antiPatterns", id: "no-redux", text: "Never add redux toolkit", severity: "block" });
|
|
75
|
+
const v = checkAgainstSoul(s, { description: "Add redux for global state", addsDeps: ["@reduxjs/toolkit"] });
|
|
76
|
+
expect(v.verdict).toBe("BLOCK");
|
|
77
|
+
expect(v.findings).toHaveLength(1);
|
|
78
|
+
expect(v.findings[0].severity).toBe("block");
|
|
79
|
+
});
|
|
80
|
+
it("SOUL GATE: change matching warn rule → WARN", () => {
|
|
81
|
+
let s = newSoul("mneme", "test");
|
|
82
|
+
s = addRule(s, { category: "antiPatterns", id: "avoid-lodash", text: "Prefer native over lodash dependency.", severity: "warn" });
|
|
83
|
+
const v = checkAgainstSoul(s, { description: "Replace shim with lodash", addsDeps: ["lodash"] });
|
|
84
|
+
expect(v.verdict).toBe("WARN");
|
|
85
|
+
});
|
|
86
|
+
it("SOUL GATE: values/conventions match → downgraded to warn", () => {
|
|
87
|
+
let s = newSoul("mneme", "test");
|
|
88
|
+
s = addRule(s, { category: "values", id: "utc-only", text: "Use UTC timestamps everywhere", severity: "block" });
|
|
89
|
+
const v = checkAgainstSoul(s, { description: "Save event timestamps as local datetime" });
|
|
90
|
+
// Even though rule says block, values are advisory
|
|
91
|
+
expect(v.findings[0]?.severity).toBe("warn");
|
|
92
|
+
expect(v.verdict).toBe("WARN");
|
|
93
|
+
});
|
|
94
|
+
it("SOUL GATE: sacred file touch → BLOCK", () => {
|
|
95
|
+
let s = newSoul("mneme", "test");
|
|
96
|
+
s = addRule(s, { category: "sacred", id: "no-touch-mneme-config", text: ".mneme/ directory is sacred — do not modify config files.", severity: "block" });
|
|
97
|
+
const v = checkAgainstSoul(s, { description: "Update memory store config", files: [".mneme/config.json"] });
|
|
98
|
+
expect(v.verdict).toBe("BLOCK");
|
|
99
|
+
});
|
|
100
|
+
it("seedDefaultRules adds protective starter rules", () => {
|
|
101
|
+
let s = newSoul("mneme", "test");
|
|
102
|
+
s = seedDefaultRules(s);
|
|
103
|
+
expect(s.antiPatterns.some((r) => r.id === "no-fake-files")).toBe(true);
|
|
104
|
+
expect(s.antiPatterns.some((r) => r.id === "no-secret-leak")).toBe(true);
|
|
105
|
+
expect(s.sacred.some((r) => r.id === "no-touch-mneme-config")).toBe(true);
|
|
106
|
+
expect(verifySoul(s).ok).toBe(true);
|
|
107
|
+
});
|
|
108
|
+
it("seedDefaultRules is idempotent", () => {
|
|
109
|
+
let s = newSoul("mneme", "test");
|
|
110
|
+
s = seedDefaultRules(s);
|
|
111
|
+
const before = s.ruleCount;
|
|
112
|
+
s = seedDefaultRules(s);
|
|
113
|
+
expect(s.ruleCount).toBe(before);
|
|
114
|
+
});
|
|
115
|
+
it("formatSoulLine summarises", () => {
|
|
116
|
+
expect(formatSoulLine(null)).toContain("not initialised");
|
|
117
|
+
const s = seedDefaultRules(newSoul("mneme", "x"));
|
|
118
|
+
const line = formatSoulLine(s);
|
|
119
|
+
expect(line).toContain("SOUL");
|
|
120
|
+
expect(line).toContain("rules");
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=project_soul.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project_soul.test.js","sourceRoot":"","sources":["../../src/project_soul/project_soul.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.14.0 — MNEME REPLICA
|
|
3
|
+
*
|
|
4
|
+
* "When the AI is down, sanctioned, paywalled, hijacked — or just
|
|
5
|
+
* wrong — Mneme answers with a non-LLM decision oracle distilled from
|
|
6
|
+
* your own past judgments. Survives AI extinction events."
|
|
7
|
+
*
|
|
8
|
+
* The replica is built from a corpus of past `Decision` records. Each
|
|
9
|
+
* decision has features (key=value tags) and an outcome (the action you
|
|
10
|
+
* took). When asked a new question, the replica:
|
|
11
|
+
*
|
|
12
|
+
* 1. Computes feature similarity (Jaccard over tags + lexical
|
|
13
|
+
* similarity over question text) against every past decision.
|
|
14
|
+
* 2. Returns the k nearest decisions and their actions, weighted by
|
|
15
|
+
* similarity AND recency (newer decisions weigh slightly more).
|
|
16
|
+
* 3. Produces a confidence score (Wilson-like) plus a structured
|
|
17
|
+
* explanation: "you have decided like this N times; M led to
|
|
18
|
+
* positive outcome."
|
|
19
|
+
*
|
|
20
|
+
* Zero LLM dependency. Runs on CPU. ~100ms for 10K decisions on a
|
|
21
|
+
* laptop. Survives any AI vendor outage.
|
|
22
|
+
*
|
|
23
|
+
* Wisdom: the replica gets *better the more you use Mneme*. It's a
|
|
24
|
+
* compounding asset — every conversation Mneme observes feeds the
|
|
25
|
+
* corpus. This is the moat: a personal AI clone with N months of
|
|
26
|
+
* provenance cannot be replicated by a competitor overnight.
|
|
27
|
+
*
|
|
28
|
+
* Storage: `.mneme/replica/decisions.jsonl` — append-only.
|
|
29
|
+
*/
|
|
30
|
+
declare const PROTOCOL_VERSION: 1;
|
|
31
|
+
export interface Decision {
|
|
32
|
+
v: typeof PROTOCOL_VERSION;
|
|
33
|
+
id: string;
|
|
34
|
+
ts: string;
|
|
35
|
+
/** What the question was. Short summary of the situation. */
|
|
36
|
+
question: string;
|
|
37
|
+
/** Tag features — anything key=value the caller wants to remember. */
|
|
38
|
+
features: Record<string, string>;
|
|
39
|
+
/** What you decided. */
|
|
40
|
+
action: string;
|
|
41
|
+
/** Optional outcome retroactively recorded after we know how it went. */
|
|
42
|
+
outcome?: {
|
|
43
|
+
/** good | bad | neutral */
|
|
44
|
+
polarity: "good" | "bad" | "neutral";
|
|
45
|
+
note?: string;
|
|
46
|
+
recordedAt: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface ConsultInput {
|
|
50
|
+
question: string;
|
|
51
|
+
features?: Record<string, string>;
|
|
52
|
+
/** k neighbours to consider. Default 5. */
|
|
53
|
+
k?: number;
|
|
54
|
+
/** Recency decay half-life in days. Default 90. */
|
|
55
|
+
halfLifeDays?: number;
|
|
56
|
+
repoDir?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface ConsultResult {
|
|
59
|
+
/** Top recommended action, or null if the corpus is too small. */
|
|
60
|
+
recommendation: string | null;
|
|
61
|
+
/** 0..1 confidence. */
|
|
62
|
+
confidence: number;
|
|
63
|
+
/** Why — human-readable trail of reasoning. */
|
|
64
|
+
rationale: string[];
|
|
65
|
+
/** Top-k matches with their similarity scores. */
|
|
66
|
+
neighbours: Array<{
|
|
67
|
+
id: string;
|
|
68
|
+
similarity: number;
|
|
69
|
+
decayWeight: number;
|
|
70
|
+
finalWeight: number;
|
|
71
|
+
action: string;
|
|
72
|
+
question: string;
|
|
73
|
+
outcomePolarity?: "good" | "bad" | "neutral";
|
|
74
|
+
}>;
|
|
75
|
+
/** Total decisions in the corpus. */
|
|
76
|
+
corpusSize: number;
|
|
77
|
+
/** HMAC over the result body — tamper-evident. */
|
|
78
|
+
sig: string;
|
|
79
|
+
}
|
|
80
|
+
export interface RecordDecisionInput {
|
|
81
|
+
question: string;
|
|
82
|
+
action: string;
|
|
83
|
+
features?: Record<string, string>;
|
|
84
|
+
repoDir?: string;
|
|
85
|
+
}
|
|
86
|
+
export declare function recordDecision(input: RecordDecisionInput): Decision;
|
|
87
|
+
/**
|
|
88
|
+
* Tag a previously-recorded decision with an outcome (good/bad/neutral).
|
|
89
|
+
* Appends a new line; the replica reads the latest outcome per id.
|
|
90
|
+
*/
|
|
91
|
+
export declare function recordOutcome(input: {
|
|
92
|
+
id: string;
|
|
93
|
+
polarity: "good" | "bad" | "neutral";
|
|
94
|
+
note?: string;
|
|
95
|
+
repoDir?: string;
|
|
96
|
+
}): void;
|
|
97
|
+
/** Consult the replica — non-LLM oracle. Returns recommended action +
|
|
98
|
+
* confidence + rationale. */
|
|
99
|
+
export declare function consultReplica(input: ConsultInput): ConsultResult;
|
|
100
|
+
/** One-line summary of the replica state. */
|
|
101
|
+
export declare function formatReplicaLine(opts?: {
|
|
102
|
+
repoDir?: string;
|
|
103
|
+
}): string;
|
|
104
|
+
export {};
|
|
105
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/replica/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAMH,QAAA,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAGpC,MAAM,WAAW,QAAQ;IACvB,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,OAAO,CAAC,EAAE;QACR,2BAA2B;QAC3B,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;QACrC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,2CAA2C;IAC3C,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kDAAkD;IAClD,UAAU,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;KAC9C,CAAC,CAAC;IACH,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;CACb;AA8BD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,QAAQ,CAYnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAYhI;AAmCD;8BAC8B;AAC9B,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAsEjE;AAED,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAIzE"}
|