@mnemoai/core 1.1.0 → 1.1.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.
Files changed (220) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +7 -0
  4. package/dist/cli.js.map +7 -0
  5. package/dist/index.d.ts +128 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/{index.ts → dist/index.js} +526 -1333
  8. package/dist/index.js.map +7 -0
  9. package/dist/src/access-tracker.d.ts +97 -0
  10. package/dist/src/access-tracker.d.ts.map +1 -0
  11. package/dist/src/access-tracker.js +184 -0
  12. package/dist/src/access-tracker.js.map +7 -0
  13. package/dist/src/adapters/chroma.d.ts +31 -0
  14. package/dist/src/adapters/chroma.d.ts.map +1 -0
  15. package/{src/adapters/chroma.ts → dist/src/adapters/chroma.js} +45 -107
  16. package/dist/src/adapters/chroma.js.map +7 -0
  17. package/dist/src/adapters/lancedb.d.ts +29 -0
  18. package/dist/src/adapters/lancedb.d.ts.map +1 -0
  19. package/{src/adapters/lancedb.ts → dist/src/adapters/lancedb.js} +41 -109
  20. package/dist/src/adapters/lancedb.js.map +7 -0
  21. package/dist/src/adapters/pgvector.d.ts +33 -0
  22. package/dist/src/adapters/pgvector.d.ts.map +1 -0
  23. package/{src/adapters/pgvector.ts → dist/src/adapters/pgvector.js} +42 -104
  24. package/dist/src/adapters/pgvector.js.map +7 -0
  25. package/dist/src/adapters/qdrant.d.ts +34 -0
  26. package/dist/src/adapters/qdrant.d.ts.map +1 -0
  27. package/dist/src/adapters/qdrant.js +132 -0
  28. package/dist/src/adapters/qdrant.js.map +7 -0
  29. package/dist/src/adaptive-retrieval.d.ts +14 -0
  30. package/dist/src/adaptive-retrieval.d.ts.map +1 -0
  31. package/dist/src/adaptive-retrieval.js +52 -0
  32. package/dist/src/adaptive-retrieval.js.map +7 -0
  33. package/dist/src/audit-log.d.ts +56 -0
  34. package/dist/src/audit-log.d.ts.map +1 -0
  35. package/dist/src/audit-log.js +139 -0
  36. package/dist/src/audit-log.js.map +7 -0
  37. package/dist/src/chunker.d.ts +45 -0
  38. package/dist/src/chunker.d.ts.map +1 -0
  39. package/dist/src/chunker.js +157 -0
  40. package/dist/src/chunker.js.map +7 -0
  41. package/dist/src/config.d.ts +70 -0
  42. package/dist/src/config.d.ts.map +1 -0
  43. package/dist/src/config.js +142 -0
  44. package/dist/src/config.js.map +7 -0
  45. package/dist/src/decay-engine.d.ts +73 -0
  46. package/dist/src/decay-engine.d.ts.map +1 -0
  47. package/dist/src/decay-engine.js +119 -0
  48. package/dist/src/decay-engine.js.map +7 -0
  49. package/dist/src/embedder.d.ts +94 -0
  50. package/dist/src/embedder.d.ts.map +1 -0
  51. package/{src/embedder.ts → dist/src/embedder.js} +119 -317
  52. package/dist/src/embedder.js.map +7 -0
  53. package/dist/src/extraction-prompts.d.ts +12 -0
  54. package/dist/src/extraction-prompts.d.ts.map +1 -0
  55. package/dist/src/extraction-prompts.js +311 -0
  56. package/dist/src/extraction-prompts.js.map +7 -0
  57. package/dist/src/license.d.ts +29 -0
  58. package/dist/src/license.d.ts.map +1 -0
  59. package/{src/license.ts → dist/src/license.js} +42 -113
  60. package/dist/src/license.js.map +7 -0
  61. package/dist/src/llm-client.d.ts +23 -0
  62. package/dist/src/llm-client.d.ts.map +1 -0
  63. package/{src/llm-client.ts → dist/src/llm-client.js} +22 -55
  64. package/dist/src/llm-client.js.map +7 -0
  65. package/dist/src/logger.d.ts +33 -0
  66. package/dist/src/logger.d.ts.map +1 -0
  67. package/dist/src/logger.js +35 -0
  68. package/dist/src/logger.js.map +7 -0
  69. package/dist/src/mcp-server.d.ts +16 -0
  70. package/dist/src/mcp-server.d.ts.map +1 -0
  71. package/{src/mcp-server.ts → dist/src/mcp-server.js} +81 -181
  72. package/dist/src/mcp-server.js.map +7 -0
  73. package/dist/src/memory-categories.d.ts +40 -0
  74. package/dist/src/memory-categories.d.ts.map +1 -0
  75. package/dist/src/memory-categories.js +33 -0
  76. package/dist/src/memory-categories.js.map +7 -0
  77. package/dist/src/memory-upgrader.d.ts +71 -0
  78. package/dist/src/memory-upgrader.d.ts.map +1 -0
  79. package/dist/src/memory-upgrader.js +238 -0
  80. package/dist/src/memory-upgrader.js.map +7 -0
  81. package/dist/src/migrate.d.ts +47 -0
  82. package/dist/src/migrate.d.ts.map +1 -0
  83. package/{src/migrate.ts → dist/src/migrate.js} +57 -165
  84. package/dist/src/migrate.js.map +7 -0
  85. package/dist/src/mnemo.d.ts +67 -0
  86. package/dist/src/mnemo.d.ts.map +1 -0
  87. package/dist/src/mnemo.js +66 -0
  88. package/dist/src/mnemo.js.map +7 -0
  89. package/dist/src/noise-filter.d.ts +23 -0
  90. package/dist/src/noise-filter.d.ts.map +1 -0
  91. package/dist/src/noise-filter.js +62 -0
  92. package/dist/src/noise-filter.js.map +7 -0
  93. package/dist/src/noise-prototypes.d.ts +40 -0
  94. package/dist/src/noise-prototypes.d.ts.map +1 -0
  95. package/dist/src/noise-prototypes.js +116 -0
  96. package/dist/src/noise-prototypes.js.map +7 -0
  97. package/dist/src/observability.d.ts +16 -0
  98. package/dist/src/observability.d.ts.map +1 -0
  99. package/dist/src/observability.js +53 -0
  100. package/dist/src/observability.js.map +7 -0
  101. package/dist/src/query-tracker.d.ts +27 -0
  102. package/dist/src/query-tracker.d.ts.map +1 -0
  103. package/dist/src/query-tracker.js +32 -0
  104. package/dist/src/query-tracker.js.map +7 -0
  105. package/dist/src/reflection-event-store.d.ts +44 -0
  106. package/dist/src/reflection-event-store.d.ts.map +1 -0
  107. package/dist/src/reflection-event-store.js +50 -0
  108. package/dist/src/reflection-event-store.js.map +7 -0
  109. package/dist/src/reflection-item-store.d.ts +58 -0
  110. package/dist/src/reflection-item-store.d.ts.map +1 -0
  111. package/dist/src/reflection-item-store.js +69 -0
  112. package/dist/src/reflection-item-store.js.map +7 -0
  113. package/dist/src/reflection-mapped-metadata.d.ts +47 -0
  114. package/dist/src/reflection-mapped-metadata.d.ts.map +1 -0
  115. package/dist/src/reflection-mapped-metadata.js +40 -0
  116. package/dist/src/reflection-mapped-metadata.js.map +7 -0
  117. package/dist/src/reflection-metadata.d.ts +11 -0
  118. package/dist/src/reflection-metadata.d.ts.map +1 -0
  119. package/dist/src/reflection-metadata.js +24 -0
  120. package/dist/src/reflection-metadata.js.map +7 -0
  121. package/dist/src/reflection-ranking.d.ts +13 -0
  122. package/dist/src/reflection-ranking.d.ts.map +1 -0
  123. package/{src/reflection-ranking.ts → dist/src/reflection-ranking.js} +12 -21
  124. package/dist/src/reflection-ranking.js.map +7 -0
  125. package/dist/src/reflection-retry.d.ts +30 -0
  126. package/dist/src/reflection-retry.d.ts.map +1 -0
  127. package/{src/reflection-retry.ts → dist/src/reflection-retry.js} +24 -64
  128. package/dist/src/reflection-retry.js.map +7 -0
  129. package/dist/src/reflection-slices.d.ts +42 -0
  130. package/dist/src/reflection-slices.d.ts.map +1 -0
  131. package/{src/reflection-slices.ts → dist/src/reflection-slices.js} +60 -136
  132. package/dist/src/reflection-slices.js.map +7 -0
  133. package/dist/src/reflection-store.d.ts +85 -0
  134. package/dist/src/reflection-store.d.ts.map +1 -0
  135. package/dist/src/reflection-store.js +407 -0
  136. package/dist/src/reflection-store.js.map +7 -0
  137. package/dist/src/resonance-state.d.ts +19 -0
  138. package/dist/src/resonance-state.d.ts.map +1 -0
  139. package/{src/resonance-state.ts → dist/src/resonance-state.js} +13 -42
  140. package/dist/src/resonance-state.js.map +7 -0
  141. package/dist/src/retriever.d.ts +228 -0
  142. package/dist/src/retriever.d.ts.map +1 -0
  143. package/dist/src/retriever.js +1006 -0
  144. package/dist/src/retriever.js.map +7 -0
  145. package/dist/src/scopes.d.ts +58 -0
  146. package/dist/src/scopes.d.ts.map +1 -0
  147. package/dist/src/scopes.js +252 -0
  148. package/dist/src/scopes.js.map +7 -0
  149. package/dist/src/self-improvement-files.d.ts +20 -0
  150. package/dist/src/self-improvement-files.d.ts.map +1 -0
  151. package/{src/self-improvement-files.ts → dist/src/self-improvement-files.js} +24 -49
  152. package/dist/src/self-improvement-files.js.map +7 -0
  153. package/dist/src/semantic-gate.d.ts +24 -0
  154. package/dist/src/semantic-gate.d.ts.map +1 -0
  155. package/dist/src/semantic-gate.js +86 -0
  156. package/dist/src/semantic-gate.js.map +7 -0
  157. package/dist/src/session-recovery.d.ts +9 -0
  158. package/dist/src/session-recovery.d.ts.map +1 -0
  159. package/{src/session-recovery.ts → dist/src/session-recovery.js} +40 -57
  160. package/dist/src/session-recovery.js.map +7 -0
  161. package/dist/src/smart-extractor.d.ts +107 -0
  162. package/dist/src/smart-extractor.d.ts.map +1 -0
  163. package/{src/smart-extractor.ts → dist/src/smart-extractor.js} +130 -383
  164. package/dist/src/smart-extractor.js.map +7 -0
  165. package/dist/src/smart-metadata.d.ts +103 -0
  166. package/dist/src/smart-metadata.d.ts.map +1 -0
  167. package/dist/src/smart-metadata.js +361 -0
  168. package/dist/src/smart-metadata.js.map +7 -0
  169. package/dist/src/storage-adapter.d.ts +102 -0
  170. package/dist/src/storage-adapter.d.ts.map +1 -0
  171. package/dist/src/storage-adapter.js +22 -0
  172. package/dist/src/storage-adapter.js.map +7 -0
  173. package/dist/src/store.d.ts +108 -0
  174. package/dist/src/store.d.ts.map +1 -0
  175. package/dist/src/store.js +939 -0
  176. package/dist/src/store.js.map +7 -0
  177. package/dist/src/tier-manager.d.ts +57 -0
  178. package/dist/src/tier-manager.d.ts.map +1 -0
  179. package/dist/src/tier-manager.js +80 -0
  180. package/dist/src/tier-manager.js.map +7 -0
  181. package/dist/src/tools.d.ts +43 -0
  182. package/dist/src/tools.d.ts.map +1 -0
  183. package/dist/src/tools.js +1075 -0
  184. package/dist/src/tools.js.map +7 -0
  185. package/dist/src/wal-recovery.d.ts +30 -0
  186. package/dist/src/wal-recovery.d.ts.map +1 -0
  187. package/{src/wal-recovery.ts → dist/src/wal-recovery.js} +26 -79
  188. package/dist/src/wal-recovery.js.map +7 -0
  189. package/package.json +21 -2
  190. package/openclaw.plugin.json +0 -815
  191. package/src/access-tracker.ts +0 -341
  192. package/src/adapters/README.md +0 -78
  193. package/src/adapters/qdrant.ts +0 -191
  194. package/src/adaptive-retrieval.ts +0 -90
  195. package/src/audit-log.ts +0 -238
  196. package/src/chunker.ts +0 -254
  197. package/src/config.ts +0 -271
  198. package/src/decay-engine.ts +0 -238
  199. package/src/extraction-prompts.ts +0 -339
  200. package/src/memory-categories.ts +0 -71
  201. package/src/memory-upgrader.ts +0 -388
  202. package/src/mnemo.ts +0 -142
  203. package/src/noise-filter.ts +0 -97
  204. package/src/noise-prototypes.ts +0 -164
  205. package/src/observability.ts +0 -81
  206. package/src/query-tracker.ts +0 -57
  207. package/src/reflection-event-store.ts +0 -98
  208. package/src/reflection-item-store.ts +0 -112
  209. package/src/reflection-mapped-metadata.ts +0 -84
  210. package/src/reflection-metadata.ts +0 -23
  211. package/src/reflection-store.ts +0 -602
  212. package/src/retriever.ts +0 -1510
  213. package/src/scopes.ts +0 -375
  214. package/src/semantic-gate.ts +0 -121
  215. package/src/smart-metadata.ts +0 -561
  216. package/src/storage-adapter.ts +0 -153
  217. package/src/store.ts +0 -1330
  218. package/src/tier-manager.ts +0 -189
  219. package/src/tools.ts +0 -1292
  220. package/test/core.test.mjs +0 -301
