@mneme-ai/core 2.13.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/agent_manifest.d.ts +1 -1
  2. package/dist/agent_manifest.d.ts.map +1 -1
  3. package/dist/agent_manifest.js +22 -1
  4. package/dist/agent_manifest.js.map +1 -1
  5. package/dist/bounty/bounty.test.d.ts +2 -0
  6. package/dist/bounty/bounty.test.d.ts.map +1 -0
  7. package/dist/bounty/bounty.test.js +125 -0
  8. package/dist/bounty/bounty.test.js.map +1 -0
  9. package/dist/bounty/index.d.ts +142 -0
  10. package/dist/bounty/index.d.ts.map +1 -0
  11. package/dist/bounty/index.js +180 -0
  12. package/dist/bounty/index.js.map +1 -0
  13. package/dist/cosmic/aurelian_v214.test.d.ts +9 -0
  14. package/dist/cosmic/aurelian_v214.test.d.ts.map +1 -0
  15. package/dist/cosmic/aurelian_v214.test.js +84 -0
  16. package/dist/cosmic/aurelian_v214.test.js.map +1 -0
  17. package/dist/cosmic/choir.d.ts +8 -0
  18. package/dist/cosmic/choir.d.ts.map +1 -1
  19. package/dist/cosmic/choir.js +14 -1
  20. package/dist/cosmic/choir.js.map +1 -1
  21. package/dist/cosmic/index.d.ts +15 -4
  22. package/dist/cosmic/index.d.ts.map +1 -1
  23. package/dist/cosmic/index.js +17 -3
  24. package/dist/cosmic/index.js.map +1 -1
  25. package/dist/index.d.ts +5 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +6 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/infra_brain/index.d.ts +148 -0
  30. package/dist/infra_brain/index.d.ts.map +1 -0
  31. package/dist/infra_brain/index.js +243 -0
  32. package/dist/infra_brain/index.js.map +1 -0
  33. package/dist/infra_brain/infra_brain.test.d.ts +2 -0
  34. package/dist/infra_brain/infra_brain.test.d.ts.map +1 -0
  35. package/dist/infra_brain/infra_brain.test.js +154 -0
  36. package/dist/infra_brain/infra_brain.test.js.map +1 -0
  37. package/dist/kill_switch/index.d.ts +168 -0
  38. package/dist/kill_switch/index.d.ts.map +1 -0
  39. package/dist/kill_switch/index.js +285 -0
  40. package/dist/kill_switch/index.js.map +1 -0
  41. package/dist/kill_switch/kill_switch.test.d.ts +2 -0
  42. package/dist/kill_switch/kill_switch.test.d.ts.map +1 -0
  43. package/dist/kill_switch/kill_switch.test.js +154 -0
  44. package/dist/kill_switch/kill_switch.test.js.map +1 -0
  45. package/dist/project_soul/index.d.ts +123 -0
  46. package/dist/project_soul/index.d.ts.map +1 -0
  47. package/dist/project_soul/index.js +241 -0
  48. package/dist/project_soul/index.js.map +1 -0
  49. package/dist/project_soul/project_soul.test.d.ts +2 -0
  50. package/dist/project_soul/project_soul.test.d.ts.map +1 -0
  51. package/dist/project_soul/project_soul.test.js +123 -0
  52. package/dist/project_soul/project_soul.test.js.map +1 -0
  53. package/dist/replica/index.d.ts +105 -0
  54. package/dist/replica/index.d.ts.map +1 -0
  55. package/dist/replica/index.js +206 -0
  56. package/dist/replica/index.js.map +1 -0
  57. package/dist/replica/replica.test.d.ts +2 -0
  58. package/dist/replica/replica.test.d.ts.map +1 -0
  59. package/dist/replica/replica.test.js +102 -0
  60. package/dist/replica/replica.test.js.map +1 -0
  61. package/package.json +1 -1
