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.
- package/CHANGELOG.md +637 -0
- package/CONTRIBUTING.md +42 -0
- package/Caddyfile +77 -0
- package/README.md +119 -29
- package/adapters/adapter-mlv-bible/README.md +124 -0
- package/adapters/adapter-mlv-bible/index.js +400 -0
- package/adapters/chat-mod-adapter.js +532 -0
- package/adapters/content-adapter.js +273 -0
- package/content/api.js +50 -41
- package/content/index.js +2 -2
- package/content/store.js +355 -173
- package/dashboard/index.html +19 -3
- package/database/replication.js +117 -37
- package/docs/CRYPTO-AGILITY.md +204 -0
- package/docs/MTLS-RESEARCH.md +367 -0
- package/docs/NAMCHE-SPEC.md +681 -0
- package/docs/PEERQUANTA-YAKMESH-INTEGRATION.md +407 -0
- package/docs/PRECISION-DISCLOSURE.md +96 -0
- package/docs/README.md +76 -0
- package/docs/ROADMAP-2.4.0.md +447 -0
- package/docs/ROADMAP-2.5.0.md +244 -0
- package/docs/SECURITY-AUDIT-REPORT.md +306 -0
- package/docs/SST-INTEGRATION.md +712 -0
- package/docs/STEADYWATCH-IMPLEMENTATION.md +303 -0
- package/docs/TERNARY-AUDIT-REPORT.md +247 -0
- package/docs/TME-FAQ.md +221 -0
- package/docs/WHITEPAPER.md +623 -0
- package/docs/adapters.html +1001 -0
- package/docs/advanced-systems.html +1045 -0
- package/docs/annex.html +1046 -0
- package/docs/api.html +970 -0
- package/docs/business/response-templates.md +160 -0
- package/docs/c2c.html +1225 -0
- package/docs/cli.html +1332 -0
- package/docs/configuration.html +1248 -0
- package/docs/darshan.html +1085 -0
- package/docs/dharma.html +966 -0
- package/docs/docs-bundle.html +1075 -0
- package/docs/docs.css +3120 -0
- package/docs/docs.js +556 -0
- package/docs/doko.html +969 -0
- package/docs/geo-proof.html +858 -0
- package/docs/getting-started.html +840 -0
- package/docs/gumba-tutorial.html +1144 -0
- package/docs/gumba.html +1098 -0
- package/docs/index.html +914 -0
- package/docs/jhilke.html +1312 -0
- package/docs/karma.html +1100 -0
- package/docs/katha.html +1037 -0
- package/docs/lama.html +978 -0
- package/docs/mandala.html +1067 -0
- package/docs/mani.html +964 -0
- package/docs/mantra.html +967 -0
- package/docs/mesh.html +1409 -0
- package/docs/nakpak.html +869 -0
- package/docs/namche.html +928 -0
- package/docs/nav-order.json +53 -0
- package/docs/prahari.html +1043 -0
- package/docs/prism-bash.min.js +1 -0
- package/docs/prism-javascript.min.js +1 -0
- package/docs/prism-json.min.js +1 -0
- package/docs/prism-tomorrow.min.css +1 -0
- package/docs/prism.min.js +1 -0
- package/docs/privacy.html +699 -0
- package/docs/quick-reference.html +1181 -0
- package/docs/sakshi.html +1402 -0
- package/docs/sandboxing.md +386 -0
- package/docs/seva.html +911 -0
- package/docs/sherpa.html +871 -0
- package/docs/studio.html +860 -0
- package/docs/stupa.html +995 -0
- package/docs/tailwind.min.css +2 -0
- package/docs/tattva.html +1332 -0
- package/docs/terms.html +686 -0
- package/docs/time-server-deployment.md +166 -0
- package/docs/time-sources.html +1392 -0
- package/docs/tivra.html +1127 -0
- package/docs/trademark-policy.html +686 -0
- package/docs/tribhuj.html +1183 -0
- package/docs/trust-security.html +1029 -0
- package/docs/tutorials/backup-recovery.html +654 -0
- package/docs/tutorials/dashboard.html +604 -0
- package/docs/tutorials/domain-setup.html +605 -0
- package/docs/tutorials/host-website.html +456 -0
- package/docs/tutorials/mesh-network.html +505 -0
- package/docs/tutorials/mobile-access.html +445 -0
- package/docs/tutorials/privacy.html +467 -0
- package/docs/tutorials/raspberry-pi.html +600 -0
- package/docs/tutorials/security-basics.html +539 -0
- package/docs/tutorials/share-files.html +431 -0
- package/docs/tutorials/troubleshooting.html +637 -0
- package/docs/tutorials/trust-karma.html +419 -0
- package/docs/tutorials/yak-protocol.html +456 -0
- package/docs/tutorials.html +1034 -0
- package/docs/vani.html +1270 -0
- package/docs/webserver.html +809 -0
- package/docs/yak-protocol.html +940 -0
- package/docs/yak-timeserver-design.md +475 -0
- package/docs/yakapp.html +1015 -0
- package/docs/ypc27.html +1069 -0
- package/docs/yurt.html +1344 -0
- package/embedded-docs/bundle.js +334 -74
- package/gossip/protocol.js +247 -27
- package/identity/key-resolver.js +262 -0
- package/identity/machine-seed.js +632 -0
- package/identity/node-key.js +669 -368
- package/identity/tribhuj-ratchet.js +506 -0
- package/knowledge-base.js +37 -8
- package/launcher/yakmesh.bat +62 -0
- package/launcher/yakmesh.sh +70 -0
- package/mesh/annex.js +462 -108
- package/mesh/beacon-broadcast.js +113 -1
- package/mesh/darshan.js +1718 -0
- package/mesh/gumba.js +1567 -0
- package/mesh/jhilke.js +651 -0
- package/mesh/katha.js +1012 -0
- package/mesh/nakpak-routing.js +8 -5
- package/mesh/network.js +724 -34
- package/mesh/pulse-sync.js +4 -1
- package/mesh/rate-limiter.js +127 -15
- package/mesh/seva.js +526 -0
- package/mesh/sherpa-discovery.js +89 -8
- package/mesh/sybil-defense.js +19 -5
- package/mesh/temporal-encoder.js +4 -3
- package/mesh/vani.js +1364 -0
- package/mesh/yurt.js +1340 -0
- package/models/entropy-sentinel.onnx +0 -0
- package/models/karma-trust.onnx +0 -0
- package/models/manifest.json +43 -0
- package/models/sakshi-anomaly.onnx +0 -0
- package/oracle/code-proof-protocol.js +7 -6
- package/oracle/codebase-lock.js +257 -28
- package/oracle/index.js +74 -15
- package/oracle/ma902-snmp.js +678 -0
- package/oracle/module-sealer.js +5 -3
- package/oracle/network-identity.js +16 -0
- package/oracle/packet-checksum.js +201 -0
- package/oracle/sst.js +579 -0
- package/oracle/ternary-144t.js +714 -0
- package/oracle/ternary-ml.js +481 -0
- package/oracle/time-api.js +239 -0
- package/oracle/time-source.js +137 -47
- package/oracle/validation-oracle-hardened.js +1111 -1071
- package/oracle/validation-oracle.js +4 -2
- package/oracle/ypc27.js +211 -0
- package/package.json +20 -3
- package/protocol/yak-handler.js +35 -9
- package/protocol/yak-protocol.js +28 -13
- package/reference/cpp/yakmesh_mceliece_shard.cpp +168 -0
- package/reference/cpp/yakmesh_ypc27.cpp +179 -0
- package/sbom.json +87 -0
- package/scripts/security-audit.mjs +264 -0
- package/scripts/update-docs-nav.js +194 -0
- package/scripts/update-docs-sidebar.cjs +164 -0
- package/security/crypto-config.js +4 -3
- package/security/dharma-moderation.js +517 -0
- package/security/doko-identity.js +193 -143
- package/security/domain-consensus.js +86 -85
- package/security/fs-hardening.js +620 -0
- package/security/hardware-attestation.js +5 -3
- package/security/hybrid-trust.js +227 -87
- package/security/karma-rate-limiter.js +692 -0
- package/security/khata-protocol.js +22 -21
- package/security/khata-trust-integration.js +277 -150
- package/security/memory-safety.js +635 -0
- package/security/mesh-auth.js +11 -10
- package/security/mesh-revocation.js +373 -5
- package/security/namche-gateway.js +298 -69
- package/security/sakshi.js +460 -3
- package/security/sangha.js +770 -0
- package/security/secure-config.js +473 -0
- package/security/silicon-parity.js +13 -10
- package/security/steadywatch.js +1142 -0
- package/security/strike-system.js +32 -3
- package/security/temporal-signing.js +488 -0
- package/security/trit-commitment.js +464 -0
- package/server/crypto/annex.js +247 -0
- package/server/darshan-api.js +343 -0
- package/server/index.js +3259 -362
- package/server/komm-api.js +668 -0
- package/utils/accel.js +2273 -0
- package/utils/ternary-id.js +79 -0
- package/utils/verify-worker.js +57 -0
- package/webserver/index.js +95 -5
- package/assets/yakmesh-logo.png +0 -0
- package/assets/yakmesh-logo.svg +0 -80
- package/assets/yakmesh-logo2.png +0 -0
- package/assets/yakmesh-logo2sm.png +0 -0
- package/assets/ymsm.png +0 -0
- package/website/assets/silhouettes/adapters.svg +0 -107
- package/website/assets/silhouettes/api-endpoints.svg +0 -115
- package/website/assets/silhouettes/atomic-clock.svg +0 -83
- package/website/assets/silhouettes/base-camp.svg +0 -81
- package/website/assets/silhouettes/bridge.svg +0 -69
- package/website/assets/silhouettes/docs-bundle.svg +0 -113
- package/website/assets/silhouettes/doko-basket.svg +0 -70
- package/website/assets/silhouettes/fortress.svg +0 -93
- package/website/assets/silhouettes/gateway.svg +0 -54
- package/website/assets/silhouettes/gears.svg +0 -93
- package/website/assets/silhouettes/globe-satellite.svg +0 -67
- package/website/assets/silhouettes/karma-wheel.svg +0 -137
- package/website/assets/silhouettes/lama-council.svg +0 -141
- package/website/assets/silhouettes/mandala-network.svg +0 -169
- package/website/assets/silhouettes/mani-stones.svg +0 -149
- package/website/assets/silhouettes/mantra-wheel.svg +0 -116
- package/website/assets/silhouettes/mesh-nodes.svg +0 -113
- package/website/assets/silhouettes/nakpak.svg +0 -56
- package/website/assets/silhouettes/peak-lightning.svg +0 -73
- package/website/assets/silhouettes/sherpa.svg +0 -69
- package/website/assets/silhouettes/stupa-tower.svg +0 -119
- package/website/assets/silhouettes/tattva-eye.svg +0 -78
- package/website/assets/silhouettes/terminal.svg +0 -74
- package/website/assets/silhouettes/webserver.svg +0 -145
- package/website/assets/silhouettes/yak.svg +0 -78
- package/website/assets/yakmesh-logo.png +0 -0
- package/website/assets/yakmesh-logo.webp +0 -0
- package/website/assets/yakmesh-logo128x140.webp +0 -0
- package/website/assets/yakmesh-logo2.png +0 -0
- package/website/assets/yakmesh-logo2.svg +0 -51
- package/website/assets/yakmesh-logo40x44.webp +0 -0
- package/website/assets/yakmesh.gif +0 -0
- package/website/assets/yakmesh.ico +0 -0
- package/website/assets/yakmesh.jpg +0 -0
- package/website/assets/yakmesh.pdf +0 -0
- package/website/assets/yakmesh.png +0 -0
- package/website/assets/yakmesh.svg +0 -70
- package/website/assets/yakmesh128.webp +0 -0
- package/website/assets/yakmesh32.png +0 -0
- package/website/assets/yakmesh32.svg +0 -65
- package/website/assets/yakmesh32o.ico +0 -2
- package/website/assets/yakmesh32o.svg +0 -65
- package/website/assets/yakmesh32o.svgz +0 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TERNARY-ML — Balanced Ternary Quantization for ML Inference
|
|
3
|
+
*
|
|
4
|
+
* Bridges TRIBHUJ balanced ternary algebra with ONNX ML inference via
|
|
5
|
+
* the ACCEL hardware acceleration layer. Provides:
|
|
6
|
+
*
|
|
7
|
+
* 1. Ternary quantization of float features → {-1, 0, +1} trits
|
|
8
|
+
* 2. SST family-aware feature encoding (digital root → family → trit)
|
|
9
|
+
* 3. TernaryInferenceAdapter for routing ternary-quantized data through NPU/GPU
|
|
10
|
+
* 4. Trust-aware consensus scoring using ternary majority logic
|
|
11
|
+
*
|
|
12
|
+
* Why ternary quantization for YAKMESH ML?
|
|
13
|
+
* - AMD XDNA NPU operates on INT8 but ternary {-1,0,+1} maps directly to it
|
|
14
|
+
* - Reduces feature space from float32 to 2 bits (ternary) per feature
|
|
15
|
+
* - Natural alignment with KARMA trust scores (DISTRUST/UNVERIFIED/TRUST)
|
|
16
|
+
* - SAKSHI anomaly detection benefits from 3-state classification
|
|
17
|
+
* - The 3^N state space prevents gradient-based adversarial attacks
|
|
18
|
+
*
|
|
19
|
+
* Integration:
|
|
20
|
+
* TRIBHUJ (algebra) → TERNARY-ML (quantization) → ACCEL (hardware)
|
|
21
|
+
* SST (family mapping) → TERNARY-ML (feature encoding) → ONNX (inference)
|
|
22
|
+
*
|
|
23
|
+
* @module oracle/ternary-ml
|
|
24
|
+
* @license MIT
|
|
25
|
+
* @copyright 2026 YAKMESH™ Contributors
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { Trit, TritArray, POSITIVE, NEUTRAL, NEGATIVE, TritState } from './tribhuj.js';
|
|
29
|
+
import { toFamilyTrit, getFamilyOf, SSTFamily, digitalRoot } from './sst.js';
|
|
30
|
+
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// TERNARY QUANTIZATION
|
|
33
|
+
// =============================================================================
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Quantize a float value to a balanced trit {-1, 0, +1}.
|
|
37
|
+
*
|
|
38
|
+
* Uses a dead-zone around zero to prevent noise from creating false signals:
|
|
39
|
+
* value < -threshold → NEGATIVE (-1)
|
|
40
|
+
* -threshold ≤ value ≤ +threshold → NEUTRAL (0)
|
|
41
|
+
* value > +threshold → POSITIVE (+1)
|
|
42
|
+
*
|
|
43
|
+
* @param {number} value — float value to quantize
|
|
44
|
+
* @param {number} [threshold=0.33] — dead-zone radius
|
|
45
|
+
* @returns {number} — trit value {-1, 0, +1}
|
|
46
|
+
*/
|
|
47
|
+
export function quantizeToTrit(value, threshold = 0.33) {
|
|
48
|
+
if (value < -threshold) return NEGATIVE;
|
|
49
|
+
if (value > threshold) return POSITIVE;
|
|
50
|
+
return NEUTRAL;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Quantize a float array to balanced trits.
|
|
55
|
+
*
|
|
56
|
+
* @param {Float32Array | number[]} values — float values
|
|
57
|
+
* @param {number} [threshold=0.33] — dead-zone radius
|
|
58
|
+
* @returns {Int8Array} — trit values
|
|
59
|
+
*/
|
|
60
|
+
export function quantizeArray(values, threshold = 0.33) {
|
|
61
|
+
const trits = new Int8Array(values.length);
|
|
62
|
+
for (let i = 0; i < values.length; i++) {
|
|
63
|
+
trits[i] = quantizeToTrit(values[i], threshold);
|
|
64
|
+
}
|
|
65
|
+
return trits;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Adaptive quantization — threshold derived from data statistics.
|
|
70
|
+
*
|
|
71
|
+
* Computes mean and standard deviation, then uses:
|
|
72
|
+
* threshold = max(minThreshold, sigma * factor)
|
|
73
|
+
*
|
|
74
|
+
* This prevents the dead-zone from being too narrow (noise)
|
|
75
|
+
* or too wide (losing signal).
|
|
76
|
+
*
|
|
77
|
+
* @param {Float32Array | number[]} values
|
|
78
|
+
* @param {number} [factor=0.5] — sigma multiplier
|
|
79
|
+
* @param {number} [minThreshold=0.1] — absolute minimum
|
|
80
|
+
* @returns {{ trits: Int8Array, threshold: number, mean: number, sigma: number }}
|
|
81
|
+
*/
|
|
82
|
+
export function adaptiveQuantize(values, factor = 0.5, minThreshold = 0.1) {
|
|
83
|
+
const n = values.length;
|
|
84
|
+
if (n === 0) return { trits: new Int8Array(0), threshold: 0, mean: 0, sigma: 0 };
|
|
85
|
+
|
|
86
|
+
// Compute mean
|
|
87
|
+
let sum = 0;
|
|
88
|
+
for (let i = 0; i < n; i++) sum += values[i];
|
|
89
|
+
const mean = sum / n;
|
|
90
|
+
|
|
91
|
+
// Compute standard deviation
|
|
92
|
+
let sqDiffSum = 0;
|
|
93
|
+
for (let i = 0; i < n; i++) {
|
|
94
|
+
const diff = values[i] - mean;
|
|
95
|
+
sqDiffSum += diff * diff;
|
|
96
|
+
}
|
|
97
|
+
const sigma = Math.sqrt(sqDiffSum / n);
|
|
98
|
+
|
|
99
|
+
// Adaptive threshold
|
|
100
|
+
const threshold = Math.max(minThreshold, sigma * factor);
|
|
101
|
+
|
|
102
|
+
// Center and quantize
|
|
103
|
+
const trits = new Int8Array(n);
|
|
104
|
+
for (let i = 0; i < n; i++) {
|
|
105
|
+
trits[i] = quantizeToTrit(values[i] - mean, threshold);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return { trits, threshold, mean, sigma };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Dequantize trits back to float approximation.
|
|
113
|
+
* Uses mean and threshold from the quantization step.
|
|
114
|
+
*
|
|
115
|
+
* @param {Int8Array} trits
|
|
116
|
+
* @param {number} mean — original mean
|
|
117
|
+
* @param {number} threshold — quantization threshold
|
|
118
|
+
* @returns {Float32Array} — reconstructed approximation
|
|
119
|
+
*/
|
|
120
|
+
export function dequantizeTrits(trits, mean = 0, threshold = 0.33) {
|
|
121
|
+
const values = new Float32Array(trits.length);
|
|
122
|
+
for (let i = 0; i < trits.length; i++) {
|
|
123
|
+
values[i] = mean + trits[i] * threshold;
|
|
124
|
+
}
|
|
125
|
+
return values;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// =============================================================================
|
|
129
|
+
// SST FAMILY FEATURE ENCODING
|
|
130
|
+
// =============================================================================
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Encode numeric features using SST family classification.
|
|
134
|
+
*
|
|
135
|
+
* Each feature value is mapped through:
|
|
136
|
+
* value → digitalRoot → family → trit
|
|
137
|
+
*
|
|
138
|
+
* This creates a "harmonic fingerprint" of the feature vector
|
|
139
|
+
* where the 3-6-9 governing family acts as natural clustering.
|
|
140
|
+
*
|
|
141
|
+
* Use cases:
|
|
142
|
+
* - Node ID classification for routing
|
|
143
|
+
* - Trust score family grouping
|
|
144
|
+
* - Anomaly detection (unusual family distribution)
|
|
145
|
+
*
|
|
146
|
+
* @param {number[]} features — numeric feature values (integers)
|
|
147
|
+
* @returns {{ trits: Int8Array, families: string[], roots: number[] }}
|
|
148
|
+
*/
|
|
149
|
+
export function sstEncodeFeatures(features) {
|
|
150
|
+
const n = features.length;
|
|
151
|
+
const trits = new Int8Array(n);
|
|
152
|
+
const families = new Array(n);
|
|
153
|
+
const roots = new Array(n);
|
|
154
|
+
|
|
155
|
+
for (let i = 0; i < n; i++) {
|
|
156
|
+
const val = Math.abs(Math.floor(features[i]));
|
|
157
|
+
roots[i] = digitalRoot(val);
|
|
158
|
+
families[i] = getFamilyOf(val);
|
|
159
|
+
trits[i] = toFamilyTrit(val).value;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return { trits, families, roots };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Compute the family balance of encoded features.
|
|
167
|
+
* A balanced distribution (roughly equal A, B, C) indicates
|
|
168
|
+
* normal/healthy data. Skew indicates anomaly.
|
|
169
|
+
*
|
|
170
|
+
* @param {string[]} families — array of 'A', 'B', 'C'
|
|
171
|
+
* @returns {{ a: number, b: number, c: number, balance: number, isBalanced: boolean }}
|
|
172
|
+
*/
|
|
173
|
+
export function familyBalance(families) {
|
|
174
|
+
let a = 0, b = 0, c = 0;
|
|
175
|
+
for (const f of families) {
|
|
176
|
+
if (f === SSTFamily.A) a++;
|
|
177
|
+
else if (f === SSTFamily.B) b++;
|
|
178
|
+
else c++;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const n = families.length || 1;
|
|
182
|
+
const expected = n / 3;
|
|
183
|
+
|
|
184
|
+
// Chi-squared-like balance metric (0 = perfect balance, higher = more skewed)
|
|
185
|
+
const balance = Math.sqrt(
|
|
186
|
+
Math.pow(a - expected, 2) +
|
|
187
|
+
Math.pow(b - expected, 2) +
|
|
188
|
+
Math.pow(c - expected, 2)
|
|
189
|
+
) / expected;
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
a, b, c,
|
|
193
|
+
balance: +balance.toFixed(4),
|
|
194
|
+
isBalanced: balance < 1.0, // Within 1 standard deviation
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// =============================================================================
|
|
199
|
+
// TERNARY FEATURE VECTOR (for ONNX model input)
|
|
200
|
+
// =============================================================================
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Build a ternary feature vector suitable for ONNX model input.
|
|
204
|
+
*
|
|
205
|
+
* Packs multiple signal channels into a single vector:
|
|
206
|
+
* 1. Adaptive-quantized raw features (captures signal direction)
|
|
207
|
+
* 2. SST family encoding (captures harmonic structure)
|
|
208
|
+
* 3. Family balance metrics (captures distribution health)
|
|
209
|
+
*
|
|
210
|
+
* The result is a Float32Array ready for ONNX Tensor creation.
|
|
211
|
+
* Values are in {-1, 0, +1} but typed as float32 for ONNX compatibility.
|
|
212
|
+
*
|
|
213
|
+
* @param {Float32Array | number[]} rawFeatures — original float features
|
|
214
|
+
* @param {Object} [options]
|
|
215
|
+
* @param {number} [options.quantThreshold=0.33] — fixed threshold (0 = adaptive)
|
|
216
|
+
* @param {boolean} [options.includeSST=true] — include SST family channel
|
|
217
|
+
* @param {boolean} [options.includeBalance=true] — include balance metrics
|
|
218
|
+
* @returns {{ vector: Float32Array, channels: Object, dimensions: number }}
|
|
219
|
+
*/
|
|
220
|
+
export function buildTernaryFeatureVector(rawFeatures, options = {}) {
|
|
221
|
+
const {
|
|
222
|
+
quantThreshold = 0, // 0 means adaptive
|
|
223
|
+
includeSST = true,
|
|
224
|
+
includeBalance = true,
|
|
225
|
+
} = options;
|
|
226
|
+
|
|
227
|
+
// Channel 1: Adaptive quantization of raw float features
|
|
228
|
+
const quant = quantThreshold > 0
|
|
229
|
+
? { trits: quantizeArray(rawFeatures, quantThreshold), threshold: quantThreshold, mean: 0, sigma: 0 }
|
|
230
|
+
: adaptiveQuantize(rawFeatures);
|
|
231
|
+
|
|
232
|
+
// Channel 2: SST family encoding (if features are interpretable as integers)
|
|
233
|
+
let sstTrits = null;
|
|
234
|
+
let balance = null;
|
|
235
|
+
if (includeSST) {
|
|
236
|
+
const encoded = sstEncodeFeatures(Array.from(rawFeatures).map(v => Math.round(Math.abs(v * 1000))));
|
|
237
|
+
sstTrits = encoded.trits;
|
|
238
|
+
if (includeBalance) {
|
|
239
|
+
balance = familyBalance(encoded.families);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Assemble the vector
|
|
244
|
+
const channels = {
|
|
245
|
+
quantized: quant.trits,
|
|
246
|
+
sst: sstTrits,
|
|
247
|
+
balance,
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// Calculate total dimensions
|
|
251
|
+
let dimensions = quant.trits.length;
|
|
252
|
+
if (sstTrits) dimensions += sstTrits.length;
|
|
253
|
+
if (balance) dimensions += 3; // a_ratio, b_ratio, c_ratio as trits
|
|
254
|
+
|
|
255
|
+
// Pack into Float32Array for ONNX compatibility
|
|
256
|
+
const vector = new Float32Array(dimensions);
|
|
257
|
+
let offset = 0;
|
|
258
|
+
|
|
259
|
+
// Write quantized channel
|
|
260
|
+
for (let i = 0; i < quant.trits.length; i++) {
|
|
261
|
+
vector[offset++] = quant.trits[i];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Write SST channel
|
|
265
|
+
if (sstTrits) {
|
|
266
|
+
for (let i = 0; i < sstTrits.length; i++) {
|
|
267
|
+
vector[offset++] = sstTrits[i];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Write balance as ternary indicators
|
|
272
|
+
if (balance) {
|
|
273
|
+
const n = rawFeatures.length || 1;
|
|
274
|
+
vector[offset++] = quantizeToTrit((balance.a / n) - (1/3), 0.1);
|
|
275
|
+
vector[offset++] = quantizeToTrit((balance.b / n) - (1/3), 0.1);
|
|
276
|
+
vector[offset++] = quantizeToTrit((balance.c / n) - (1/3), 0.1);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return { vector, channels, dimensions };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// =============================================================================
|
|
283
|
+
// TERNARY INFERENCE ADAPTER
|
|
284
|
+
// =============================================================================
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* TernaryInferenceAdapter — Routes ternary-quantized features through
|
|
288
|
+
* the ACCEL inference engine (NPU → GPU → CPU).
|
|
289
|
+
*
|
|
290
|
+
* This adapter sits between the ternary quantization layer and the
|
|
291
|
+
* ONNX models, providing:
|
|
292
|
+
* - Ternary feature encoding
|
|
293
|
+
* - Model-specific input formatting
|
|
294
|
+
* - Output trit classification
|
|
295
|
+
* - Consensus-based multi-model voting
|
|
296
|
+
*
|
|
297
|
+
* The adapter does NOT load models itself — it delegates to the
|
|
298
|
+
* shared inference engine from accel.js.
|
|
299
|
+
*/
|
|
300
|
+
export class TernaryInferenceAdapter {
|
|
301
|
+
/**
|
|
302
|
+
* @param {Object} inferenceEngine — accel.inference singleton
|
|
303
|
+
*/
|
|
304
|
+
constructor(inferenceEngine) {
|
|
305
|
+
this._engine = inferenceEngine;
|
|
306
|
+
this._stats = {
|
|
307
|
+
totalInferences: 0,
|
|
308
|
+
ternaryInputs: 0,
|
|
309
|
+
consensusVotes: 0,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Run ternary-quantized inference on a named model.
|
|
315
|
+
*
|
|
316
|
+
* @param {string} modelName — model loaded in inference engine
|
|
317
|
+
* @param {Float32Array | number[]} rawFeatures — raw float features
|
|
318
|
+
* @param {Object} [options]
|
|
319
|
+
* @param {boolean} [options.ternaryOutput=true] — quantize output to trits
|
|
320
|
+
* @param {number} [options.outputThreshold=0.33] — output quantization threshold
|
|
321
|
+
* @returns {Promise<{output: Float32Array|null, trits: Int8Array|null, raw: Object|null}>}
|
|
322
|
+
*/
|
|
323
|
+
async infer(modelName, rawFeatures, options = {}) {
|
|
324
|
+
const { ternaryOutput = true, outputThreshold = 0.33 } = options;
|
|
325
|
+
|
|
326
|
+
if (!this._engine || !this._engine.hasModel(modelName)) {
|
|
327
|
+
return { output: null, trits: null, raw: null };
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Build ternary feature vector
|
|
331
|
+
const { vector } = buildTernaryFeatureVector(rawFeatures);
|
|
332
|
+
|
|
333
|
+
this._stats.totalInferences++;
|
|
334
|
+
this._stats.ternaryInputs++;
|
|
335
|
+
|
|
336
|
+
// Run through ONNX via accel.inference
|
|
337
|
+
const raw = await this._engine.infer(modelName, { input: vector });
|
|
338
|
+
|
|
339
|
+
if (!raw) {
|
|
340
|
+
return { output: null, trits: null, raw: null };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Extract primary output
|
|
344
|
+
const outputKey = Object.keys(raw)[0];
|
|
345
|
+
const output = raw[outputKey];
|
|
346
|
+
|
|
347
|
+
// Optionally quantize output to trits
|
|
348
|
+
const trits = ternaryOutput ? quantizeArray(output, outputThreshold) : null;
|
|
349
|
+
|
|
350
|
+
return { output, trits, raw };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Run ternary consensus across multiple model outputs.
|
|
355
|
+
*
|
|
356
|
+
* Each model votes with its ternary output, and the final result
|
|
357
|
+
* uses TRIBHUJ majority logic — if no majority, NEUTRAL wins.
|
|
358
|
+
* This is inherently Byzantine-fault tolerant: a single compromised
|
|
359
|
+
* model can't override the consensus.
|
|
360
|
+
*
|
|
361
|
+
* @param {string[]} modelNames — models to query
|
|
362
|
+
* @param {Float32Array | number[]} rawFeatures — shared input
|
|
363
|
+
* @param {Object} [options] — per-model inference options
|
|
364
|
+
* @returns {Promise<{consensus: Int8Array, votes: Int8Array[], models: string[]}>}
|
|
365
|
+
*/
|
|
366
|
+
async consensusInfer(modelNames, rawFeatures, options = {}) {
|
|
367
|
+
const votes = [];
|
|
368
|
+
const activeModels = [];
|
|
369
|
+
|
|
370
|
+
// Collect votes from all available models
|
|
371
|
+
for (const name of modelNames) {
|
|
372
|
+
const result = await this.infer(name, rawFeatures, { ternaryOutput: true, ...options });
|
|
373
|
+
if (result.trits) {
|
|
374
|
+
votes.push(result.trits);
|
|
375
|
+
activeModels.push(name);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
this._stats.consensusVotes++;
|
|
380
|
+
|
|
381
|
+
if (votes.length === 0) {
|
|
382
|
+
return { consensus: null, votes: [], models: [] };
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Compute element-wise majority using TRIBHUJ
|
|
386
|
+
const outputLen = votes[0].length;
|
|
387
|
+
const consensus = new Int8Array(outputLen);
|
|
388
|
+
|
|
389
|
+
for (let i = 0; i < outputLen; i++) {
|
|
390
|
+
// Collect votes for this output position
|
|
391
|
+
const posVotes = votes.map(v => v[i] || 0);
|
|
392
|
+
const arr = new TritArray(posVotes);
|
|
393
|
+
consensus[i] = arr.majority().value;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return { consensus, votes, models: activeModels };
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Classify a trust score using ternary quantization.
|
|
401
|
+
* Maps KARMA-style trust to the three-state TRIBHUJ representation.
|
|
402
|
+
*
|
|
403
|
+
* @param {number} trustScore — 0.0 to 1.0
|
|
404
|
+
* @returns {{ trit: number, state: string, confidence: number }}
|
|
405
|
+
*/
|
|
406
|
+
classifyTrust(trustScore) {
|
|
407
|
+
// Map trust to balanced range [-1, +1]
|
|
408
|
+
const balanced = (trustScore * 2) - 1;
|
|
409
|
+
|
|
410
|
+
// Quantize with adaptive threshold
|
|
411
|
+
const trit = quantizeToTrit(balanced, 0.33);
|
|
412
|
+
|
|
413
|
+
// Confidence is distance from decision boundary
|
|
414
|
+
const confidence = Math.abs(balanced) > 0.33
|
|
415
|
+
? Math.min(1, (Math.abs(balanced) - 0.33) / 0.67)
|
|
416
|
+
: 0;
|
|
417
|
+
|
|
418
|
+
const stateMap = {
|
|
419
|
+
[NEGATIVE]: TritState.DISTRUST,
|
|
420
|
+
[NEUTRAL]: TritState.UNVERIFIED,
|
|
421
|
+
[POSITIVE]: TritState.TRUST,
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
return {
|
|
425
|
+
trit,
|
|
426
|
+
state: trit === NEGATIVE ? 'DISTRUST' : trit === POSITIVE ? 'TRUST' : 'UNVERIFIED',
|
|
427
|
+
confidence: +confidence.toFixed(3),
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Detect anomalies using ternary family balance.
|
|
433
|
+
*
|
|
434
|
+
* A healthy feature distribution has roughly equal A/B/C families.
|
|
435
|
+
* Significant skew indicates potential anomaly.
|
|
436
|
+
*
|
|
437
|
+
* @param {Float32Array | number[]} features
|
|
438
|
+
* @param {number} [anomalyThreshold=1.5] — balance score above this = anomaly
|
|
439
|
+
* @returns {{ isAnomaly: boolean, balanceScore: number, distribution: Object }}
|
|
440
|
+
*/
|
|
441
|
+
detectFamilyAnomaly(features, anomalyThreshold = 1.5) {
|
|
442
|
+
const encoded = sstEncodeFeatures(
|
|
443
|
+
Array.from(features).map(v => Math.round(Math.abs(v * 1000)))
|
|
444
|
+
);
|
|
445
|
+
const balance = familyBalance(encoded.families);
|
|
446
|
+
|
|
447
|
+
return {
|
|
448
|
+
isAnomaly: balance.balance > anomalyThreshold,
|
|
449
|
+
balanceScore: balance.balance,
|
|
450
|
+
distribution: { a: balance.a, b: balance.b, c: balance.c },
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Get adapter statistics.
|
|
456
|
+
* @returns {Object}
|
|
457
|
+
*/
|
|
458
|
+
getStats() {
|
|
459
|
+
return { ...this._stats };
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// =============================================================================
|
|
464
|
+
// EXPORTS
|
|
465
|
+
// =============================================================================
|
|
466
|
+
|
|
467
|
+
export default {
|
|
468
|
+
// Quantization
|
|
469
|
+
quantizeToTrit,
|
|
470
|
+
quantizeArray,
|
|
471
|
+
adaptiveQuantize,
|
|
472
|
+
dequantizeTrits,
|
|
473
|
+
|
|
474
|
+
// SST Feature Encoding
|
|
475
|
+
sstEncodeFeatures,
|
|
476
|
+
familyBalance,
|
|
477
|
+
buildTernaryFeatureVector,
|
|
478
|
+
|
|
479
|
+
// Inference Adapter
|
|
480
|
+
TernaryInferenceAdapter,
|
|
481
|
+
};
|