@mneme-ai/core 2.19.21 → 2.19.23

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 (86) hide show
  1. package/dist/autonomic_breath/autonomic_breath.test.d.ts +2 -0
  2. package/dist/autonomic_breath/autonomic_breath.test.d.ts.map +1 -0
  3. package/dist/autonomic_breath/autonomic_breath.test.js +140 -0
  4. package/dist/autonomic_breath/autonomic_breath.test.js.map +1 -0
  5. package/dist/autonomic_breath/index.d.ts +135 -0
  6. package/dist/autonomic_breath/index.d.ts.map +1 -0
  7. package/dist/autonomic_breath/index.js +180 -0
  8. package/dist/autonomic_breath/index.js.map +1 -0
  9. package/dist/catalog_parity/catalog_parity.test.d.ts +2 -0
  10. package/dist/catalog_parity/catalog_parity.test.d.ts.map +1 -0
  11. package/dist/catalog_parity/catalog_parity.test.js +104 -0
  12. package/dist/catalog_parity/catalog_parity.test.js.map +1 -0
  13. package/dist/catalog_parity/index.d.ts +69 -0
  14. package/dist/catalog_parity/index.d.ts.map +1 -0
  15. package/dist/catalog_parity/index.js +118 -0
  16. package/dist/catalog_parity/index.js.map +1 -0
  17. package/dist/cosmic/aurelian_v1922.test.d.ts +2 -0
  18. package/dist/cosmic/aurelian_v1922.test.d.ts.map +1 -0
  19. package/dist/cosmic/aurelian_v1922.test.js +48 -0
  20. package/dist/cosmic/aurelian_v1922.test.js.map +1 -0
  21. package/dist/cosmic/aurelian_v1923.test.d.ts +2 -0
  22. package/dist/cosmic/aurelian_v1923.test.d.ts.map +1 -0
  23. package/dist/cosmic/aurelian_v1923.test.js +89 -0
  24. package/dist/cosmic/aurelian_v1923.test.js.map +1 -0
  25. package/dist/dynamic/pack-schema.d.ts +14 -14
  26. package/dist/hippocampus_dreams/hippocampus_dreams.test.d.ts +2 -0
  27. package/dist/hippocampus_dreams/hippocampus_dreams.test.d.ts.map +1 -0
  28. package/dist/hippocampus_dreams/hippocampus_dreams.test.js +106 -0
  29. package/dist/hippocampus_dreams/hippocampus_dreams.test.js.map +1 -0
  30. package/dist/hippocampus_dreams/index.d.ts +79 -0
  31. package/dist/hippocampus_dreams/index.d.ts.map +1 -0
  32. package/dist/hippocampus_dreams/index.js +122 -0
  33. package/dist/hippocampus_dreams/index.js.map +1 -0
  34. package/dist/hormonal/hormonal.test.d.ts +2 -0
  35. package/dist/hormonal/hormonal.test.d.ts.map +1 -0
  36. package/dist/hormonal/hormonal.test.js +116 -0
  37. package/dist/hormonal/hormonal.test.js.map +1 -0
  38. package/dist/hormonal/index.d.ts +105 -0
  39. package/dist/hormonal/index.d.ts.map +1 -0
  40. package/dist/hormonal/index.js +132 -0
  41. package/dist/hormonal/index.js.map +1 -0
  42. package/dist/index.d.ts +8 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +9 -0
  45. package/dist/index.js.map +1 -1
  46. package/dist/periodic/periodic.test.js +1 -1
  47. package/dist/periodic/periodic.test.js.map +1 -1
  48. package/dist/proprioception/index.d.ts +82 -0
  49. package/dist/proprioception/index.d.ts.map +1 -0
  50. package/dist/proprioception/index.js +170 -0
  51. package/dist/proprioception/index.js.map +1 -0
  52. package/dist/proprioception/proprioception.test.d.ts +2 -0
  53. package/dist/proprioception/proprioception.test.d.ts.map +1 -0
  54. package/dist/proprioception/proprioception.test.js +159 -0
  55. package/dist/proprioception/proprioception.test.js.map +1 -0
  56. package/dist/reflex/index.d.ts +210 -0
  57. package/dist/reflex/index.d.ts.map +1 -0
  58. package/dist/reflex/index.js +298 -0
  59. package/dist/reflex/index.js.map +1 -0
  60. package/dist/reflex/reflex.test.d.ts +2 -0
  61. package/dist/reflex/reflex.test.d.ts.map +1 -0
  62. package/dist/reflex/reflex.test.js +379 -0
  63. package/dist/reflex/reflex.test.js.map +1 -0
  64. package/dist/spinal_reflex/index.d.ts +86 -0
  65. package/dist/spinal_reflex/index.d.ts.map +1 -0
  66. package/dist/spinal_reflex/index.js +180 -0
  67. package/dist/spinal_reflex/index.js.map +1 -0
  68. package/dist/spinal_reflex/spinal_reflex.test.d.ts +2 -0
  69. package/dist/spinal_reflex/spinal_reflex.test.d.ts.map +1 -0
  70. package/dist/spinal_reflex/spinal_reflex.test.js +168 -0
  71. package/dist/spinal_reflex/spinal_reflex.test.js.map +1 -0
  72. package/dist/thalamus/index.d.ts +92 -0
  73. package/dist/thalamus/index.d.ts.map +1 -0
  74. package/dist/thalamus/index.js +95 -0
  75. package/dist/thalamus/index.js.map +1 -0
  76. package/dist/thalamus/thalamus.test.d.ts +2 -0
  77. package/dist/thalamus/thalamus.test.d.ts.map +1 -0
  78. package/dist/thalamus/thalamus.test.js +101 -0
  79. package/dist/thalamus/thalamus.test.js.map +1 -0
  80. package/dist/whats_new.d.ts.map +1 -1
  81. package/dist/whats_new.js +16 -0
  82. package/dist/whats_new.js.map +1 -1
  83. package/dist/wrapper_genesis/index.d.ts.map +1 -1
  84. package/dist/wrapper_genesis/index.js +41 -0
  85. package/dist/wrapper_genesis/index.js.map +1 -1
  86. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=autonomic_breath.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autonomic_breath.test.d.ts","sourceRoot":"","sources":["../../src/autonomic_breath/autonomic_breath.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,140 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { decideBreath, heartbeatBudgetMs, emptyLedger, recordBreath, verifyLedger, computeStats, formatBreathLine, } from "./index.js";
