yakmesh 2.8.2 → 3.0.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 (232) hide show
  1. package/CHANGELOG.md +637 -0
  2. package/CONTRIBUTING.md +42 -0
  3. package/Caddyfile +77 -0
  4. package/README.md +119 -29
  5. package/adapters/adapter-mlv-bible/README.md +124 -0
  6. package/adapters/adapter-mlv-bible/index.js +400 -0
  7. package/adapters/chat-mod-adapter.js +532 -0
  8. package/adapters/content-adapter.js +273 -0
  9. package/content/api.js +50 -41
  10. package/content/index.js +2 -2
  11. package/content/store.js +355 -173
  12. package/dashboard/index.html +19 -3
  13. package/database/replication.js +117 -37
  14. package/docs/CRYPTO-AGILITY.md +204 -0
  15. package/docs/MTLS-RESEARCH.md +367 -0
  16. package/docs/NAMCHE-SPEC.md +681 -0
  17. package/docs/PEERQUANTA-YAKMESH-INTEGRATION.md +407 -0
  18. package/docs/PRECISION-DISCLOSURE.md +96 -0
  19. package/docs/README.md +76 -0
  20. package/docs/ROADMAP-2.4.0.md +447 -0
  21. package/docs/ROADMAP-2.5.0.md +244 -0
  22. package/docs/SECURITY-AUDIT-REPORT.md +306 -0
  23. package/docs/SST-INTEGRATION.md +712 -0
  24. package/docs/STEADYWATCH-IMPLEMENTATION.md +303 -0
  25. package/docs/TERNARY-AUDIT-REPORT.md +247 -0
  26. package/docs/TME-FAQ.md +221 -0
  27. package/docs/WHITEPAPER.md +623 -0
  28. package/docs/adapters.html +1001 -0
  29. package/docs/advanced-systems.html +1045 -0
  30. package/docs/annex.html +1046 -0
  31. package/docs/api.html +970 -0
  32. package/docs/business/response-templates.md +160 -0
  33. package/docs/c2c.html +1225 -0
  34. package/docs/cli.html +1332 -0
  35. package/docs/configuration.html +1248 -0
  36. package/docs/darshan.html +1085 -0
  37. package/docs/dharma.html +966 -0
  38. package/docs/docs-bundle.html +1075 -0
  39. package/docs/docs.css +3120 -0
  40. package/docs/docs.js +556 -0
  41. package/docs/doko.html +969 -0
  42. package/docs/geo-proof.html +858 -0
  43. package/docs/getting-started.html +840 -0
  44. package/docs/gumba-tutorial.html +1144 -0
  45. package/docs/gumba.html +1098 -0
  46. package/docs/index.html +914 -0
  47. package/docs/jhilke.html +1312 -0
  48. package/docs/karma.html +1100 -0
  49. package/docs/katha.html +1037 -0
  50. package/docs/lama.html +978 -0
  51. package/docs/mandala.html +1067 -0
  52. package/docs/mani.html +964 -0
  53. package/docs/mantra.html +967 -0
  54. package/docs/mesh.html +1409 -0
  55. package/docs/nakpak.html +869 -0
  56. package/docs/namche.html +928 -0
  57. package/docs/nav-order.json +53 -0
  58. package/docs/prahari.html +1043 -0
  59. package/docs/prism-bash.min.js +1 -0
  60. package/docs/prism-javascript.min.js +1 -0
  61. package/docs/prism-json.min.js +1 -0
  62. package/docs/prism-tomorrow.min.css +1 -0
  63. package/docs/prism.min.js +1 -0
  64. package/docs/privacy.html +699 -0
  65. package/docs/quick-reference.html +1181 -0
  66. package/docs/sakshi.html +1402 -0
  67. package/docs/sandboxing.md +386 -0
  68. package/docs/seva.html +911 -0
  69. package/docs/sherpa.html +871 -0
  70. package/docs/studio.html +860 -0
  71. package/docs/stupa.html +995 -0
  72. package/docs/tailwind.min.css +2 -0
  73. package/docs/tattva.html +1332 -0
  74. package/docs/terms.html +686 -0
  75. package/docs/time-server-deployment.md +166 -0
  76. package/docs/time-sources.html +1392 -0
  77. package/docs/tivra.html +1127 -0
  78. package/docs/trademark-policy.html +686 -0
  79. package/docs/tribhuj.html +1183 -0
  80. package/docs/trust-security.html +1029 -0
  81. package/docs/tutorials/backup-recovery.html +654 -0
  82. package/docs/tutorials/dashboard.html +604 -0
  83. package/docs/tutorials/domain-setup.html +605 -0
  84. package/docs/tutorials/host-website.html +456 -0
  85. package/docs/tutorials/mesh-network.html +505 -0
  86. package/docs/tutorials/mobile-access.html +445 -0
  87. package/docs/tutorials/privacy.html +467 -0
  88. package/docs/tutorials/raspberry-pi.html +600 -0
  89. package/docs/tutorials/security-basics.html +539 -0
  90. package/docs/tutorials/share-files.html +431 -0
  91. package/docs/tutorials/troubleshooting.html +637 -0
  92. package/docs/tutorials/trust-karma.html +419 -0
  93. package/docs/tutorials/yak-protocol.html +456 -0
  94. package/docs/tutorials.html +1034 -0
  95. package/docs/vani.html +1270 -0
  96. package/docs/webserver.html +809 -0
  97. package/docs/yak-protocol.html +940 -0
  98. package/docs/yak-timeserver-design.md +475 -0
  99. package/docs/yakapp.html +1015 -0
  100. package/docs/ypc27.html +1069 -0
  101. package/docs/yurt.html +1344 -0
  102. package/embedded-docs/bundle.js +334 -74
  103. package/gossip/protocol.js +247 -27
  104. package/identity/key-resolver.js +262 -0
  105. package/identity/machine-seed.js +632 -0
  106. package/identity/node-key.js +669 -368
  107. package/identity/tribhuj-ratchet.js +506 -0
  108. package/knowledge-base.js +37 -8
  109. package/launcher/yakmesh.bat +62 -0
  110. package/launcher/yakmesh.sh +70 -0
  111. package/mesh/annex.js +462 -108
  112. package/mesh/beacon-broadcast.js +113 -1
  113. package/mesh/darshan.js +1718 -0
  114. package/mesh/gumba.js +1567 -0
  115. package/mesh/jhilke.js +651 -0
  116. package/mesh/katha.js +1012 -0
  117. package/mesh/nakpak-routing.js +8 -5
  118. package/mesh/network.js +724 -34
  119. package/mesh/pulse-sync.js +4 -1
  120. package/mesh/rate-limiter.js +127 -15
  121. package/mesh/seva.js +526 -0
  122. package/mesh/sherpa-discovery.js +89 -8
  123. package/mesh/sybil-defense.js +19 -5
  124. package/mesh/temporal-encoder.js +4 -3
  125. package/mesh/vani.js +1364 -0
  126. package/mesh/yurt.js +1340 -0
  127. package/models/entropy-sentinel.onnx +0 -0
  128. package/models/karma-trust.onnx +0 -0
  129. package/models/manifest.json +43 -0
  130. package/models/sakshi-anomaly.onnx +0 -0
  131. package/oracle/code-proof-protocol.js +7 -6
  132. package/oracle/codebase-lock.js +257 -28
  133. package/oracle/index.js +74 -15
  134. package/oracle/ma902-snmp.js +678 -0
  135. package/oracle/module-sealer.js +5 -3
  136. package/oracle/network-identity.js +16 -0
  137. package/oracle/packet-checksum.js +201 -0
  138. package/oracle/sst.js +579 -0
  139. package/oracle/ternary-144t.js +714 -0
  140. package/oracle/ternary-ml.js +481 -0
  141. package/oracle/time-api.js +239 -0
  142. package/oracle/time-source.js +137 -47
  143. package/oracle/validation-oracle-hardened.js +1111 -1071
  144. package/oracle/validation-oracle.js +4 -2
  145. package/oracle/ypc27.js +211 -0
  146. package/package.json +20 -3
  147. package/protocol/yak-handler.js +35 -9
  148. package/protocol/yak-protocol.js +28 -13
  149. package/reference/cpp/yakmesh_mceliece_shard.cpp +168 -0
  150. package/reference/cpp/yakmesh_ypc27.cpp +179 -0
  151. package/sbom.json +87 -0
  152. package/scripts/security-audit.mjs +264 -0
  153. package/scripts/update-docs-nav.js +194 -0
  154. package/scripts/update-docs-sidebar.cjs +164 -0
  155. package/security/crypto-config.js +4 -3
  156. package/security/dharma-moderation.js +517 -0
  157. package/security/doko-identity.js +193 -143
  158. package/security/domain-consensus.js +86 -85
  159. package/security/fs-hardening.js +620 -0
  160. package/security/hardware-attestation.js +5 -3
  161. package/security/hybrid-trust.js +227 -87
  162. package/security/karma-rate-limiter.js +692 -0
  163. package/security/khata-protocol.js +22 -21
  164. package/security/khata-trust-integration.js +277 -150
  165. package/security/memory-safety.js +635 -0
  166. package/security/mesh-auth.js +11 -10
  167. package/security/mesh-revocation.js +373 -5
  168. package/security/namche-gateway.js +298 -69
  169. package/security/sakshi.js +460 -3
  170. package/security/sangha.js +770 -0
  171. package/security/secure-config.js +473 -0
  172. package/security/silicon-parity.js +13 -10
  173. package/security/steadywatch.js +1142 -0
  174. package/security/strike-system.js +32 -3
  175. package/security/temporal-signing.js +488 -0
  176. package/security/trit-commitment.js +464 -0
  177. package/server/crypto/annex.js +247 -0
  178. package/server/darshan-api.js +343 -0
  179. package/server/index.js +3259 -362
  180. package/server/komm-api.js +668 -0
  181. package/utils/accel.js +2273 -0
  182. package/utils/ternary-id.js +79 -0
  183. package/utils/verify-worker.js +57 -0
  184. package/webserver/index.js +95 -5
  185. package/assets/yakmesh-logo.png +0 -0
  186. package/assets/yakmesh-logo.svg +0 -80
  187. package/assets/yakmesh-logo2.png +0 -0
  188. package/assets/yakmesh-logo2sm.png +0 -0
  189. package/assets/ymsm.png +0 -0
  190. package/website/assets/silhouettes/adapters.svg +0 -107
  191. package/website/assets/silhouettes/api-endpoints.svg +0 -115
  192. package/website/assets/silhouettes/atomic-clock.svg +0 -83
  193. package/website/assets/silhouettes/base-camp.svg +0 -81
  194. package/website/assets/silhouettes/bridge.svg +0 -69
  195. package/website/assets/silhouettes/docs-bundle.svg +0 -113
  196. package/website/assets/silhouettes/doko-basket.svg +0 -70
  197. package/website/assets/silhouettes/fortress.svg +0 -93
  198. package/website/assets/silhouettes/gateway.svg +0 -54
  199. package/website/assets/silhouettes/gears.svg +0 -93
  200. package/website/assets/silhouettes/globe-satellite.svg +0 -67
  201. package/website/assets/silhouettes/karma-wheel.svg +0 -137
  202. package/website/assets/silhouettes/lama-council.svg +0 -141
  203. package/website/assets/silhouettes/mandala-network.svg +0 -169
  204. package/website/assets/silhouettes/mani-stones.svg +0 -149
  205. package/website/assets/silhouettes/mantra-wheel.svg +0 -116
  206. package/website/assets/silhouettes/mesh-nodes.svg +0 -113
  207. package/website/assets/silhouettes/nakpak.svg +0 -56
  208. package/website/assets/silhouettes/peak-lightning.svg +0 -73
  209. package/website/assets/silhouettes/sherpa.svg +0 -69
  210. package/website/assets/silhouettes/stupa-tower.svg +0 -119
  211. package/website/assets/silhouettes/tattva-eye.svg +0 -78
  212. package/website/assets/silhouettes/terminal.svg +0 -74
  213. package/website/assets/silhouettes/webserver.svg +0 -145
  214. package/website/assets/silhouettes/yak.svg +0 -78
  215. package/website/assets/yakmesh-logo.png +0 -0
  216. package/website/assets/yakmesh-logo.webp +0 -0
  217. package/website/assets/yakmesh-logo128x140.webp +0 -0
  218. package/website/assets/yakmesh-logo2.png +0 -0
  219. package/website/assets/yakmesh-logo2.svg +0 -51
  220. package/website/assets/yakmesh-logo40x44.webp +0 -0
  221. package/website/assets/yakmesh.gif +0 -0
  222. package/website/assets/yakmesh.ico +0 -0
  223. package/website/assets/yakmesh.jpg +0 -0
  224. package/website/assets/yakmesh.pdf +0 -0
  225. package/website/assets/yakmesh.png +0 -0
  226. package/website/assets/yakmesh.svg +0 -70
  227. package/website/assets/yakmesh128.webp +0 -0
  228. package/website/assets/yakmesh32.png +0 -0
  229. package/website/assets/yakmesh32.svg +0 -65
  230. package/website/assets/yakmesh32o.ico +0 -2
  231. package/website/assets/yakmesh32o.svg +0 -65
  232. package/website/assets/yakmesh32o.svgz +0 -0