@@ -0,0 +1,154 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { mkdtempSync, rmSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { issueKillSwitch, readKillSwitch, verifyKillSwitch, shouldRespond, recordAudit, verifyAuditChain, exportAuditReport, dlpScan, loadDlpRules, formatCompliancePulse, } from "./index.js";
6
+ describe("v2.14 · KILL SWITCH PROTOCOL", () => {
7
+ let dir;
8
+ beforeEach(() => { dir = mkdtempSync(join(tmpdir(), "ks-")); });
9
+ afterEach(() => { try {
10
+ rmSync(dir, { recursive: true, force: true });
11
+ }
12
+ catch { } });
13
+ describe("kill switch", () => {
14
+ it("issue and read round-trip", () => {
15
+ const d = issueKillSwitch({ state: "active", reason: "incident response", issuedBy: "ciso@x.com", repoDir: dir });
16
+ expect(d.state).toBe("active");
17
+ expect(d.sig).toMatch(/^[0-9a-f]{64}$/);
18
+ const r = readKillSwitch({ repoDir: dir });
19
+ expect(r?.sig).toBe(d.sig);
20
+ });
21
+ it("verifyKillSwitch passes for un-tampered directive", () => {
22
+ const d = issueKillSwitch({ state: "active", reason: "test", issuedBy: "x", repoDir: dir });
23
+ expect(verifyKillSwitch(d).ok).toBe(true);
24
+ });
25
+ it("verifyKillSwitch fails on tamper", () => {
26
+ const d = issueKillSwitch({ state: "active", reason: "test", issuedBy: "x", repoDir: dir });
27
+ const tampered = { ...d, reason: "TAMPERED" };
28
+ expect(verifyKillSwitch(tampered).ok).toBe(false);
29
+ });
30
+ it("shouldRespond: no directive → allowed", () => {
31
+ const r = shouldRespond({ repoDir: dir });
32
+ expect(r.allowed).toBe(true);
33
+ });
34
+ it("shouldRespond: active kill → not allowed", () => {
35
+ issueKillSwitch({ state: "active", reason: "test", issuedBy: "x", repoDir: dir });
36
+ const r = shouldRespond({ repoDir: dir });
37
+ expect(r.allowed).toBe(false);
38
+ });
39
+ it("shouldRespond: scoped kill respects vendor scope", () => {
40
+ issueKillSwitch({ state: "scoped", reason: "test", issuedBy: "x", scopes: { vendors: ["chatgpt"] }, repoDir: dir });
41
+ expect(shouldRespond({ vendor: "chatgpt", repoDir: dir }).allowed).toBe(false);
42
+ expect(shouldRespond({ vendor: "claude", repoDir: dir }).allowed).toBe(true);
43
+ });
44
+ it("shouldRespond: expired kill → allowed again", () => {
45
+ const past = new Date(Date.now() - 1000).toISOString();
46
+ issueKillSwitch({ state: "active", reason: "test", issuedBy: "x", expiresAt: past, repoDir: dir });
47
+ expect(shouldRespond({ repoDir: dir }).allowed).toBe(true);
48
+ });
49
+ it("shouldRespond: tampered directive is ignored (forge protection)", () => {
50
+ issueKillSwitch({ state: "active", reason: "test", issuedBy: "x", repoDir: dir });
51
+ // Tamper file directly
52
+ const path = join(dir, ".mneme", "compliance", "kill_switch.json");
53
+ const cur = JSON.parse(readFileSync(path, "utf8"));
54
+ cur.reason = "FORGED kill";
55
+ writeFileSync(path, JSON.stringify(cur));
56
+ const r = shouldRespond({ repoDir: dir });
57
+ expect(r.allowed).toBe(true);
58
+ expect(r.reason).toContain("ignoring unverified");
59
+ });
60
+ it("issueKillSwitch records an audit entry", () => {
61
+ issueKillSwitch({ state: "active", reason: "incident", issuedBy: "ciso@x.com", repoDir: dir });
62
+ const report = exportAuditReport({ repoDir: dir });
63
+ expect(report.entries.some((e) => e.kind === "kill_switch")).toBe(true);
64
+ });
65
+ });
66
+ describe("audit log", () => {
67
+ it("recordAudit appends signed entries", () => {
68
+ const a = recordAudit({ kind: "prompt", actor: "claude", detail: "user asked X", repoDir: dir });
69
+ expect(a.id).toMatch(/^a-/);
70
+ expect(a.chainSig).toMatch(/^[0-9a-f]{64}$/);
71
+ });
72
+ it("verifyAuditChain ok on clean log", () => {
73
+ recordAudit({ kind: "prompt", actor: "claude", detail: "x", repoDir: dir });
74
+ recordAudit({ kind: "response", actor: "claude", detail: "y", repoDir: dir });
75
+ recordAudit({ kind: "tool_call", actor: "claude", detail: "z", repoDir: dir });
76
+ expect(verifyAuditChain({ repoDir: dir }).ok).toBe(true);
77
+ });
78
+ it("tampering breaks the chain", () => {
79
+ recordAudit({ kind: "prompt", actor: "claude", detail: "x", repoDir: dir });
80
+ recordAudit({ kind: "response", actor: "claude", detail: "y", repoDir: dir });
81
+ const path = join(dir, ".mneme", "compliance", "audit.jsonl");
82
+ const lines = readFileSync(path, "utf8").split("\n").filter((l) => l.length > 0);
83
+ const parsed = JSON.parse(lines[0]);
84
+ parsed.detail = "TAMPERED";
85
+ lines[0] = JSON.stringify(parsed);
86
+ writeFileSync(path, lines.join("\n") + "\n");
87
+ const r = verifyAuditChain({ repoDir: dir });
88
+ expect(r.ok).toBe(false);
89
+ expect(r.brokenIndex).toBe(0);
90
+ });
91
+ it("exportAuditReport groups by kind + actor", () => {
92
+ recordAudit({ kind: "prompt", actor: "claude", detail: "a", repoDir: dir });
93
+ recordAudit({ kind: "prompt", actor: "claude", detail: "b", repoDir: dir });
94
+ recordAudit({ kind: "response", actor: "claude", detail: "c", repoDir: dir });
95
+ recordAudit({ kind: "prompt", actor: "chatgpt", detail: "d", repoDir: dir });
96
+ const r = exportAuditReport({ repoDir: dir });
97
+ expect(r.byKind.prompt).toBe(3);
98
+ expect(r.byKind.response).toBe(1);
99
+ expect(r.byActor.claude).toBe(3);
100
+ expect(r.byActor.chatgpt).toBe(1);
101
+ expect(r.chainOk).toBe(true);
102
+ });
103
+ });
104
+ describe("DLP", () => {
105
+ it("scans clean text → no hits", () => {
106
+ const r = dlpScan("just a normal commit message about refactoring", { repoDir: dir });
107
+ expect(r.hits).toHaveLength(0);
108
+ expect(r.worstSeverity).toBe("none");
109
+ expect(r.blocked).toBe(false);
110
+ });
111
+ it("blocks AWS Access Key", () => {
112
+ const r = dlpScan("the key is AKIAIOSFODNN7EXAMPLE here", { repoDir: dir, actor: "claude" });
113
+ expect(r.blocked).toBe(true);
114
+ expect(r.hits.some((h) => h.ruleId === "aws-access-key")).toBe(true);
115
+ });
116
+ it("blocks GitHub PAT", () => {
117
+ const r = dlpScan("token: ghp_abcdefghijklmnopqrstuvwxyz0123456789", { repoDir: dir });
118
+ expect(r.blocked).toBe(true);
119
+ expect(r.hits.some((h) => h.ruleId === "github-pat")).toBe(true);
120
+ });
121
+ it("blocks OpenAI sk- key", () => {
122
+ const r = dlpScan("OPENAI_API_KEY=sk-abc123def456ghi789jkl012mno345pq", { repoDir: dir });
123
+ expect(r.blocked).toBe(true);
124
+ });
125
+ it("blocks PEM private key block", () => {
126
+ const r = dlpScan("-----BEGIN RSA PRIVATE KEY-----\nMIICstuff", { repoDir: dir });
127
+ expect(r.blocked).toBe(true);
128
+ });
129
+ it("warns on email PII", () => {
130
+ const r = dlpScan("contact me at user@example.com please", { repoDir: dir });
131
+ expect(r.worstSeverity).toBe("warn");
132
+ expect(r.blocked).toBe(false);
133
+ });
134
+ it("blocked scan creates a dlp_block audit entry", () => {
135
+ dlpScan("AKIAIOSFODNN7EXAMPLE", { repoDir: dir, actor: "claude" });
136
+ const report = exportAuditReport({ repoDir: dir });
137
+ expect(report.entries.some((e) => e.kind === "dlp_block")).toBe(true);
138
+ });
139
+ it("loadDlpRules returns the built-in set", () => {
140
+ const rules = loadDlpRules({ repoDir: dir });
141
+ expect(rules.length).toBeGreaterThanOrEqual(8);
142
+ expect(rules.some((r) => r.id === "aws-access-key")).toBe(true);
143
+ });
144
+ it("formatCompliancePulse summarises", () => {
145
+ issueKillSwitch({ state: "scoped", reason: "test", issuedBy: "x", scopes: { vendors: ["x"] }, repoDir: dir });
146
+ recordAudit({ kind: "prompt", actor: "claude", detail: "y", repoDir: dir });
147
+ const line = formatCompliancePulse({ repoDir: dir });
148
+ expect(line).toContain("COMPLIANCE");
149
+ expect(line).toContain("kill=scoped");
150
+ expect(line).toMatch(/audit=\d+/);
151
+ });
152
+ });
153
+ });
154
+ //# sourceMappingURL=kill_switch.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kill_switch.test.js","sourceRoot":"","sources":["../../src/kill_switch/kill_switch.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
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
+ declare const PROTOCOL_VERSION: 1;
31
+ export interface SoulRule {
32
+ /** Stable kebab-case ID of the rule. */
33
+ id: string;
34
+ /** Plain-English statement of the rule. */
35
+ text: string;
36
+ /** When this rule was added (ISO 8601). */
37
+ addedAt: string;
38
+ /** Optional historical incident the rule traces back to. */
39
+ scarFrom?: string;
40
+ /** warn = note it; block = refuse the change. */
41
+ severity: "warn" | "block";
42
+ /** If true, AI may not silently propose removing this rule. */
43
+ immutable?: boolean;
44
+ /** HMAC of the rule body. */
45
+ sig: string;
46
+ }
47
+ export interface ProjectSoul {
48
+ v: typeof PROTOCOL_VERSION;
49
+ project: string;
50
+ /** Free-form "what is the spirit of this project". */
51
+ spirit: string;
52
+ values: SoulRule[];
53
+ antiPatterns: SoulRule[];
54
+ conventions: SoulRule[];
55
+ scars: SoulRule[];
56
+ sacred: SoulRule[];
57
+ updatedAt: string;
58
+ ruleCount: number;
59
+ /** HMAC over the canonical body. Tampering with rules invalidates this. */
60
+ soulSig: string;
61
+ }
62
+ export type SoulCategory = "values" | "antiPatterns" | "conventions" | "scars" | "sacred";
63
+ export interface SoulChange {
64
+ description: string;
65
+ files?: string[];
66
+ addsDeps?: string[];
67
+ codeExcerpts?: string[];
68
+ }
69
+ export interface SoulFinding {
70
+ ruleId: string;
71
+ matchedAnchor: string;
72
+ severity: "warn" | "block";
73
+ evidence: string;
74
+ category: SoulCategory;
75
+ }
76
+ export interface SoulVerdict {
77
+ verdict: "PASS" | "WARN" | "BLOCK";
78
+ findings: SoulFinding[];
79
+ reasons: string[];
80
+ next: string;
81
+ signedAt: string;
82
+ sig: string;
83
+ }
84
+ export declare function newSoul(project: string, spirit: string, opts?: {
85
+ secret?: string;
86
+ }): ProjectSoul;
87
+ export interface AddRuleInput {
88
+ category: SoulCategory;
89
+ id: string;
90
+ text: string;
91
+ severity?: "warn" | "block";
92
+ scarFrom?: string;
93
+ immutable?: boolean;
94
+ secret?: string;
95
+ }
96
+ export declare function addRule(s: ProjectSoul, input: AddRuleInput): ProjectSoul;
97
+ export declare function verifySoul(s: ProjectSoul, secret?: string): {
98
+ ok: boolean;
99
+ reason?: string;
100
+ };
101
+ export declare function saveSoul(s: ProjectSoul, opts?: {
102
+ repoDir?: string;
103
+ }): string;
104
+ export declare function loadSoul(opts?: {
105
+ repoDir?: string;
106
+ }): ProjectSoul | null;
107
+ /**
108
+ * The SOUL GATE. Returns a verdict + HMAC-signed audit trail. Block findings
109
+ * mean "refuse the change". Warn findings mean "log + proceed".
110
+ */
111
+ export declare function checkAgainstSoul(s: ProjectSoul, change: SoulChange, secret?: string): SoulVerdict;
112
+ /** One-line summary for pulse / wisdom output. */
113
+ export declare function formatSoulLine(s: ProjectSoul | null): string;
114
+ /**
115
+ * Sensible default rules every Mneme-managed project starts with.
116
+ * Run once to bootstrap; they're additive so re-running is a no-op
117
+ * for already-present IDs.
118
+ */
119
+ export declare function seedDefaultRules(s: ProjectSoul, opts?: {
120
+ secret?: string;
121
+ }): ProjectSoul;
122
+ export {};
123
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/project_soul/index.ts"],"names":[],"mappings":"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"}
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=project_soul.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project_soul.test.d.ts","sourceRoot":"","sources":["../../src/project_soul/project_soul.test.ts"],"names":[],"mappings":""}