3
+ const SECRET = "breath-test-secret-997744";
4
+ function probeAlive() {
5
+ return { pidIsAlive: true, pidFileExists: true, pid: 1234, pidFileMtimeMs: 1_000_000, nowMs: 1_000_000 };
6
+ }
7
+ function probeDead() {
8
+ return { pidIsAlive: false, pidFileExists: true, pid: 1234, pidFileMtimeMs: 1_000_000, nowMs: 1_000_000 };
9
+ }
10
+ function probeNoPid() {
11
+ return { pidIsAlive: false, pidFileExists: false, pid: NaN, pidFileMtimeMs: 0, nowMs: 1_000_000 };
12
+ }
13
+ describe("v2.19.23 BREATH · decideBreath (G1 killer)", () => {
14
+ it("alive daemon -> no respawn", () => {
15
+ const d = decideBreath({ probe: probeAlive() });
16
+ expect(d.shouldRespawn).toBe(false);
17
+ expect(d.shouldCleanStalePidFile).toBe(false);
18
+ expect(d.reason).toContain("already_alive");
19
+ });
20
+ it("no PID file -> respawn (never_started)", () => {
21
+ const d = decideBreath({ probe: probeNoPid() });
22
+ expect(d.shouldRespawn).toBe(true);
23
+ expect(d.shouldCleanStalePidFile).toBe(false);
24
+ expect(d.reason).toContain("no_pid_file");
25
+ });
26
+ it("dead PID + fresh file -> respawn + clean", () => {
27
+ const d = decideBreath({ probe: probeDead() });
28
+ expect(d.shouldRespawn).toBe(true);
29
+ expect(d.shouldCleanStalePidFile).toBe(true);
30
+ expect(d.reason).toContain("dead_pid");
31
+ });
32
+ it("dead PID + 31-day-old file -> respawn + clean (stale)", () => {
33
+ const probe = {
34
+ pidIsAlive: false, pidFileExists: true, pid: 1, pidFileMtimeMs: 0,
35
+ nowMs: 31 * 86400 * 1000,
36
+ };
37
+ const d = decideBreath({ probe });
38
+ expect(d.shouldRespawn).toBe(true);
39
+ expect(d.shouldCleanStalePidFile).toBe(true);
40
+ expect(d.reason).toContain("stale_pid");
41
+ });
42
+ it("default policy: windowsHide + detached + silentStdio = true (silent ghost-sniper)", () => {
43
+ const d = decideBreath({ probe: probeNoPid() });
44
+ expect(d.windowsHide).toBe(true);
45
+ expect(d.detached).toBe(true);
46
+ expect(d.silentStdio).toBe(true);
47
+ });
48
+ it("caller can override hints (foreground debug mode)", () => {
49
+ const d = decideBreath({ probe: probeNoPid(), windowsHide: false, silentStdio: false });
50
+ expect(d.windowsHide).toBe(false);
51
+ expect(d.silentStdio).toBe(false);
52
+ });
53
+ });
54
+ describe("v2.19.23 BREATH · heartbeatBudgetMs (HORMONAL coupling)", () => {
55
+ it("zero fatigue -> 50ms", () => {
56
+ expect(heartbeatBudgetMs()).toBe(50);
57
+ expect(heartbeatBudgetMs({ hormonal: { fatigue: 0 } })).toBe(50);
58
+ });
59
+ it("full fatigue -> 200ms (linear scale)", () => {
60
+ expect(heartbeatBudgetMs({ hormonal: { fatigue: 1 } })).toBe(200);
61
+ });
62
+ it("mid fatigue -> ~125ms", () => {
63
+ expect(heartbeatBudgetMs({ hormonal: { fatigue: 0.5 } })).toBe(125);
64
+ });
65
+ it("clamps out-of-range fatigue", () => {
66
+ expect(heartbeatBudgetMs({ hormonal: { fatigue: -1 } })).toBe(50);
67
+ expect(heartbeatBudgetMs({ hormonal: { fatigue: 99 } })).toBe(200);
68
+ });
69
+ });
70
+ describe("v2.19.23 BREATH · ledger (HMAC chain)", () => {
71
+ function ok(action, ms = 12) {
72
+ return { action, ms };
73
+ }
74
+ it("recordBreath appends + chains; verify passes on untampered", () => {
75
+ let L = emptyLedger();
76
+ const probe = probeAlive();
77
+ const decision = decideBreath({ probe });
78
+ L = recordBreath({ ledger: L, probe, decision, outcome: ok("already_alive"), secret: SECRET });
79
+ L = recordBreath({ ledger: L, probe: probeDead(), decision: decideBreath({ probe: probeDead() }), outcome: ok("respawned", 250), secret: SECRET });
80
+ expect(L.records).toHaveLength(2);
81
+ expect(L.records[0].prevSig).toBeNull();
82
+ expect(L.records[1].prevSig).toBe(L.records[0].sig);
83
+ expect(verifyLedger(L, SECRET).ok).toBe(true);
84
+ });
85
+ it("verifyLedger detects tamper at exact step", () => {
86
+ let L = emptyLedger();
87
+ const probe = probeAlive();
88
+ for (let i = 0; i < 4; i++) {
89
+ L = recordBreath({ ledger: L, probe, decision: decideBreath({ probe }), outcome: ok("already_alive", i), secret: SECRET });
90
+ }
91
+ const tampered = {
92
+ ...L,
93
+ records: L.records.map((r, i) => (i === 2 ? { ...r, outcome: { ...r.outcome, ms: 999 } } : r)),
94
+ };
95
+ const v = verifyLedger(tampered, SECRET);
96
+ expect(v.ok).toBe(false);
97
+ expect(v.brokenAt).toBe(2);
98
+ });
99
+ it("computeStats: alive 4, respawn 1, failed 0 -> uptimeRatio 4/5", () => {
100
+ let L = emptyLedger();
101
+ const aliveDecision = decideBreath({ probe: probeAlive() });
102
+ const respawnDecision = decideBreath({ probe: probeDead() });
103
+ for (let i = 0; i < 4; i++) {
104
+ L = recordBreath({ ledger: L, probe: probeAlive(), decision: aliveDecision, outcome: ok("already_alive"), secret: SECRET });
105
+ }
106
+ L = recordBreath({ ledger: L, probe: probeDead(), decision: respawnDecision, outcome: ok("respawned", 250), secret: SECRET });
107
+ const s = computeStats(L);
108
+ expect(s.totalChecks).toBe(5);
109
+ expect(s.alreadyAlive).toBe(4);
110
+ expect(s.respawned).toBe(1);
111
+ expect(s.uptimeRatio).toBeCloseTo(4 / 5, 5);
112
+ });
113
+ it("MEASURED 100% determinism: same input -> same chain sig (20 trials)", () => {
114
+ const probe = probeAlive();
115
+ const decision = decideBreath({ probe });
116
+ const outcome = ok("already_alive", 12);
117
+ const baseLedger = recordBreath({ ledger: emptyLedger(), probe, decision, outcome, nowMs: 1_000_000, secret: SECRET });
118
+ const firstSig = baseLedger.records[0].sig;
119
+ let allEqual = true;
120
+ for (let i = 0; i < 20; i++) {
121
+ const L = recordBreath({ ledger: emptyLedger(), probe, decision, outcome, nowMs: 1_000_000, secret: SECRET });
122
+ if (L.records[0].sig !== firstSig) {
123
+ allEqual = false;
124
+ break;
125
+ }
126
+ }
127
+ expect(allEqual).toBe(true);
128
+ });
129
+ });
130
+ describe("v2.19.23 BREATH · formatter", () => {
131
+ it("formatBreathLine uses 🫁 / 🌱 / 💀 / 🧹 per action", () => {
132
+ const probe = probeAlive();
133
+ const decision = decideBreath({ probe });
134
+ expect(formatBreathLine(decision, { action: "already_alive", ms: 12 })).toContain("🫁");
135
+ expect(formatBreathLine(decision, { action: "respawned", ms: 250 })).toContain("🌱");
136
+ expect(formatBreathLine(decision, { action: "failed", ms: 5 })).toContain("💀");
137
+ expect(formatBreathLine(decision, { action: "stale_pid_cleaned", ms: 2 })).toContain("🧹");
138
+ });
139
+ });
140
+ //# sourceMappingURL=autonomic_breath.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autonomic_breath.test.js","sourceRoot":"","sources":["../../src/autonomic_breath/autonomic_breath.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * v2.19.23 — MNEME AUTONOMIC BREATH (G1 killer · organ #1 of LIMBIC)
3
+ *
4
+ * "Pulse says 'daemon=running' but status says 'not running' — info
5
+ * drift. DREAMS / CONSEQUENCE / NEGEV / AUTO-ACTION ทั้งหมดไม่หมุน
6
+ * เพราะไม่มี scheduler. user ที่ install Mneme แล้วไม่รู้ว่าต้อง
7
+ * `mneme daemon start` — ใช้แค่ pull-only features."
8
+ * — user audit, 2026-05-17
9
+ *
10
+ * Diagnosis: human ไม่ต้อง "คิด" ว่าจะหายใจ. Mneme ทุก function เหมือน
11
+ * กล้ามเนื้อ — ต้องคิดเองว่าจะใช้ตอนไหน. 90/100 features ค้าง.
12
+ *
13
+ * Fix at SOURCE: every `mneme <cmd>` invocation does a 50ms silent
14
+ * PID heartbeat check. Dead → respawn BEFORE the real command runs.
15
+ * User never has to know `mneme daemon start` exists.
16
+ *
17
+ * Composes onto packages/cli/src/commands/daemon.ts (existing PID file
18
+ * + isAlive + spawn detached + writeFileSync PID). This module is
19
+ * pure-function decision logic; the CLI bin file does the actual
20
+ * spawn + fs work. Same separation as v2.19.21 SNN AUTO-PROMOTE.
21
+ *
22
+ * Honest scope:
23
+ * - DECIDES, never SPAWNS. Caller (CLI bin) does the spawn.
24
+ * - Silent on success (user sees nothing); LOUD on respawn-failed
25
+ * (caller decides what to print, but action is reported as 'failed').
26
+ * - Heartbeat budget: 50ms default. Caller times out their own
27
+ * `process.kill(pid, 0)` if needed.
28
+ * - HMAC-chained ledger of every (check, action, outcome) so the daemon
29
+ * can audit "how often was I dead when user invoked me?"
30
+ * - Multi-platform decisions (windowsHide / detached / stdio) are
31
+ * hints; CLI implements them.
32
+ */
33
+ declare const PROTOCOL_VERSION: 1;
34
+ export type BreathAction = "already_alive" | "respawned" | "stale_pid_cleaned" | "no_pid_file" | "failed";
35
+ export interface BreathProbe {
36
+ /** Caller-side: did `process.kill(pid, 0)` succeed? */
37
+ pidIsAlive: boolean;
38
+ /** Caller-side: does the PID file exist? */
39
+ pidFileExists: boolean;
40
+ /** Caller-side: PID value read from file (NaN if absent). */
41
+ pid: number;
42
+ /** Caller-side: mtime of PID file in ms epoch (0 if absent). */
43
+ pidFileMtimeMs: number;
44
+ /** Caller's current wall-clock in ms epoch. */
45
+ nowMs: number;
46
+ }
47
+ export interface BreathDecision {
48
+ v: typeof PROTOCOL_VERSION;
49
+ shouldRespawn: boolean;
50
+ shouldCleanStalePidFile: boolean;
51
+ reason: string;
52
+ /** Suggested spawn budget — caller raises a timeout against this. */
53
+ respawnBudgetMs: number;
54
+ /** Caller decision: hide window on Windows? Daemon is silent service. */
55
+ windowsHide: boolean;
56
+ /** Caller decision: detach from parent so daemon survives shell close. */
57
+ detached: boolean;
58
+ /** Caller decision: ignore stdio so user doesn't see daemon output. */
59
+ silentStdio: boolean;
60
+ }
61
+ export interface BreathOutcome {
62
+ action: BreathAction;
63
+ ms: number;
64
+ errorMessage?: string;
65
+ }
66
+ export interface BreathRecord {
67
+ v: typeof PROTOCOL_VERSION;
68
+ ts: number;
69
+ probe: BreathProbe;
70
+ decision: BreathDecision;
71
+ outcome: BreathOutcome;
72
+ prevSig: string | null;
73
+ sig: string;
74
+ }
75
+ export interface BreathLedger {
76
+ v: typeof PROTOCOL_VERSION;
77
+ records: BreathRecord[];
78
+ }
79
+ /**
80
+ * Decide whether the daemon needs respawning given a heartbeat probe.
81
+ *
82
+ * Rules:
83
+ * - no pid file at all → respawn (with reason: no_pid_file)
84
+ * - pid file present + alive → no respawn (already_alive)
85
+ * - pid file present + dead + pid file is fresh (<30 days) →
86
+ * respawn + clean stale pid (likely crash)
87
+ * - pid file present + dead + pid file is stale (>30 days) →
88
+ * respawn + clean stale pid (old workspace; safe to restart)
89
+ *
90
+ * Returns a structured decision; caller acts on it.
91
+ */
92
+ export declare function decideBreath(input: {
93
+ probe: BreathProbe;
94
+ respawnBudgetMs?: number;
95
+ windowsHide?: boolean;
96
+ detached?: boolean;
97
+ silentStdio?: boolean;
98
+ }): BreathDecision;
99
+ /**
100
+ * Returns the suggested heartbeat budget for the caller to use. Pure;
101
+ * returns the constant. Exposed so callers can adjust under HORMONAL
102
+ * state (high fatigue → longer interval).
103
+ */
104
+ export declare function heartbeatBudgetMs(opts?: {
105
+ hormonal?: {
106
+ fatigue?: number;
107
+ };
108
+ }): number;
109
+ export declare function emptyLedger(): BreathLedger;
110
+ export declare function recordBreath(input: {
111
+ ledger: BreathLedger;
112
+ probe: BreathProbe;
113
+ decision: BreathDecision;
114
+ outcome: BreathOutcome;
115
+ nowMs?: number;
116
+ secret?: string;
117
+ }): BreathLedger;
118
+ export declare function verifyLedger(ledger: BreathLedger, secret?: string): {
119
+ ok: boolean;
120
+ brokenAt?: number;
121
+ reason?: string;
122
+ };
123
+ export interface BreathStats {
124
+ totalChecks: number;
125
+ alreadyAlive: number;
126
+ respawned: number;
127
+ staleCleaned: number;
128
+ failed: number;
129
+ /** alreadyAlive / total — daemon was up when called. 1.0 = always up. */
130
+ uptimeRatio: number;
131
+ }
132
+ export declare function computeStats(ledger: BreathLedger): BreathStats;
133
+ export declare function formatBreathLine(d: BreathDecision, o: BreathOutcome): string;
134
+ export {};
135
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/autonomic_breath/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * v2.19.23 — MNEME AUTONOMIC BREATH (G1 killer · organ #1 of LIMBIC)
3
+ *
4
+ * "Pulse says 'daemon=running' but status says 'not running' — info
5
+ * drift. DREAMS / CONSEQUENCE / NEGEV / AUTO-ACTION ทั้งหมดไม่หมุน
6
+ * เพราะไม่มี scheduler. user ที่ install Mneme แล้วไม่รู้ว่าต้อง
7
+ * `mneme daemon start` — ใช้แค่ pull-only features."
8
+ * — user audit, 2026-05-17
9
+ *
10
+ * Diagnosis: human ไม่ต้อง "คิด" ว่าจะหายใจ. Mneme ทุก function เหมือน
11
+ * กล้ามเนื้อ — ต้องคิดเองว่าจะใช้ตอนไหน. 90/100 features ค้าง.
12
+ *
13
+ * Fix at SOURCE: every `mneme <cmd>` invocation does a 50ms silent
14
+ * PID heartbeat check. Dead → respawn BEFORE the real command runs.
15
+ * User never has to know `mneme daemon start` exists.
16
+ *
17
+ * Composes onto packages/cli/src/commands/daemon.ts (existing PID file
18
+ * + isAlive + spawn detached + writeFileSync PID). This module is
19
+ * pure-function decision logic; the CLI bin file does the actual
20
+ * spawn + fs work. Same separation as v2.19.21 SNN AUTO-PROMOTE.
21
+ *
22
+ * Honest scope:
23
+ * - DECIDES, never SPAWNS. Caller (CLI bin) does the spawn.
24
+ * - Silent on success (user sees nothing); LOUD on respawn-failed
25
+ * (caller decides what to print, but action is reported as 'failed').
26
+ * - Heartbeat budget: 50ms default. Caller times out their own
27
+ * `process.kill(pid, 0)` if needed.
28
+ * - HMAC-chained ledger of every (check, action, outcome) so the daemon
29
+ * can audit "how often was I dead when user invoked me?"
30
+ * - Multi-platform decisions (windowsHide / detached / stdio) are
31
+ * hints; CLI implements them.
32
+ */
33
+ import { createHmac, timingSafeEqual } from "node:crypto";
34
+ const PROTOCOL_VERSION = 1;
35
+ const DEFAULT_HEARTBEAT_BUDGET_MS = 50;
36
+ const DEFAULT_RESPAWN_BUDGET_MS = 500;
37
+ const STALE_PID_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
38
+ // ─── canonical helpers ────────────────────────────────────────────────
39
+ function canon(v) {
40
+ if (v === null || typeof v !== "object")
41
+ return JSON.stringify(v);
42
+ if (Array.isArray(v))
43
+ return "[" + v.map(canon).join(",") + "]";
44
+ const keys = Object.keys(v).sort();
45
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
46
+ }
47
+ function defaultSecret() {
48
+ return process.env["MNEME_BREATH_SECRET"] || `mneme-autonomic-breath-v${PROTOCOL_VERSION}`;
49
+ }
50
+ function hmacHex(body, secret) {
51
+ return createHmac("sha256", secret).update(canon(body)).digest("hex");
52
+ }
53
+ function safeEqHex(a, b) {
54
+ try {
55
+ return timingSafeEqual(Buffer.from(a, "hex"), Buffer.from(b, "hex"));
56
+ }
57
+ catch {
58
+ return false;
59
+ }
60
+ }
61
+ // ─── decision logic ───────────────────────────────────────────────────
62
+ /**
63
+ * Decide whether the daemon needs respawning given a heartbeat probe.
64
+ *
65
+ * Rules:
66
+ * - no pid file at all → respawn (with reason: no_pid_file)
67
+ * - pid file present + alive → no respawn (already_alive)
68
+ * - pid file present + dead + pid file is fresh (<30 days) →
69
+ * respawn + clean stale pid (likely crash)
70
+ * - pid file present + dead + pid file is stale (>30 days) →
71
+ * respawn + clean stale pid (old workspace; safe to restart)
72
+ *
73
+ * Returns a structured decision; caller acts on it.
74
+ */
75
+ export function decideBreath(input) {
76
+ const respawnBudgetMs = input.respawnBudgetMs ?? DEFAULT_RESPAWN_BUDGET_MS;
77
+ const windowsHide = input.windowsHide ?? true;
78
+ const detached = input.detached ?? true;
79
+ const silentStdio = input.silentStdio ?? true;
80
+ let shouldRespawn = false;
81
+ let shouldClean = false;
82
+ let reason;
83
+ if (!input.probe.pidFileExists) {
84
+ shouldRespawn = true;
85
+ reason = "no_pid_file: daemon never started or pid was cleaned";
86
+ }
87
+ else if (input.probe.pidIsAlive) {
88
+ shouldRespawn = false;
89
+ reason = `already_alive: pid=${input.probe.pid} responding to kill(0)`;
90
+ }
91
+ else {
92
+ shouldRespawn = true;
93
+ shouldClean = true;
94
+ const ageMs = input.probe.nowMs - input.probe.pidFileMtimeMs;
95
+ if (ageMs > STALE_PID_THRESHOLD_MS) {
96
+ reason = `stale_pid: file age ${Math.round(ageMs / 86400000)}d > ${Math.round(STALE_PID_THRESHOLD_MS / 86400000)}d threshold`;
97
+ }
98
+ else {
99
+ reason = `dead_pid: pid=${input.probe.pid} not alive (likely crash); pid file fresh`;
100
+ }
101
+ }
102
+ return {
103
+ v: PROTOCOL_VERSION,
104
+ shouldRespawn,
105
+ shouldCleanStalePidFile: shouldClean,
106
+ reason,
107
+ respawnBudgetMs,
108
+ windowsHide,
109
+ detached,
110
+ silentStdio,
111
+ };
112
+ }
113
+ /**
114
+ * Returns the suggested heartbeat budget for the caller to use. Pure;
115
+ * returns the constant. Exposed so callers can adjust under HORMONAL
116
+ * state (high fatigue → longer interval).
117
+ */
118
+ export function heartbeatBudgetMs(opts) {
119
+ const f = Math.max(0, Math.min(1, opts?.hormonal?.fatigue ?? 0));
120
+ // Linear scaling: 0 fatigue → 50ms; 1 fatigue → 200ms (back off when system is loaded).
121
+ return Math.round(DEFAULT_HEARTBEAT_BUDGET_MS + f * 150);
122
+ }
123
+ // ─── ledger ───────────────────────────────────────────────────────────
124
+ export function emptyLedger() {
125
+ return { v: PROTOCOL_VERSION, records: [] };
126
+ }
127
+ export function recordBreath(input) {
128
+ const prev = input.ledger.records[input.ledger.records.length - 1];
129
+ const body = {
130
+ v: PROTOCOL_VERSION,
131
+ ts: input.nowMs ?? input.probe.nowMs,
132
+ probe: input.probe,
133
+ decision: input.decision,
134
+ outcome: input.outcome,
135
+ prevSig: prev ? prev.sig : null,
136
+ };
137
+ const sig = hmacHex(body, input.secret ?? defaultSecret());
138
+ return { v: PROTOCOL_VERSION, records: [...input.ledger.records, { ...body, sig }] };
139
+ }
140
+ export function verifyLedger(ledger, secret) {
141
+ const sec = secret ?? defaultSecret();
142
+ let prevSig = null;
143
+ for (let i = 0; i < ledger.records.length; i++) {
144
+ const r = ledger.records[i];
145
+ const { sig, ...body } = r;
146
+ if (body.prevSig !== prevSig)
147
+ return { ok: false, brokenAt: i, reason: `prevSig mismatch at step ${i}` };
148
+ if (!safeEqHex(hmacHex(body, sec), sig))
149
+ return { ok: false, brokenAt: i, reason: `HMAC mismatch at step ${i}` };
150
+ prevSig = sig;
151
+ }
152
+ return { ok: true };
153
+ }
154
+ export function computeStats(ledger) {
155
+ let alreadyAlive = 0, respawned = 0, staleCleaned = 0, failed = 0;
156
+ for (const r of ledger.records) {
157
+ if (r.outcome.action === "already_alive")
158
+ alreadyAlive++;
159
+ else if (r.outcome.action === "respawned")
160
+ respawned++;
161
+ else if (r.outcome.action === "stale_pid_cleaned")
162
+ staleCleaned++;
163
+ else if (r.outcome.action === "failed")
164
+ failed++;
165
+ }
166
+ const total = ledger.records.length;
167
+ return {
168
+ totalChecks: total,
169
+ alreadyAlive,
170
+ respawned,
171
+ staleCleaned,
172
+ failed,
173
+ uptimeRatio: total === 0 ? 1 : alreadyAlive / total,
174
+ };
175
+ }
176
+ export function formatBreathLine(d, o) {
177
+ const tag = o.action === "already_alive" ? "🫁" : o.action === "respawned" ? "🌱" : o.action === "failed" ? "💀" : "🧹";
178
+ return `${tag} BREATH · ${o.action} · ${o.ms}ms · ${d.reason}`;
179
+ }
180
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/autonomic_breath/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=catalog_parity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog_parity.test.d.ts","sourceRoot":"","sources":["../../src/catalog_parity/catalog_parity.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { computeParity, extractMcpFamilies, verifyParityReport, formatParityLine } from "./index.js";
3
+ const SECRET = "catalog-parity-test-secret-997744";
4
+ describe("v2.19.22 CATALOG PARITY · G2 quick-win", () => {
5
+ it("extractMcpFamilies parses mneme.<family>.<action> -> family set", () => {
6
+ const fams = extractMcpFamilies([
7
+ "mneme.arena.judge", "mneme.arena.leaderboard",
8
+ "mneme.badge.issue",
9
+ "not_mneme.foo.bar",
10
+ "mneme.too.many.parts",
11
+ ]);
12
+ expect(fams.has("arena")).toBe(true);
13
+ expect(fams.has("badge")).toBe(true);
14
+ expect(fams.has("foo")).toBe(false);
15
+ expect(fams.has("too")).toBe(false);
16
+ expect(fams.size).toBe(2);
17
+ });
18
+ it("classifies into shared / mcp-only / legacy-only correctly", () => {
19
+ const r = computeParity({
20
+ cliTopLevelCommands: ["ghost", "status", "ask", "premortem"],
21
+ mcpToolNames: [
22
+ "mneme.ghost.distill", // shared (ghost both)
23
+ "mneme.arena.judge", // mcp-only
24
+ "mneme.badge.issue", // mcp-only
25
+ "mneme.status.report", // shared
26
+ ],
27
+ secret: SECRET,
28
+ });
29
+ expect(r.sharedFamilies).toEqual(["ghost", "status"]);
30
+ expect(r.mcpOnlyFamilies).toEqual(["arena", "badge"]);
31
+ expect(r.legacyOnlyCommands).toEqual(["ask", "premortem"]);
32
+ expect(r.totalMcpFamilies).toBe(4);
33
+ });
34
+ it("parityRatio = shared / (shared + mcp-only)", () => {
35
+ const r = computeParity({
36
+ cliTopLevelCommands: ["a", "b", "c"],
37
+ mcpToolNames: ["mneme.a.x", "mneme.b.x", "mneme.d.x", "mneme.e.x"],
38
+ secret: SECRET,
39
+ });
40
+ expect(r.sharedFamilies).toEqual(["a", "b"]);
41
+ expect(r.mcpOnlyFamilies).toEqual(["d", "e"]);
42
+ expect(r.parityRatio).toBe(2 / 4);
43
+ });
44
+ it("100% parity when every MCP family has a CLI counterpart", () => {
45
+ const r = computeParity({
46
+ cliTopLevelCommands: ["arena", "badge"],
47
+ mcpToolNames: ["mneme.arena.x", "mneme.badge.y"],
48
+ secret: SECRET,
49
+ });
50
+ expect(r.parityRatio).toBe(1.0);
51
+ expect(r.mcpOnlyFamilies).toEqual([]);
52
+ });
53
+ it("HMAC signature verifies on untampered report; fails on tamper", () => {
54
+ const r = computeParity({
55
+ cliTopLevelCommands: ["x"],
56
+ mcpToolNames: ["mneme.x.y"],
57
+ secret: SECRET,
58
+ });
59
+ expect(verifyParityReport(r, SECRET)).toBe(true);
60
+ const tampered = { ...r, totalMcpTools: 9999 };
61
+ expect(verifyParityReport(tampered, SECRET)).toBe(false);
62
+ });
63
+ it("formatParityLine renders single-line digest", () => {
64
+ const r = computeParity({
65
+ cliTopLevelCommands: ["a", "b"],
66
+ mcpToolNames: ["mneme.a.x", "mneme.c.x"],
67
+ secret: SECRET,
68
+ });
69
+ const line = formatParityLine(r);
70
+ expect(line).toContain("PARITY");
71
+ expect(line).toContain("50.0%");
72
+ });
73
+ it("MEASURED 100% determinism: same input -> same sig (50 trials)", () => {
74
+ const input = {
75
+ cliTopLevelCommands: ["arena", "ghost", "status"],
76
+ mcpToolNames: ["mneme.arena.judge", "mneme.ghost.distill", "mneme.badge.issue"],
77
+ secret: SECRET,
78
+ };
79
+ const first = computeParity(input).sig;
80
+ let allEqual = true;
81
+ for (let i = 0; i < 50; i++) {
82
+ if (computeParity(input).sig !== first) {
83
+ allEqual = false;
84
+ break;
85
+ }
86
+ }
87
+ expect(allEqual).toBe(true);
88
+ });
89
+ it("ordering of input lists does NOT change report (canonicalised internally)", () => {
90
+ const a = computeParity({
91
+ cliTopLevelCommands: ["c", "a", "b"],
92
+ mcpToolNames: ["mneme.b.x", "mneme.a.y"],
93
+ secret: SECRET,
94
+ });
95
+ const b = computeParity({
96
+ cliTopLevelCommands: ["a", "b", "c"],
97
+ mcpToolNames: ["mneme.a.y", "mneme.b.x"],
98
+ secret: SECRET,
99
+ });
100
+ expect(a.sig).toBe(b.sig);
101
+ expect(a.parityRatio).toBe(b.parityRatio);
102
+ });
103
+ });
104
+ //# sourceMappingURL=catalog_parity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog_parity.test.js","sourceRoot":"","sources":["../../src/catalog_parity/catalog_parity.test.ts"],"names":[],"mappings":"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"}