@@ -0,0 +1,635 @@
1
+ /**
2
+ * Yakmesh Memory Safety — Circulating Canaries
3
+ *
4
+ * ═══════════════════════════════════════════════════════════════════════════════
5
+ * PHILOSOPHY: MEMORY AS LIVING TISSUE
6
+ * ═══════════════════════════════════════════════════════════════════════════════
7
+ *
8
+ * Traditional memory safety: Static analysis, bounds checking, fuzzing.
9
+ * Circulating Canaries: Runtime memory integrity that flows through SANGHA.
10
+ *
11
+ * A CANARY is a strategically-placed memory region with known content.
12
+ * During SANGHA circulation, canaries are checksummed and attested.
13
+ * Corruption (buffer overflow, use-after-free exploit) is detected
14
+ * within one circulation cycle.
15
+ *
16
+ * ═══════════════════════════════════════════════════════════════════════════════
17
+ * CANARY TYPES
18
+ * ═══════════════════════════════════════════════════════════════════════════════
19
+ *
20
+ * 1. STACK CANARIES — Placed in hot function frames
21
+ * Node.js doesn't give direct stack access, so we use proxy objects
22
+ * that live on the JS heap but represent "stack-like" volatile state.
23
+ *
24
+ * 2. HEAP CANARIES — Typed arrays with known patterns
25
+ * These catch heap corruption from native modules (ONNX Runtime, etc.)
26
+ *
27
+ * 3. BUFFER CANARIES — Boundaries around shared ArrayBuffers
28
+ * Detect out-of-bounds writes in Worker-shared memory.
29
+ *
30
+ * 4. CLOSURE CANARIES — Captured variables in long-lived closures
31
+ * Detect corruption of closure state (rare but severe).
32
+ *
33
+ * @module security/memory-safety
34
+ * @version 1.0.0
35
+ */
36
+
37
+ import { createLogger } from '../utils/logger.js';
38
+ import { sha3_256 } from '../utils/accel.js';
39
+ import { bytesToHex } from '@noble/hashes/utils.js';
40
+ import { randomBytes } from 'crypto';
41
+ import { EventEmitter } from 'events';
42
+
43
+ const log = createLogger('security:memory-safety');
44
+
45
+ // =============================================================================
46
+ // CONSTANTS
47
+ // =============================================================================
48
+
49
+ /** Canary types */
50
+ export const CANARY_TYPE = Object.freeze({
51
+ HEAP: 'HEAP', // Typed array with known pattern
52
+ BUFFER: 'BUFFER', // ArrayBuffer boundary markers
53
+ CLOSURE: 'CLOSURE', // Closure variable integrity
54
+ NATIVE: 'NATIVE', // Native module interface canary
55
+ });
56
+
57
+ /** Default canary pattern size */
58
+ const CANARY_SIZE = 256;
59
+
60
+ /** Canary check interval (during SANGHA circulation) */
61
+ const DEFAULT_CHECK_INTERVAL_MS = 5000;
62
+
63
+ // =============================================================================
64
+ // CANARY
65
+ // =============================================================================
66
+
67
+ /**
68
+ * Canary — A memory integrity checkpoint
69
+ *
70
+ * Each canary:
71
+ * - Holds a known pattern in memory
72
+ * - Computes a baseline hash at creation
73
+ * - Verifies integrity during circulation
74
+ */
75
+ export class Canary {
76
+ #id;
77
+ #type;
78
+ #data;
79
+ #baselineHash;
80
+ #createdAt;
81
+ #lastCheck;
82
+ #checkCount;
83
+ #corrupted;
84
+
85
+ /**
86
+ * @param {string} id - Unique canary identifier
87
+ * @param {string} type - Canary type (HEAP/BUFFER/CLOSURE/NATIVE)
88
+ * @param {number} size - Size in bytes
89
+ */
90
+ constructor(id, type = CANARY_TYPE.HEAP, size = CANARY_SIZE) {
91
+ this.#id = id;
92
+ this.#type = type;
93
+ this.#data = new Uint8Array(size);
94
+ this.#createdAt = Date.now();
95
+ this.#lastCheck = 0;
96
+ this.#checkCount = 0;
97
+ this.#corrupted = false;
98
+
99
+ // Fill with cryptographically random pattern
100
+ const pattern = randomBytes(size);
101
+ this.#data.set(pattern);
102
+
103
+ // Compute baseline hash
104
+ this.#baselineHash = bytesToHex(sha3_256(this.#data));
105
+
106
+ Object.seal(this);
107
+ }
108
+
109
+ /** Get canary ID */
110
+ get id() { return this.#id; }
111
+
112
+ /** Get canary type */
113
+ get type() { return this.#type; }
114
+
115
+ /** Get baseline hash */
116
+ get baselineHash() { return this.#baselineHash; }
117
+
118
+ /** Is canary corrupted? */
119
+ get isCorrupted() { return this.#corrupted; }
120
+
121
+ /** Get check count */
122
+ get checkCount() { return this.#checkCount; }
123
+
124
+ /**
125
+ * Verify canary integrity
126
+ * @returns {{ valid: boolean, currentHash?: string }}
127
+ */
128
+ verify() {
129
+ this.#lastCheck = Date.now();
130
+ this.#checkCount++;
131
+
132
+ const currentHash = bytesToHex(sha3_256(this.#data));
133
+
134
+ if (currentHash !== this.#baselineHash) {
135
+ this.#corrupted = true;
136
+ return {
137
+ valid: false,
138
+ currentHash,
139
+ expectedHash: this.#baselineHash,
140
+ };
141
+ }
142
+
143
+ return { valid: true };
144
+ }
145
+
146
+ /**
147
+ * Get pointer to underlying buffer (for native module boundary testing)
148
+ * @returns {Uint8Array}
149
+ */
150
+ getBuffer() {
151
+ return this.#data;
152
+ }
153
+
154
+ /**
155
+ * Get state for SANGHA attestation
156
+ */
157
+ getState() {
158
+ return {
159
+ id: this.#id,
160
+ type: this.#type,
161
+ size: this.#data.length,
162
+ baselineHash: this.#baselineHash.slice(0, 16) + '...',
163
+ lastCheck: this.#lastCheck,
164
+ checkCount: this.#checkCount,
165
+ corrupted: this.#corrupted,
166
+ };
167
+ }
168
+ }
169
+
170
+ // =============================================================================
171
+ // CLOSURE CANARY
172
+ // =============================================================================
173
+
174
+ /**
175
+ * ClosureCanary — Protects closure state integrity
176
+ *
177
+ * JavaScript closures capture variables from outer scope.
178
+ * If those variables are corrupted (rare, but possible via
179
+ * native module bugs), the closure behavior changes silently.
180
+ *
181
+ * A ClosureCanary captures a set of sentinel values in a closure
182
+ * and verifies they haven't been mutated.
183
+ */
184
+ export class ClosureCanary {
185
+ #id;
186
+ #verifier;
187
+ #expectedHash;
188
+ #corrupted;
189
+ #checkCount;
190
+
191
+ /**
192
+ * @param {string} id - Unique identifier
193
+ */
194
+ constructor(id) {
195
+ this.#id = id;
196
+ this.#corrupted = false;
197
+ this.#checkCount = 0;
198
+
199
+ // Create sentinel values in a closure
200
+ const sentinel1 = 0xDEADBEEF;
201
+ const sentinel2 = 0xCAFEBABE;
202
+ const sentinel3 = 'YAKMESH_CLOSURE_CANARY_' + id;
203
+ const sentinel4 = Object.freeze({ magic: 0x144714, frozen: true });
204
+
205
+ // Compute expected hash
206
+ const combined = `${sentinel1}:${sentinel2}:${sentinel3}:${JSON.stringify(sentinel4)}`;
207
+ this.#expectedHash = bytesToHex(sha3_256(new TextEncoder().encode(combined)));
208
+
209
+ // Create verifier closure that captures the sentinels
210
+ this.#verifier = () => {
211
+ const combined = `${sentinel1}:${sentinel2}:${sentinel3}:${JSON.stringify(sentinel4)}`;
212
+ return bytesToHex(sha3_256(new TextEncoder().encode(combined)));
213
+ };
214
+
215
+ Object.seal(this);
216
+ }
217
+
218
+ /** Get canary ID */
219
+ get id() { return this.#id; }
220
+
221
+ /** Is canary corrupted? */
222
+ get isCorrupted() { return this.#corrupted; }
223
+
224
+ /**
225
+ * Verify closure integrity
226
+ */
227
+ verify() {
228
+ this.#checkCount++;
229
+
230
+ try {
231
+ const currentHash = this.#verifier();
232
+
233
+ if (currentHash !== this.#expectedHash) {
234
+ this.#corrupted = true;
235
+ return {
236
+ valid: false,
237
+ error: 'Closure sentinel corruption detected',
238
+ };
239
+ }
240
+
241
+ return { valid: true };
242
+ } catch (e) {
243
+ this.#corrupted = true;
244
+ return {
245
+ valid: false,
246
+ error: `Closure verification threw: ${e.message}`,
247
+ };
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Get state for SANGHA attestation
253
+ */
254
+ getState() {
255
+ return {
256
+ id: this.#id,
257
+ type: CANARY_TYPE.CLOSURE,
258
+ expectedHash: this.#expectedHash.slice(0, 16) + '...',
259
+ checkCount: this.#checkCount,
260
+ corrupted: this.#corrupted,
261
+ };
262
+ }
263
+ }
264
+
265
+ // =============================================================================
266
+ // NATIVE MODULE CANARY
267
+ // =============================================================================
268
+
269
+ /**
270
+ * NativeModuleCanary — Boundary canary for native module interfaces
271
+ *
272
+ * Places canaries around data passed to native modules (ONNX Runtime, etc.)
273
+ * to detect buffer overflows or out-of-bounds writes.
274
+ */
275
+ export class NativeModuleCanary {
276
+ #id;
277
+ #moduleName;
278
+ #preBuffer;
279
+ #postBuffer;
280
+ #preHash;
281
+ #postHash;
282
+ #corrupted;
283
+ #checkCount;
284
+
285
+ /**
286
+ * @param {string} id - Unique identifier
287
+ * @param {string} moduleName - Name of the native module being protected
288
+ * @param {number} size - Canary size (before and after)
289
+ */
290
+ constructor(id, moduleName, size = 64) {
291
+ this.#id = id;
292
+ this.#moduleName = moduleName;
293
+ this.#corrupted = false;
294
+ this.#checkCount = 0;
295
+
296
+ // Create pre and post buffers with random patterns
297
+ this.#preBuffer = new Uint8Array(size);
298
+ this.#postBuffer = new Uint8Array(size);
299
+
300
+ const prePat = randomBytes(size);
301
+ const postPat = randomBytes(size);
302
+
303
+ this.#preBuffer.set(prePat);
304
+ this.#postBuffer.set(postPat);
305
+
306
+ this.#preHash = bytesToHex(sha3_256(this.#preBuffer));
307
+ this.#postHash = bytesToHex(sha3_256(this.#postBuffer));
308
+
309
+ Object.seal(this);
310
+ }
311
+
312
+ /** Get canary ID */
313
+ get id() { return this.#id; }
314
+
315
+ /** Get module name */
316
+ get moduleName() { return this.#moduleName; }
317
+
318
+ /** Get pre-buffer (place before native call data) */
319
+ get preBuffer() { return this.#preBuffer; }
320
+
321
+ /** Get post-buffer (place after native call data) */
322
+ get postBuffer() { return this.#postBuffer; }
323
+
324
+ /** Is canary corrupted? */
325
+ get isCorrupted() { return this.#corrupted; }
326
+
327
+ /**
328
+ * Verify both boundaries
329
+ */
330
+ verify() {
331
+ this.#checkCount++;
332
+
333
+ const preHash = bytesToHex(sha3_256(this.#preBuffer));
334
+ const postHash = bytesToHex(sha3_256(this.#postBuffer));
335
+
336
+ const errors = [];
337
+
338
+ if (preHash !== this.#preHash) {
339
+ errors.push('Pre-buffer corrupted (underflow detected)');
340
+ }
341
+
342
+ if (postHash !== this.#postHash) {
343
+ errors.push('Post-buffer corrupted (overflow detected)');
344
+ }
345
+
346
+ if (errors.length > 0) {
347
+ this.#corrupted = true;
348
+ return {
349
+ valid: false,
350
+ errors,
351
+ module: this.#moduleName,
352
+ };
353
+ }
354
+
355
+ return { valid: true };
356
+ }
357
+
358
+ /**
359
+ * Get state for SANGHA attestation
360
+ */
361
+ getState() {
362
+ return {
363
+ id: this.#id,
364
+ type: CANARY_TYPE.NATIVE,
365
+ module: this.#moduleName,
366
+ preHash: this.#preHash.slice(0, 16) + '...',
367
+ postHash: this.#postHash.slice(0, 16) + '...',
368
+ checkCount: this.#checkCount,
369
+ corrupted: this.#corrupted,
370
+ };
371
+ }
372
+ }
373
+
374
+ // =============================================================================
375
+ // MEMORY SAFETY MANAGER
376
+ // =============================================================================
377
+
378
+ /**
379
+ * MemorySafety — Manages all canaries and SANGHA integration
380
+ */
381
+ export class MemorySafety extends EventEmitter {
382
+ #canaries;
383
+ #closureCanaries;
384
+ #nativeCanaries;
385
+ #sangha;
386
+ #started;
387
+ #checkInterval;
388
+ #lastCheck;
389
+ #totalCorruptions;
390
+
391
+ constructor() {
392
+ super();
393
+ this.#canaries = new Map();
394
+ this.#closureCanaries = new Map();
395
+ this.#nativeCanaries = new Map();
396
+ this.#sangha = null;
397
+ this.#started = false;
398
+ this.#checkInterval = null;
399
+ this.#lastCheck = 0;
400
+ this.#totalCorruptions = 0;
401
+
402
+ Object.seal(this);
403
+ }
404
+
405
+ /**
406
+ * Create a heap canary
407
+ * @param {string} id - Unique identifier
408
+ * @param {number} size - Size in bytes
409
+ * @returns {Canary}
410
+ */
411
+ createHeapCanary(id, size = CANARY_SIZE) {
412
+ const canary = new Canary(id, CANARY_TYPE.HEAP, size);
413
+ this.#canaries.set(id, canary);
414
+ log.debug('Created heap canary', { id, size });
415
+ return canary;
416
+ }
417
+
418
+ /**
419
+ * Create a closure canary
420
+ * @param {string} id - Unique identifier
421
+ * @returns {ClosureCanary}
422
+ */
423
+ createClosureCanary(id) {
424
+ const canary = new ClosureCanary(id);
425
+ this.#closureCanaries.set(id, canary);
426
+ log.debug('Created closure canary', { id });
427
+ return canary;
428
+ }
429
+
430
+ /**
431
+ * Create a native module canary
432
+ * @param {string} id - Unique identifier
433
+ * @param {string} moduleName - Native module name
434
+ * @param {number} size - Boundary size
435
+ * @returns {NativeModuleCanary}
436
+ */
437
+ createNativeCanary(id, moduleName, size = 64) {
438
+ const canary = new NativeModuleCanary(id, moduleName, size);
439
+ this.#nativeCanaries.set(id, canary);
440
+ log.debug('Created native module canary', { id, module: moduleName });
441
+ return canary;
442
+ }
443
+
444
+ /**
445
+ * Initialize default canaries for critical components
446
+ */
447
+ init() {
448
+ // Heap canaries for key memory regions
449
+ this.createHeapCanary('heap:crypto', 512); // Crypto operations
450
+ this.createHeapCanary('heap:mesh', 256); // Mesh state
451
+ this.createHeapCanary('heap:identity', 256); // Identity data
452
+
453
+ // Closure canaries for long-lived closures
454
+ this.createClosureCanary('closure:event-handlers');
455
+ this.createClosureCanary('closure:timers');
456
+
457
+ // Native module canaries
458
+ this.createNativeCanary('native:onnx', 'onnxruntime', 128);
459
+ this.createNativeCanary('native:sqlite', 'better-sqlite3', 64);
460
+
461
+ log.info('Memory safety initialized', {
462
+ heapCanaries: this.#canaries.size,
463
+ closureCanaries: this.#closureCanaries.size,
464
+ nativeCanaries: this.#nativeCanaries.size,
465
+ });
466
+ }
467
+
468
+ /**
469
+ * Bind to SANGHA collective
470
+ * @param {Sangha} sangha - The SANGHA instance
471
+ */
472
+ bindSangha(sangha) {
473
+ this.#sangha = sangha;
474
+ log.info('Memory safety bound to SANGHA collective');
475
+ }
476
+
477
+ /**
478
+ * Verify all canaries
479
+ * @returns {{ valid: boolean, corruptions: object[] }}
480
+ */
481
+ verifyAll() {
482
+ const corruptions = [];
483
+ this.#lastCheck = Date.now();
484
+
485
+ // Check heap canaries
486
+ for (const [id, canary] of this.#canaries) {
487
+ const result = canary.verify();
488
+ if (!result.valid) {
489
+ corruptions.push({
490
+ type: CANARY_TYPE.HEAP,
491
+ id,
492
+ ...result,
493
+ });
494
+ }
495
+ }
496
+
497
+ // Check closure canaries
498
+ for (const [id, canary] of this.#closureCanaries) {
499
+ const result = canary.verify();
500
+ if (!result.valid) {
501
+ corruptions.push({
502
+ type: CANARY_TYPE.CLOSURE,
503
+ id,
504
+ ...result,
505
+ });
506
+ }
507
+ }
508
+
509
+ // Check native canaries
510
+ for (const [id, canary] of this.#nativeCanaries) {
511
+ const result = canary.verify();
512
+ if (!result.valid) {
513
+ corruptions.push({
514
+ type: CANARY_TYPE.NATIVE,
515
+ id,
516
+ ...result,
517
+ });
518
+ }
519
+ }
520
+
521
+ if (corruptions.length > 0) {
522
+ this.#totalCorruptions += corruptions.length;
523
+ this.emit('corruption', corruptions);
524
+ log.error('🚨 MEMORY CORRUPTION DETECTED', {
525
+ count: corruptions.length,
526
+ corruptions,
527
+ });
528
+ }
529
+
530
+ return {
531
+ valid: corruptions.length === 0,
532
+ corruptions,
533
+ };
534
+ }
535
+
536
+ /**
537
+ * Start periodic verification
538
+ * @param {number} intervalMs - Check interval
539
+ */
540
+ start(intervalMs = DEFAULT_CHECK_INTERVAL_MS) {
541
+ if (this.#started) return;
542
+
543
+ this.#started = true;
544
+
545
+ this.#checkInterval = setInterval(() => {
546
+ this.verifyAll();
547
+ }, intervalMs);
548
+
549
+ log.info('Memory safety monitoring started', { interval: intervalMs });
550
+ }
551
+
552
+ /**
553
+ * Get state for SANGHA attestation
554
+ * @returns {Promise<object>}
555
+ */
556
+ async getState() {
557
+ const heapStates = [];
558
+ const closureStates = [];
559
+ const nativeStates = [];
560
+
561
+ for (const canary of this.#canaries.values()) {
562
+ heapStates.push(canary.getState());
563
+ }
564
+
565
+ for (const canary of this.#closureCanaries.values()) {
566
+ closureStates.push(canary.getState());
567
+ }
568
+
569
+ for (const canary of this.#nativeCanaries.values()) {
570
+ nativeStates.push(canary.getState());
571
+ }
572
+
573
+ return {
574
+ component: 'memory',
575
+ heapCanaries: heapStates.length,
576
+ closureCanaries: closureStates.length,
577
+ nativeCanaries: nativeStates.length,
578
+ totalCorruptions: this.#totalCorruptions,
579
+ allHealthy: heapStates.every(c => !c.corrupted) &&
580
+ closureStates.every(c => !c.corrupted) &&
581
+ nativeStates.every(c => !c.corrupted),
582
+ lastCheck: this.#lastCheck,
583
+ };
584
+ }
585
+
586
+ /**
587
+ * Get status summary
588
+ */
589
+ getStatus() {
590
+ return {
591
+ started: this.#started,
592
+ sanghaConnected: !!this.#sangha,
593
+ heapCanaries: this.#canaries.size,
594
+ closureCanaries: this.#closureCanaries.size,
595
+ nativeCanaries: this.#nativeCanaries.size,
596
+ totalCorruptions: this.#totalCorruptions,
597
+ lastCheck: this.#lastCheck,
598
+ };
599
+ }
600
+
601
+ /**
602
+ * Stop monitoring
603
+ */
604
+ stop() {
605
+ if (!this.#started) return;
606
+
607
+ this.#started = false;
608
+
609
+ if (this.#checkInterval) {
610
+ clearInterval(this.#checkInterval);
611
+ this.#checkInterval = null;
612
+ }
613
+
614
+ log.info('Memory safety monitoring stopped');
615
+ }
616
+ }
617
+
618
+ // =============================================================================
619
+ // SINGLETON & EXPORTS
620
+ // =============================================================================
621
+
622
+ let _instance = null;
623
+
624
+ /**
625
+ * Get the MemorySafety singleton
626
+ * @returns {MemorySafety}
627
+ */
628
+ export function getMemorySafety() {
629
+ if (!_instance) {
630
+ _instance = new MemorySafety();
631
+ }
632
+ return _instance;
633
+ }
634
+
635
+ export default MemorySafety;
@@ -9,7 +9,8 @@
9
9
  */
10
10
 
11
11
  import { sha3_256 } from '@noble/hashes/sha3.js';
12
- import { randomBytes, bytesToHex, hexToBytes, utf8ToBytes } from '@noble/hashes/utils.js';
12
+ import { bytesToHex, hexToBytes, utf8ToBytes } from '@noble/hashes/utils.js';
13
+ import { ternaryId } from '../utils/ternary-id.js';
13
14
  import { EventEmitter } from 'events';
14
15
  import { createLogger } from '../utils/logger.js';
15
16
 
@@ -33,7 +34,7 @@ export class MeshAuthenticator extends EventEmitter {
33
34
  this.sessions = new Map();
34
35
  this.stats = { authAttempts: 0, authSuccess: 0, authFailed: 0, blocked: 0 };
35
36
  }
36
-
37
+
37
38
  isAllowed(peerId) {
38
39
  if (this.options.blocklist.has(peerId)) {
39
40
  this.stats.blocked++;
@@ -42,15 +43,15 @@ export class MeshAuthenticator extends EventEmitter {
42
43
  if (this.options.allowlist.size === 0) return true;
43
44
  return this.options.allowlist.has(peerId);
44
45
  }
45
-
46
+
46
47
  generateChallenge(peerId) {
47
48
  if (this.pendingChallenges.size >= this.options.maxPendingAuth) {
48
49
  throw new Error('Too many pending authentication requests');
49
50
  }
50
51
  const challenge = {
51
52
  type: 'auth_challenge',
52
- challengeId: bytesToHex(randomBytes(16)),
53
- nonce: bytesToHex(randomBytes(32)),
53
+ challengeId: ternaryId(16),
54
+ nonce: ternaryId(32),
54
55
  timestamp: Date.now(),
55
56
  challengerNodeId: this.identity.identity.nodeId,
56
57
  };
@@ -59,7 +60,7 @@ export class MeshAuthenticator extends EventEmitter {
59
60
  this.stats.authAttempts++;
60
61
  return challenge;
61
62
  }
62
-
63
+
63
64
  respondToChallenge(challenge) {
64
65
  const responseData = JSON.stringify({
65
66
  challengeId: challenge.challengeId,
@@ -77,7 +78,7 @@ export class MeshAuthenticator extends EventEmitter {
77
78
  signature,
78
79
  };
79
80
  }
80
-
81
+
81
82
  verifyResponse(response) {
82
83
  const pending = this.pendingChallenges.get(response.challengeId);
83
84
  if (!pending) {
@@ -105,17 +106,17 @@ export class MeshAuthenticator extends EventEmitter {
105
106
  this.emit('authenticated', { peerId: response.responderNodeId });
106
107
  return { valid: true, peerId: response.responderNodeId, sessionKey: bytesToHex(sessionKey) };
107
108
  }
108
-
109
+
109
110
  isAuthenticated(peerId) { return this.sessions.has(peerId); }
110
111
  getSession(peerId) { return this.sessions.get(peerId) || null; }
111
112
  revokeSession(peerId) { this.sessions.delete(peerId); this.emit('session-revoked', { peerId }); }
112
113
  block(peerId) { this.options.blocklist.add(peerId); this.revokeSession(peerId); }
113
114
  unblock(peerId) { this.options.blocklist.delete(peerId); }
114
-
115
+
115
116
  _deriveSessionKey(peerId, nonce) {
116
117
  return sha3_256(utf8ToBytes(peerId + nonce + this.identity.identity.nodeId));
117
118
  }
118
-
119
+
119
120
  getStats() {
120
121
  return { ...this.stats, pendingChallenges: this.pendingChallenges.size, activeSessions: this.sessions.size };
121
122
  }