@@ -1,301 +0,0 @@
1
- /**
2
- * Mnemo Core — Test Suite
3
- * Using Node.js built-in test runner (node --test)
4
- * No external test framework needed.
5
- */
6
-
7
- import { describe, it } from "node:test";
8
- import assert from "node:assert/strict";
9
- import { createHash, generateKeyPairSync, sign, verify, createPublicKey, createPrivateKey } from "node:crypto";
10
- import { hostname, arch, cpus, platform } from "node:os";
11
-
12
- // ============================================================================
13
- // Group 1: SQL Injection Prevention
14
- // ============================================================================
15
-
16
- describe("escapeSqlLiteral (allowlist sanitizer)", () => {
17
- // Re-implement the function here for testing (same logic as store.ts)
18
- function escapeSqlLiteral(value) {
19
- if (typeof value !== "string") return "";
20
- return value.replace(/[^a-zA-Z0-9\-_.:@ \u4e00-\u9fff\u3400-\u4dbf]/g, "");
21
- }
22
-
23
- it("passes normal ID through", () => {
24
- assert.equal(escapeSqlLiteral("abc-123-def"), "abc-123-def");
25
- });
26
-
27
- it("passes UUID through", () => {
28
- assert.equal(
29
- escapeSqlLiteral("550e8400-e29b-41d4-a716-446655440000"),
30
- "550e8400-e29b-41d4-a716-446655440000"
31
- );
32
- });
33
-
34
- it("passes Chinese text through", () => {
35
- assert.equal(escapeSqlLiteral("用户偏好"), "用户偏好");
36
- });
37
-
38
- it("strips single quotes (SQL injection)", () => {
39
- assert.equal(escapeSqlLiteral("'; DROP TABLE memories; --"), " DROP TABLE memories --");
40
- });
41
-
42
- it("strips parentheses", () => {
43
- assert.equal(escapeSqlLiteral("id = '1' OR (1=1)"), "id 1 OR 11");
44
- });
45
-
46
- it("strips backticks", () => {
47
- assert.equal(escapeSqlLiteral("`memories`"), "memories");
48
- });
49
-
50
- it("strips semicolons", () => {
51
- assert.equal(escapeSqlLiteral("abc; DELETE FROM x"), "abc DELETE FROM x");
52
- });
53
-
54
- it("handles empty string", () => {
55
- assert.equal(escapeSqlLiteral(""), "");
56
- });
57
-
58
- it("handles non-string input", () => {
59
- assert.equal(escapeSqlLiteral(null), "");
60
- assert.equal(escapeSqlLiteral(undefined), "");
61
- assert.equal(escapeSqlLiteral(123), "");
62
- });
63
-
64
- it("preserves scope format", () => {
65
- assert.equal(escapeSqlLiteral("agent:bot3"), "agent:bot3");
66
- assert.equal(escapeSqlLiteral("global"), "global");
67
- });
68
-
69
- it("preserves email-like strings", () => {
70
- assert.equal(escapeSqlLiteral("user@example.com"), "user@example.com");
71
- });
72
- });
73
-
74
- // ============================================================================
75
- // Group 2: License Key System
76
- // ============================================================================
77
-
78
- describe("License Key (Ed25519)", () => {
79
- const { publicKey, privateKey } = generateKeyPairSync("ed25519");
80
- const pubDer = publicKey.export({ type: "spki", format: "der" });
81
- const privDer = privateKey.export({ type: "pkcs8", format: "der" });
82
-
83
- function signPayload(payload) {
84
- const buf = Buffer.from(JSON.stringify(payload));
85
- const sig = sign(null, buf, privateKey);
86
- return buf.toString("base64") + "." + sig.toString("base64");
87
- }
88
-
89
- function verifyKey(key) {
90
- const dot = key.indexOf(".");
91
- if (dot < 1) return null;
92
- try {
93
- const payloadBuf = Buffer.from(key.slice(0, dot), "base64");
94
- const sigBuf = Buffer.from(key.slice(dot + 1), "base64");
95
- const valid = verify(null, payloadBuf, publicKey, sigBuf);
96
- if (!valid) return null;
97
- return JSON.parse(payloadBuf.toString());
98
- } catch { return null; }
99
- }
100
-
101
- it("valid key verifies correctly", () => {
102
- const key = signPayload({ licensee: "Test", plan: "indie" });
103
- const payload = verifyKey(key);
104
- assert.notEqual(payload, null);
105
- assert.equal(payload.licensee, "Test");
106
- });
107
-
108
- it("tampered payload fails", () => {
109
- const key = signPayload({ licensee: "Test" });
110
- const parts = key.split(".");
111
- const original = JSON.parse(Buffer.from(parts[0], "base64").toString());
112
- original.licensee = "Hacked";
113
- const tampered = Buffer.from(JSON.stringify(original)).toString("base64") + "." + parts[1];
114
- assert.equal(verifyKey(tampered), null);
115
- });
116
-
117
- it("tampered signature fails", () => {
118
- const key = signPayload({ licensee: "Test" });
119
- const parts = key.split(".");
120
- const sigBuf = Buffer.from(parts[1], "base64");
121
- sigBuf[0] ^= 0xff;
122
- const tampered = parts[0] + "." + sigBuf.toString("base64");
123
- assert.equal(verifyKey(tampered), null);
124
- });
125
-
126
- it("empty string fails", () => {
127
- assert.equal(verifyKey(""), null);
128
- });
129
-
130
- it("wrong key pair fails", () => {
131
- const { privateKey: otherPriv } = generateKeyPairSync("ed25519");
132
- const buf = Buffer.from(JSON.stringify({ licensee: "Evil" }));
133
- const sig = sign(null, buf, otherPriv);
134
- const key = buf.toString("base64") + "." + sig.toString("base64");
135
- assert.equal(verifyKey(key), null);
136
- });
137
-
138
- it("expired key detected", () => {
139
- const payload = { licensee: "Test", expires: "2020-01-01" };
140
- const key = signPayload(payload);
141
- const decoded = verifyKey(key);
142
- assert.notEqual(decoded, null);
143
- assert.ok(new Date(decoded.expires).getTime() < Date.now());
144
- });
145
- });
146
-
147
- // ============================================================================
148
- // Group 3: Machine Fingerprint
149
- // ============================================================================
150
-
151
- describe("Machine Fingerprint", () => {
152
- function getMachineFingerprint() {
153
- const cpu = cpus()[0]?.model || "unknown";
154
- const raw = `${hostname()}:${arch()}:${cpu}:${platform()}`;
155
- return createHash("sha256").update(raw).digest("hex");
156
- }
157
-
158
- it("produces SHA-256 hex (64 chars)", () => {
159
- const fp = getMachineFingerprint();
160
- assert.match(fp, /^[a-f0-9]{64}$/);
161
- });
162
-
163
- it("is deterministic", () => {
164
- assert.equal(getMachineFingerprint(), getMachineFingerprint());
165
- });
166
- });
167
-
168
- // ============================================================================
169
- // Group 4: Storage Adapter Interface
170
- // ============================================================================
171
-
172
- describe("StorageAdapter Registry", async () => {
173
- // Dynamic import to test the module
174
- let registerAdapter, createAdapter, listAdapters;
175
- try {
176
- const mod = await import("../src/storage-adapter.js");
177
- registerAdapter = mod.registerAdapter;
178
- createAdapter = mod.createAdapter;
179
- listAdapters = mod.listAdapters;
180
- } catch {
181
- // Skip if module can't be loaded (TS not compiled)
182
- console.log(" ⚠ Skipping adapter tests (TS modules not compiled)");
183
- return;
184
- }
185
-
186
- it("registerAdapter + createAdapter round-trip", () => {
187
- registerAdapter("test-backend", () => ({ name: "test-backend" }));
188
- const adapter = createAdapter("test-backend");
189
- assert.equal(adapter.name, "test-backend");
190
- });
191
-
192
- it("listAdapters includes registered backends", () => {
193
- const list = listAdapters();
194
- assert.ok(list.includes("test-backend"));
195
- });
196
-
197
- it("createAdapter throws for unknown backend", () => {
198
- assert.throws(() => createAdapter("nonexistent"), /not found/);
199
- });
200
- });
201
-
202
- // ============================================================================
203
- // Group 5: Audit Log
204
- // ============================================================================
205
-
206
- describe("Audit Log Entry Format", () => {
207
- it("audit entry has required fields", () => {
208
- const entry = {
209
- timestamp: new Date().toISOString(),
210
- action: "create",
211
- actor: "agent:default",
212
- memoryIds: ["mem_001"],
213
- scope: "global",
214
- reason: "auto-capture",
215
- };
216
-
217
- assert.ok(entry.timestamp);
218
- assert.ok(["create", "update", "delete", "expire", "recall"].includes(entry.action));
219
- assert.ok(Array.isArray(entry.memoryIds));
220
- assert.ok(entry.actor);
221
- });
222
-
223
- it("audit entry serializes to valid JSON", () => {
224
- const entry = {
225
- timestamp: "2026-03-23T10:00:00Z",
226
- action: "update",
227
- actor: "system",
228
- memoryIds: ["mem_001", "mem_002"],
229
- reason: "contradiction",
230
- details: JSON.stringify({ old: "age 30", new: "age 31" }),
231
- };
232
- const json = JSON.stringify(entry);
233
- const parsed = JSON.parse(json);
234
- assert.deepEqual(parsed, entry);
235
- });
236
- });
237
-
238
- // ============================================================================
239
- // Group 6: Weibull Decay Model
240
- // ============================================================================
241
-
242
- describe("Weibull Decay", () => {
243
- function weibull(t, beta, halflife) {
244
- const lam = halflife / Math.pow(Math.LN2, 1 / beta);
245
- return Math.exp(-Math.pow(t / lam, beta));
246
- }
247
-
248
- it("score is 1.0 at t=0", () => {
249
- assert.equal(weibull(0, 1.0, 30), 1.0);
250
- });
251
-
252
- it("score is ~0.5 at t=halflife for beta=1.0", () => {
253
- const score = weibull(30, 1.0, 30);
254
- assert.ok(Math.abs(score - 0.5) < 0.01);
255
- });
256
-
257
- it("Core (beta=0.8) retains more than Working after 2x halflife", () => {
258
- const core = weibull(60, 0.8, 30);
259
- const working = weibull(60, 1.0, 30);
260
- assert.ok(core > working, `Core ${core} should be > Working ${working} at t=2*halflife`);
261
- });
262
-
263
- it("Peripheral (beta=1.3) retains less than Working after 2x halflife", () => {
264
- const peripheral = weibull(60, 1.3, 30);
265
- const working = weibull(60, 1.0, 30);
266
- assert.ok(peripheral < working, `Peripheral ${peripheral} should be < Working ${working} at t=2*halflife`);
267
- });
268
-
269
- it("score approaches 0 for very old memories", () => {
270
- const score = weibull(365, 1.0, 30);
271
- assert.ok(score < 0.001);
272
- });
273
-
274
- it("Core memories retain >50% at 90 days", () => {
275
- const score = weibull(90, 0.8, 90);
276
- assert.ok(score > 0.45);
277
- });
278
- });
279
-
280
- // ============================================================================
281
- // Group 7: Config Path Resolution
282
- // ============================================================================
283
-
284
- describe("Config Path Defaults", () => {
285
- it("MNEMO_DB_PATH env overrides default", () => {
286
- const original = process.env.MNEMO_DB_PATH;
287
- process.env.MNEMO_DB_PATH = "/custom/path";
288
- // The function checks env first
289
- assert.equal(process.env.MNEMO_DB_PATH, "/custom/path");
290
- if (original) process.env.MNEMO_DB_PATH = original;
291
- else delete process.env.MNEMO_DB_PATH;
292
- });
293
-
294
- it("MNEMO_CONFIG env is respected", () => {
295
- const original = process.env.MNEMO_CONFIG;
296
- process.env.MNEMO_CONFIG = "/custom/config.json";
297
- assert.equal(process.env.MNEMO_CONFIG, "/custom/config.json");
298
- if (original) process.env.MNEMO_CONFIG = original;
299
- else delete process.env.MNEMO_CONFIG;
300
- });
301
- });