@mneme-ai/core 3.89.0 → 3.91.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.
@@ -1,59 +1,81 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { firewall, parsePolicy, severityFromAge, firewallReport, archFirewallGauntlet } from "./index.js";
2
+ import { firewall, parsePolicy, loadPolicy, scoreSeverity, firewallReport, archFirewallGauntlet, DEFAULT_POLICY } from "./index.js";
3
3
  const baseline = [
4
4
  { path: "schema.prisma", content: "model Wallet { id Int @id }\nmodel Note { id Int @id }" },
5
5
  { path: "a.ts", content: "export function charge(){ return prisma.wallet.create({data:{}}); }\nexport function readNote(){ return prisma.note.findMany(); }" },
6
6
  ];
7
7
  const broke = [...baseline, { path: "refund.ts", content: "export function refundHandler(){ return prisma.wallet.update({where:{}}); }" }];
8
+ const oldAge = () => ({ ageDays: 875, establishedAt: "a1b2c3", heldThroughCommits: 312 });
9
+ const youngAge = () => ({ ageDays: 3 });
8
10
  describe("arch_firewall", () => {
9
11
  it("gauntlet is 100", () => expect(archFirewallGauntlet().score).toBe(100));
10
- it("BLOCKS a broken old contract, names the offending writer + history", () => {
11
- const v = firewall(baseline, broke, { ageResolver: () => ({ ageDays: 426, establishedAt: "a1b2c3", heldThroughCommits: 312 }) });
12
+ it("BLOCKS an old contract (base high +2 ⇒ critical), names the writer + history", () => {
13
+ const v = firewall(baseline, broke, DEFAULT_POLICY, { ageResolver: oldAge });
12
14
  expect(v.verdict).toBe("BLOCK");
13
- expect(v.critical).toBe(1);
14
- expect(v.violations[0].counterexample).toMatch(/refundHandler/);
15
- expect(v.violations[0].heldThroughCommits).toBe(312);
15
+ expect(v.findings[0].finalSeverity).toBe("critical");
16
+ expect(v.findings[0].counterexample).toMatch(/refundHandler/);
17
+ expect(v.findings[0].heldThroughCommits).toBe(312);
16
18
  expect(firewallReport(v)).toMatch(/BLOCKED/);
17
19
  });
18
- it("treats a broken YOUNG contract as evolution (info, not blocked)", () => {
19
- const v = firewall(baseline, broke, { ageResolver: () => ({ ageDays: 3 }) });
20
+ it("WARNs (not BLOCK) for a young contract (base high +0 ⇒ high)", () => {
21
+ const v = firewall(baseline, broke, DEFAULT_POLICY, { ageResolver: youngAge });
22
+ expect(v.verdict).toBe("WARN");
23
+ expect(v.findings[0].finalSeverity).toBe("high");
24
+ });
25
+ it("a waiver suppresses the block", () => {
26
+ const pol = parsePolicy("waive table wallet single-writer :: dual-writer approved in RFC-42");
27
+ const v = firewall(baseline, broke, pol, { ageResolver: oldAge, today: "2026-06-11" });
20
28
  expect(v.verdict).not.toBe("BLOCK");
21
- expect(v.violations[0].severity).toBe("info");
29
+ expect(v.findings[0].waived).toBe(true);
30
+ expect(v.findings[0].waiverReason).toMatch(/RFC-42/);
22
31
  });
23
- it("a declared-critical policy overrides age and forces BLOCK", () => {
24
- const v = firewall(baseline, broke, { policies: parsePolicy("critical table wallet single-writer"), ageResolver: () => ({ ageDays: 3 }) });
32
+ it("an EXPIRED waiver is NOT honoured block stands + surfaced", () => {
33
+ const pol = parsePolicy("waive until=2025-01-01 table wallet single-writer :: temporary");
34
+ const v = firewall(baseline, broke, pol, { ageResolver: oldAge, today: "2026-06-11" });
25
35
  expect(v.verdict).toBe("BLOCK");
26
- expect(v.violations[0].severity).toBe("critical");
36
+ expect(v.findings[0].waiverExpired).toBe(true);
37
+ expect(v.expiredWaivers.length).toBe(1);
27
38
  });
28
39
  it("PASSES when nothing regressed", () => {
29
- const v = firewall(baseline, baseline, { ageResolver: () => ({ ageDays: 999 }) });
40
+ const v = firewall(baseline, baseline, DEFAULT_POLICY, { ageResolver: oldAge });
30
41
  expect(v.verdict).toBe("PASS");
31
- expect(v.violations.length).toBe(0);
32
- });
33
- it("parsePolicy: severity prefix + default warn + comments", () => {
34
- const p = parsePolicy("# header\ncritical table wallet single-writer\nwarn endpoint POST /x exists\ntable note private\n \n");
35
- expect(p.length).toBe(3);
36
- expect(p[0].severity).toBe("critical");
37
- expect(p[1].severity).toBe("warn");
38
- expect(p[2].severity).toBe("warn"); // default
39
- expect(p[2].rule).toBe("table note private");
40
- });
41
- it("severityFromAge thresholds", () => {
42
- expect(severityFromAge(400)).toBe("critical");
43
- expect(severityFromAge(120)).toBe("warn");
44
- expect(severityFromAge(5)).toBe("info");
45
- expect(severityFromAge(null)).toBe("warn");
46
- expect(severityFromAge(undefined)).toBe("warn");
47
- });
48
- it("verdict is the worst severity present (critical > warn > info)", () => {
49
- // declare wallet warn (so the regression is warn, not age-critical) → WARN verdict
50
- const v = firewall(baseline, broke, { policies: parsePolicy("warn table wallet single-writer"), ageResolver: () => ({ ageDays: 999 }) });
51
- expect(v.verdict).toBe("WARN");
42
+ expect(v.clean).toBe(true);
43
+ });
44
+ it("scoreSeverity: age bump, flicker cap, UNKNOWN penalty", () => {
45
+ expect(scoreSeverity({ base: "high", status: "VIOLATED", ageDays: 800, flickered: false, ageWeight: true, ageTiers: DEFAULT_POLICY.ageTiers }).final).toBe("critical"); // +2
46
+ expect(scoreSeverity({ base: "medium", status: "VIOLATED", ageDays: 800, flickered: false, ageWeight: true, ageTiers: DEFAULT_POLICY.ageTiers }).final).toBe("critical"); // medium +2
47
+ expect(scoreSeverity({ base: "medium", status: "VIOLATED", ageDays: 800, flickered: true, ageWeight: true, ageTiers: DEFAULT_POLICY.ageTiers }).final).toBe("high"); // flicker caps +2→+1
48
+ expect(scoreSeverity({ base: "high", status: "UNKNOWN", ageDays: 3, flickered: false, ageWeight: true, ageTiers: DEFAULT_POLICY.ageTiers }).final).toBe("medium"); // +0 −1
49
+ expect(scoreSeverity({ base: "medium", status: "VIOLATED", ageDays: 200, flickered: false, ageWeight: true, ageTiers: DEFAULT_POLICY.ageTiers }).final).toBe("high"); // +1
50
+ });
51
+ it("parsePolicy: directives + enforce + waiver(+until)", () => {
52
+ const p = parsePolicy("# header\nname payments\nblockon high\ndefault single-writer critical\nagetier 30 1\ncritical table x single-writer\nwaive until=2030-01-01 table y private :: ok");
53
+ expect(p.name).toBe("payments");
54
+ expect(p.blockOn).toBe("high");
55
+ expect(p.defaults["single-writer"]).toBe("critical");
56
+ expect(p.enforce.length).toBe(1);
57
+ expect(p.enforce[0].severity).toBe("critical");
58
+ expect(p.waivers[0].until).toBe("2030-01-01");
59
+ expect(p.ageTiers.some((t) => t.minDays === 30 && t.bump === 1)).toBe(true);
60
+ });
61
+ it("an enforce override changes the base severity", () => {
62
+ // pin wallet single-writer to 'critical' base → even at 3 days it blocks (critical ≥ blockOn critical)
63
+ const pol = parsePolicy("critical table wallet single-writer");
64
+ const v = firewall(baseline, broke, pol, { ageResolver: youngAge });
65
+ expect(v.verdict).toBe("BLOCK");
66
+ });
67
+ it("loadPolicy parses JSON and falls back to DSL", () => {
68
+ const j = loadPolicy(JSON.stringify({ name: "j", blockOn: "high", waivers: [{ rule: "table wallet single-writer", reason: "x" }] }));
69
+ expect(j.name).toBe("j");
70
+ expect(j.blockOn).toBe("high");
71
+ expect(j.waivers.length).toBe(1);
72
+ expect(loadPolicy("critical table z private").enforce.length).toBe(1);
52
73
  });
53
74
  it("never throws on garbage", () => {
54
75
  expect(() => firewall(null, null)).not.toThrow();
55
76
  expect(firewall(null, null).verdict).toBe("PASS");
56
77
  expect(() => parsePolicy(null)).not.toThrow();
78
+ expect(() => loadPolicy("{bad json")).not.toThrow();
57
79
  });
58
80
  });
59
81
  //# sourceMappingURL=arch_firewall.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"arch_firewall.test.js","sourceRoot":"","sources":["../../src/arch_firewall/arch_firewall.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"arch_firewall.test.js","sourceRoot":"","sources":["../../src/arch_firewall/arch_firewall.test.ts"],"names":[],"mappings":"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"}
@@ -1,51 +1,89 @@
1
1
  import { type SourceFile } from "../cross_layer_graph/index.js";
2
- export type Severity = "critical" | "warn" | "info";
3
- export interface Policy {
2
+ export type Severity = "info" | "low" | "medium" | "high" | "critical";
3
+ export interface AgeTier {
4
+ minDays: number;
5
+ bump: number;
6
+ }
7
+ export interface Waiver {
4
8
  rule: string;
5
- severity: Severity;
6
- raw: string;
7
- }
8
- /**
9
- * Parse a policy file. Each non-comment line is `[critical|warn|info] <invariant-rule>`; the severity
10
- * prefix is optional (defaults to `warn`). e.g. `critical table wallet single-writer`.
11
- */
12
- export declare function parsePolicy(text: string): Policy[];
13
- /** Severity weighted by how long a contract has stood. Old contract broken = crime; young = evolution. */
14
- export declare function severityFromAge(ageDays: number | null | undefined): Severity;
9
+ reason: string;
10
+ until?: string;
11
+ }
12
+ export interface FirewallPolicy {
13
+ name: string;
14
+ defaults: Record<string, Severity>;
15
+ enforce: Array<{
16
+ rule: string;
17
+ severity: Severity;
18
+ }>;
19
+ declared: string[];
20
+ waivers: Waiver[];
21
+ ageWeight: boolean;
22
+ ageTiers: AgeTier[];
23
+ blockOn: Severity;
24
+ }
25
+ export declare const DEFAULT_POLICY: FirewallPolicy;
26
+ /** Parse the line-DSL policy. Directives: `blockon <sev>`, `default <kind> <sev>`, `agetier <days> <bump>`,
27
+ * `waive [until=YYYY-MM-DD] <rule> :: <reason>`. Rule lines: `[<sev>] <invariant-rule>`. `#` comments. */
28
+ export declare function parsePolicy(text: string): FirewallPolicy;
29
+ /** Load a policy from JSON (full structured) or the line DSL, merged onto DEFAULT_POLICY. */
30
+ export declare function loadPolicy(raw: string): FirewallPolicy;
31
+ export interface ScoreInput {
32
+ base: Severity;
33
+ status: "VIOLATED" | "UNKNOWN";
34
+ ageDays: number | null;
35
+ flickered?: boolean;
36
+ ageWeight: boolean;
37
+ ageTiers: ReadonlyArray<AgeTier>;
38
+ }
39
+ /** final = base + age-tier bump − UNKNOWN penalty, with a flicker cap and a transparent rationale. */
40
+ export declare function scoreSeverity(s: ScoreInput): {
41
+ final: Severity;
42
+ rationale: string;
43
+ };
15
44
  export interface AgeInfo {
16
45
  ageDays: number;
17
46
  establishedAt?: string;
18
47
  heldThroughCommits?: number;
48
+ flickered?: boolean;
19
49
  }
20
- export interface FirewallViolation {
50
+ export interface FirewallFinding {
21
51
  rule: string;
22
- severity: Severity;
52
+ kind: string;
53
+ status: "VIOLATED" | "UNKNOWN";
23
54
  reason: string;
24
55
  counterexample?: string;
25
56
  source: "mined" | "declared";
26
- ageDays?: number | null;
57
+ baseSeverity: Severity;
58
+ finalSeverity: Severity;
59
+ rationale: string;
60
+ ageDays: number | null;
27
61
  establishedAt?: string;
28
62
  heldThroughCommits?: number;
63
+ waived: boolean;
64
+ waiverReason?: string;
65
+ waiverExpired: boolean;
66
+ blocking: boolean;
29
67
  }
30
68
  export interface FirewallVerdict {
31
69
  verdict: "PASS" | "WARN" | "BLOCK";
32
- violations: FirewallViolation[];
70
+ policyName: string;
71
+ baselineContracts: number;
72
+ findings: FirewallFinding[];
73
+ blocked: boolean;
74
+ blockedBy: FirewallFinding[];
75
+ expiredWaivers: FirewallFinding[];
76
+ waivedCount: number;
77
+ clean: boolean;
33
78
  critical: number;
34
- warn: number;
35
- info: number;
36
- checkedContracts: number;
37
- declaredChecked: number;
38
- }
39
- /**
40
- * Run the firewall: which baseline contracts (and which architect-declared policies) does the current
41
- * code violate, weighted into PASS / WARN / BLOCK. `ageResolver` (optional, git-backed in the caller)
42
- * supplies how long each violated contract has stood; in tests pass a stub.
43
- */
44
- export declare function firewall(baselineFiles: ReadonlyArray<SourceFile>, currentFiles: ReadonlyArray<SourceFile>, opts?: {
45
- policies?: ReadonlyArray<Policy>;
79
+ high: number;
80
+ blockOn: Severity;
81
+ }
82
+ export declare function firewall(baselineFiles: ReadonlyArray<SourceFile>, currentFiles: ReadonlyArray<SourceFile>, policy?: FirewallPolicy, opts?: {
46
83
  ageResolver?: (rule: string) => AgeInfo | null;
84
+ today?: string;
47
85
  }): FirewallVerdict;
48
- /** A human/PR-comment rendering of the verdict, with the killer line per violation. */
86
+ /** Plain-text verdict, ready for a terminal or a PR comment. */
49
87
  export declare function firewallReport(v: FirewallVerdict): string;
50
88
  export interface ArchFirewallGauntlet {
51
89
  score: 0 | 100;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/arch_firewall/index.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAEhE,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,MAAM;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE;AAEzE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAUlD;AAED,0GAA0G;AAC1G,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,CAK5E;AAED,MAAM,WAAW,OAAO;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE;AACjG,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAC1E,MAAM,EAAE,OAAO,GAAG,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5G;AACD,MAAM,WAAW,eAAe;IAAG,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAAC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE;AAQzM;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,aAAa,EAAE,aAAa,CAAC,UAAU,CAAC,EACxC,YAAY,EAAE,aAAa,CAAC,UAAU,CAAC,EACvC,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAA;CAAE,GAC1F,eAAe,CAkCjB;AAED,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAUzD;AAGD,MAAM,WAAW,oBAAoB;IAAG,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE;AACxH,wBAAgB,oBAAoB,IAAI,oBAAoB,CAuC3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/arch_firewall/index.ts"],"names":[],"mappings":"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"}