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
@@ -18,9 +18,12 @@
18
18
  */
19
19
 
20
20
  import { randomBytes, createHash } from 'crypto';
21
- import { sha3_256 } from '@noble/hashes/sha3.js';
21
+ import { sha3_256 as _nobleSha3 } from '@noble/hashes/sha3.js';
22
22
  import { bytesToHex, utf8ToBytes } from '@noble/hashes/utils.js';
23
23
 
24
+ // ACCEL: Hardware-accelerated SHA3-256 (OpenSSL/SHA-NI — 4.6x faster)
25
+ import { sha3_256 } from '../utils/accel.js';
26
+
24
27
  const PULSE_CONFIG = {
25
28
  // Heartbeat timing
26
29
  heartbeatIntervalMs: 1000, // 1 second between heartbeats
@@ -7,20 +7,49 @@
7
7
  * - Gossip message floods
8
8
  * - Cross-network attack attempts
9
9
  *
10
+ * Trust-Proportional Limits:
11
+ * - Trusted nodes get higher limits (they've earned it)
12
+ * - But trusted nodes get STRICTER penalties if they abuse (betrayal tax)
13
+ * - This balances power with accountability
14
+ *
10
15
  * @module mesh/rate-limiter
11
16
  */
12
17
 
18
+ /**
19
+ * Trust levels for rate limiting
20
+ * Higher trust = higher limits, but also higher abuse penalties
21
+ */
22
+ export const TRUST_LEVEL = Object.freeze({
23
+ UNKNOWN: 'unknown', // New/unverified nodes
24
+ SUSPICIOUS: 'suspicious', // Nodes with some bad behavior
25
+ NORMAL: 'normal', // Regular nodes
26
+ TRUSTED: 'trusted', // Established good actors
27
+ VETERAN: 'veteran', // Long-term high-trust nodes
28
+ });
29
+
30
+ /**
31
+ * Trust-proportional multipliers
32
+ * Format: { limit: multiplier, penalty: multiplier }
33
+ */
34
+ const TRUST_MULTIPLIERS = Object.freeze({
35
+ [TRUST_LEVEL.UNKNOWN]: { limit: 0.5, penalty: 1.0 }, // Half limits, normal penalty
36
+ [TRUST_LEVEL.SUSPICIOUS]: { limit: 0.25, penalty: 1.5 }, // Quarter limits, 1.5x penalty
37
+ [TRUST_LEVEL.NORMAL]: { limit: 1.0, penalty: 1.0 }, // Base limits
38
+ [TRUST_LEVEL.TRUSTED]: { limit: 2.0, penalty: 2.0 }, // 2x limits, 2x penalty
39
+ [TRUST_LEVEL.VETERAN]: { limit: 5.0, penalty: 3.0 }, // 5x limits, 3x penalty (betrayal tax)
40
+ });
41
+
13
42
  /**
14
43
  * Sliding window rate limiter with per-IP and per-node tracking
15
44
  */
16
45
  export class ConnectionRateLimiter {
17
46
  constructor(options = {}) {
18
47
  this.config = {
19
- // Connection rate limits
48
+ // Connection rate limits (base values)
20
49
  maxConnectionsPerMinute: options.maxConnectionsPerMinute || 10,
21
50
  maxConnectionsPerHour: options.maxConnectionsPerHour || 60,
22
51
 
23
- // Message rate limits
52
+ // Message rate limits (base values)
24
53
  maxMessagesPerSecond: options.maxMessagesPerSecond || 50,
25
54
  maxMessagesPerMinute: options.maxMessagesPerMinute || 500,
26
55
 
@@ -31,7 +60,7 @@ export class ConnectionRateLimiter {
31
60
  maxGossipPerSecond: options.maxGossipPerSecond || 20,
32
61
  maxRumorsPerMinute: options.maxRumorsPerMinute || 100,
33
62
 
34
- // Ban thresholds
63
+ // Ban thresholds (adjusted by trust penalty multiplier)
35
64
  banThreshold: options.banThreshold || 5, // violations before ban
36
65
  banDuration: options.banDuration || 300000, // 5 minutes
37
66
 
@@ -47,10 +76,52 @@ export class ConnectionRateLimiter {
47
76
  this.violations = new Map(); // IP -> { count, lastViolation }
48
77
  this.banned = new Map(); // IP -> banExpiry timestamp
49
78
 
79
+ // Trust level cache (nodeId -> TRUST_LEVEL)
80
+ this.trustLevels = new Map();
81
+
50
82
  // Start cleanup interval
51
83
  this._cleanupInterval = setInterval(() => this._cleanup(), this.config.cleanupInterval);
52
84
  }
53
85
 
86
+ /**
87
+ * Set trust level for a node (call this when trust changes)
88
+ * @param {string} nodeId - Node identifier
89
+ * @param {string} trustLevel - One of TRUST_LEVEL values
90
+ */
91
+ setTrustLevel(nodeId, trustLevel) {
92
+ if (!Object.values(TRUST_LEVEL).includes(trustLevel)) {
93
+ trustLevel = TRUST_LEVEL.NORMAL;
94
+ }
95
+ this.trustLevels.set(nodeId, trustLevel);
96
+ }
97
+
98
+ /**
99
+ * Get trust level for a node
100
+ */
101
+ getTrustLevel(nodeId) {
102
+ return this.trustLevels.get(nodeId) || TRUST_LEVEL.UNKNOWN;
103
+ }
104
+
105
+ /**
106
+ * Get effective limit based on trust level
107
+ * @private
108
+ */
109
+ _getEffectiveLimit(baseLimit, nodeId) {
110
+ const trustLevel = this.getTrustLevel(nodeId);
111
+ const multiplier = TRUST_MULTIPLIERS[trustLevel]?.limit || 1.0;
112
+ return Math.ceil(baseLimit * multiplier);
113
+ }
114
+
115
+ /**
116
+ * Get effective penalty based on trust level
117
+ * Higher trust = higher penalty (betrayal tax)
118
+ * @private
119
+ */
120
+ _getEffectivePenalty(nodeId) {
121
+ const trustLevel = this.getTrustLevel(nodeId);
122
+ return TRUST_MULTIPLIERS[trustLevel]?.penalty || 1.0;
123
+ }
124
+
54
125
  /**
55
126
  * Check if an IP is currently banned
56
127
  */
@@ -67,21 +138,34 @@ export class ConnectionRateLimiter {
67
138
 
68
139
  /**
69
140
  * Record a violation and potentially ban
141
+ * Uses trust-proportional penalty (higher trust = stricter penalty)
70
142
  */
71
- _recordViolation(ip, reason) {
72
- const record = this.violations.get(ip) || { count: 0, reasons: [] };
73
- record.count++;
143
+ _recordViolation(ip, reason, nodeId = null) {
144
+ const record = this.violations.get(ip) || { count: 0, reasons: [], nodeId };
145
+ const penaltyMultiplier = nodeId ? this._getEffectivePenalty(nodeId) : 1.0;
146
+
147
+ // Apply penalty multiplier - trusted nodes get penalized harder
148
+ const effectivePenalty = penaltyMultiplier;
149
+ record.count += effectivePenalty;
74
150
  record.lastViolation = Date.now();
75
151
  record.reasons.push(reason);
152
+ if (nodeId) record.nodeId = nodeId;
76
153
  this.violations.set(ip, record);
77
154
 
78
- if (record.count >= this.config.banThreshold) {
79
- this.banned.set(ip, Date.now() + this.config.banDuration);
80
- console.warn(`🚫 Banned IP ${ip} for ${this.config.banDuration/1000}s. Reasons: ${record.reasons.slice(-3).join(', ')}`);
155
+ // Effective ban threshold (lower for high-trust nodes that betray)
156
+ const effectiveThreshold = this.config.banThreshold / penaltyMultiplier;
157
+
158
+ if (record.count >= effectiveThreshold) {
159
+ // Ban duration is also extended for trusted nodes that abuse
160
+ const effectiveBanDuration = this.config.banDuration * penaltyMultiplier;
161
+ this.banned.set(ip, Date.now() + effectiveBanDuration);
162
+
163
+ const trustLevel = nodeId ? this.getTrustLevel(nodeId) : TRUST_LEVEL.UNKNOWN;
164
+ console.warn(`🚫 Banned IP ${ip} for ${effectiveBanDuration/1000}s (trust: ${trustLevel}, penalty: ${penaltyMultiplier}x). Reasons: ${record.reasons.slice(-3).join(', ')}`);
81
165
  return true;
82
166
  }
83
167
 
84
- console.warn(`⚠️ Rate limit violation from ${ip}: ${reason} (${record.count}/${this.config.banThreshold})`);
168
+ console.warn(`⚠️ Rate limit violation from ${ip}: ${reason} (${record.count.toFixed(1)}/${effectiveThreshold} with ${penaltyMultiplier}x penalty)`);
85
169
  return false;
86
170
  }
87
171
 
@@ -177,8 +261,12 @@ export class ConnectionRateLimiter {
177
261
 
178
262
  /**
179
263
  * Check if a message from a node is allowed
264
+ * Uses trust-proportional limits
180
265
  */
181
- checkMessage(nodeIdOrIp) {
266
+ checkMessage(nodeIdOrIp, nodeId = null) {
267
+ // If only one arg and it looks like a nodeId, use it for trust lookup
268
+ const effectiveNodeId = nodeId || (nodeIdOrIp.startsWith('DOKO-') ? nodeIdOrIp : null);
269
+
182
270
  const now = Date.now();
183
271
  const record = this.messages.get(nodeIdOrIp) || {
184
272
  count: 0,
@@ -199,8 +287,12 @@ export class ConnectionRateLimiter {
199
287
  record.windowStart = now;
200
288
  }
201
289
 
290
+ // Get trust-proportional limits
291
+ const effectivePerSecond = this._getEffectiveLimit(this.config.maxMessagesPerSecond, effectiveNodeId);
292
+ const effectivePerMinute = this._getEffectiveLimit(this.config.maxMessagesPerMinute, effectiveNodeId);
293
+
202
294
  // Check per-second limit
203
- if (record.secondCount >= this.config.maxMessagesPerSecond) {
295
+ if (record.secondCount >= effectivePerSecond) {
204
296
  return {
205
297
  allowed: false,
206
298
  reason: 'Message rate exceeded (per second)',
@@ -209,7 +301,7 @@ export class ConnectionRateLimiter {
209
301
  }
210
302
 
211
303
  // Check per-minute limit
212
- if (record.count >= this.config.maxMessagesPerMinute) {
304
+ if (record.count >= effectivePerMinute) {
213
305
  return {
214
306
  allowed: false,
215
307
  reason: 'Message rate exceeded (per minute)',
@@ -225,6 +317,7 @@ export class ConnectionRateLimiter {
225
317
 
226
318
  /**
227
319
  * Check if a gossip/rumor from a node is allowed
320
+ * Uses trust-proportional limits
228
321
  */
229
322
  checkGossip(nodeId) {
230
323
  const now = Date.now();
@@ -247,13 +340,17 @@ export class ConnectionRateLimiter {
247
340
  record.windowStart = now;
248
341
  }
249
342
 
343
+ // Get trust-proportional limits
344
+ const effectivePerSecond = this._getEffectiveLimit(this.config.maxGossipPerSecond, nodeId);
345
+ const effectivePerMinute = this._getEffectiveLimit(this.config.maxRumorsPerMinute, nodeId);
346
+
250
347
  // Check per-second limit
251
- if (record.secondCount >= this.config.maxGossipPerSecond) {
348
+ if (record.secondCount >= effectivePerSecond) {
252
349
  return { allowed: false, reason: 'Gossip rate exceeded (per second)' };
253
350
  }
254
351
 
255
352
  // Check per-minute limit
256
- if (record.count >= this.config.maxRumorsPerMinute) {
353
+ if (record.count >= effectivePerMinute) {
257
354
  return { allowed: false, reason: 'Gossip rate exceeded (per minute)' };
258
355
  }
259
356
 
@@ -267,6 +364,19 @@ export class ConnectionRateLimiter {
267
364
  * Get statistics for monitoring
268
365
  */
269
366
  getStats() {
367
+ // Count nodes by trust level
368
+ const trustDistribution = {
369
+ [TRUST_LEVEL.UNKNOWN]: 0,
370
+ [TRUST_LEVEL.SUSPICIOUS]: 0,
371
+ [TRUST_LEVEL.NORMAL]: 0,
372
+ [TRUST_LEVEL.TRUSTED]: 0,
373
+ [TRUST_LEVEL.VETERAN]: 0,
374
+ };
375
+
376
+ for (const level of this.trustLevels.values()) {
377
+ trustDistribution[level] = (trustDistribution[level] || 0) + 1;
378
+ }
379
+
270
380
  return {
271
381
  activeConnections: this.connections.size,
272
382
  activeMessageTracking: this.messages.size,
@@ -275,6 +385,8 @@ export class ConnectionRateLimiter {
275
385
  violations: this.violations.size,
276
386
  banned: this.banned.size,
277
387
  bannedIPs: Array.from(this.banned.keys()),
388
+ trustLevelsTracked: this.trustLevels.size,
389
+ trustDistribution,
278
390
  };
279
391
  }
280
392