betterwithage Claude Opus 4.7 commited on
Commit
9c3ff39
·
verified ·
1 Parent(s): b6c8e60

deploy(hf): sync szl-holdings/a11oy@main derived COPY set

Browse files

Reusable Dockerfile-COPY-derived deploy from szl-holdings/a11oy main.
Files: 884 Pruned: 0
Derived from Dockerfile COPY sources (NO hand-maintained allowlist).

Signed-off-by: SZL Holdings <noreply@szlholdings.ai>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

static/3d/holographic.html CHANGED
@@ -160,6 +160,7 @@ const SURFACES = [
160
  { id: "ctxready", title: "Context-Ready Transformer", mod: "/static/3d/surfaces/ctxready.js" },
161
  { id: "opera", title: "OPERA Perplexity-Reward Alignment", mod: "/static/3d/surfaces/opera.js" },
162
  { id: "brain", title: "Formula-Graph Brain", mod: "/static/3d/surfaces/brain.js" },
 
163
  ];
164
 
165
  const stageEl = document.getElementById("stage");
 
160
  { id: "ctxready", title: "Context-Ready Transformer", mod: "/static/3d/surfaces/ctxready.js" },
161
  { id: "opera", title: "OPERA Perplexity-Reward Alignment", mod: "/static/3d/surfaces/opera.js" },
162
  { id: "brain", title: "Formula-Graph Brain", mod: "/static/3d/surfaces/brain.js" },
163
+ { id: "zkinfer", title: "zkML Proof-of-Inference (Cryptographic Receipts)", mod: "/static/3d/surfaces/zkinfer.js" },
164
  ];
165
 
166
  const stageEl = document.getElementById("stage");
static/3d/surfaces/zkinfer.js ADDED
@@ -0,0 +1,566 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // © 2026 Lutar, Stephen P. Jr. — SZL Holdings · ORCID 0009-0001-0110-4173 · Doctrine v11
3
+ //
4
+ // surfaces/zkinfer.js — zkML PROOF-OF-INFERENCE ("Cryptographic Receipts").
5
+ //
6
+ // The CRYPTOGRAPHIC-PROOF trust branch of verifiable inference — a prover (model host)
7
+ // emits a succinct zero-knowledge argument that a COMMITTED model produced a specific
8
+ // output, checkable against only a public weight commitment: no trusted hardware, no
9
+ // silicon vendor in the trust base. Orthogonal to the estate's TEE/hardware branch
10
+ // (ccattest, which trusts an enclave + vendor attestation service).
11
+ //
12
+ // DATA: live snapshot from the same-origin endpoint /api/a11oy/v1/frontier/zkinfer:
13
+ // label (MODELED, VERBATIM), proof_cost_model{ anchor_points[], cost_frontier{grid} },
14
+ // trust_model_matrix{ branches: crypto vs TEE }, micro_artifact{ label, verify_ok },
15
+ // doctrine{ trust_ceiling, lambda }, sources{}.
16
+ //
17
+ // VISUALIZES:
18
+ // 1. a layerwise prover→verifier PROOF-PACKET TUNNEL — stacked model-layer planes; a
19
+ // proof-teal packet travels layer-by-layer and collapses into a single small glyph at
20
+ // the verifier, whose size is scaled to the MODELED proof size (kB) — "succinct".
21
+ // 2. a COST-FRONTIER RIBBON — x = model size, y = sequence length, z = prover time, from
22
+ // the literature-parameterized grid; each cell MODELED (never a benchmark).
23
+ // 3. TRUST-BASE CONTRAST PILLARS — "cryptographic (this)" vs "TEE / ccattest"; the
24
+ // silicon-vendor node on the crypto pillar is GREYED-OUT (outside the trust base).
25
+ // 4. a LIVE ROUNDTRIP PULSE — when the real commit→prove→verify micro-artifact returns
26
+ // MEASURED, one proof-teal pulse fires prover→verifier; on HONEST-STUB it is dim grey
27
+ // and labeled STUB. No green "1.0 / VERIFIED" state anywhere.
28
+ //
29
+ // PRIMARY SOURCES (cited verbatim on-surface; IDs only — 0 runtime CDN, no URL fetch):
30
+ // zkLLM arXiv:2404.16109 (CCS'24) · Kang et al. arXiv:2210.08674 · ZKML EuroSys'24
31
+ // DOI 10.1145/3627703.3650088 · South et al. arXiv:2402.02675 · Peng et al. survey
32
+ // arXiv:2502.18535.
33
+ //
34
+ // HONESTY LABEL: MODELED — literature-parameterized cost model + trust matrix, explicitly
35
+ // NOT VERIFIED; no live LLM-scale proof is produced. The ONE narrowly MEASURED tile is the
36
+ // toy commit-verify roundtrip (plumbing only; reveals weights; not LLM-scale). Read
37
+ // VERBATIM from JSON; never upgraded here. Trust ceiling 0.97, NEVER 100%.
38
+ // COLOURS: lattice-blue 0x5b8dee, violet-blue 0x8a6bff (data-viz marker), proof-teal
39
+ // 0x3af4c8 (packet / MEASURED pulse), greys (pending / TEE / greyed vendor / STUB).
40
+ // PURPLE BANNED. No green/1.0 verified state.
41
+ // 0 RUNTIME CDN. Vendored three.js r170 via page importmap (ctx.THREE).
42
+ // DOCTRINE v11: adds NOTHING to the locked-8 {F1,F4,F7,F11,F12,F18,F19,F22} @ c7c0ba17;
43
+ // Λ stays Conjecture 1; introduces no theorem. Degrades grey on 404/error; label shown.
44
+
45
+ const ID = "zkinfer";
46
+ const TITLE = "zkML Proof-of-Inference · Cryptographic Receipts (live)";
47
+
48
+ // same-origin, relative — no CDN, no cross-origin fetch.
49
+ const EP = "/api/a11oy/v1/frontier/zkinfer";
50
+
51
+ // data-viz hues — purple BANNED, no green
52
+ const C_LAYER = 0x5b8dee; // lattice-blue (model-layer planes, tunnel body)
53
+ const C_PACKET = 0x3af4c8; // proof-teal (proof packet / MEASURED roundtrip pulse)
54
+ const C_MARKER = 0x8a6bff; // violet-blue (verifier glyph / data-viz marker)
55
+ const C_DIM = 0x42505d; // grey (pending / greyed vendor / STUB / no-live-data)
56
+ const C_GRID = 0x1b3a44; // floor / link colour
57
+ const C_RIBBON = 0x5b8dee; // lattice-blue (cost ribbon base)
58
+
59
+ // tunnel geometry
60
+ const N_LAYERS = 7; // stacked model-layer planes
61
+ const LAYER_GAP = 1.4; // world-units between layers along z
62
+ const LAYER_W = 3.2; // plane width/height
63
+
64
+ let _stage = null, _THREE = null, _ctx = null, _group = null, _overlay = null;
65
+ let _frameReg = false, _polls = [], _el = {}, _badge = null, _plain = false;
66
+
67
+ // geometry handles
68
+ let _layers = []; // Array<THREE.Mesh> — stacked layer planes (prover -> verifier)
69
+ let _packet = null; // THREE.Mesh — traveling proof packet
70
+ let _verifier = null; // THREE.Mesh — verifier glyph (collapses proof to a small object)
71
+ let _ribbon = null; // THREE.Mesh — cost-frontier surface
72
+ let _pillars = []; // Array<{ mesh, node }> — trust-base contrast pillars
73
+ let _floor = null;
74
+ let _pulseT = -1; // >=0 while a roundtrip pulse is animating
75
+
76
+ // live state (all read from JSON; nothing invented)
77
+ const S = {
78
+ label: null, // top honesty label VERBATIM (MODELED)
79
+ notVerified: null,
80
+ microLabel: null, // MEASURED | HONEST-STUB
81
+ verifyOk: null,
82
+ proofKb: null, // modeled proof size (kB)
83
+ anchorTime: null, // zkLLM anchor prover time (s)
84
+ trustCeil: null,
85
+ lambda: null,
86
+ grid: null, // prover_time_grid_s rows
87
+ seqAxis: null,
88
+ paramsAxis: null,
89
+ cryptoTCB: null, // trusted_hardware_in_TCB for crypto branch (false)
90
+ teeTCB: null, // trusted_hardware_in_TCB for TEE branch (true)
91
+ state: "init",
92
+ };
93
+
94
+ // =============================================================================
95
+ // mount(ctx)
96
+ // =============================================================================
97
+ export function mount(ctx) {
98
+ _ctx = ctx; _stage = ctx.stage; _THREE = ctx.THREE;
99
+ _group = new _THREE.Group();
100
+ _stage.scene.add(_group);
101
+ _stage.camera.position.set(9, 6, 15);
102
+ try { if (_stage.controls && _stage.controls.target) { _stage.controls.target.set(0, 1.5, 0); _stage.controls.update(); } } catch (_) {}
103
+ try { _stage.setBloom(true); } catch (_) {}
104
+
105
+ _buildFloor();
106
+ _buildTunnel();
107
+ _buildRibbon();
108
+ _buildPillars();
109
+
110
+ if (!_frameReg) { _stage.onFrame(_onFrame); _frameReg = true; }
111
+
112
+ _badge = ctx.live.createBadge();
113
+ _polls.push(ctx.live.poll(EP, 6000, _onData, {
114
+ badge: _badge, onState: (m) => { S.state = m.state; _paintOverlay(); },
115
+ }));
116
+
117
+ _buildOverlay();
118
+ return { id: ID, started: true };
119
+ }
120
+
121
+ // =============================================================================
122
+ // builders
123
+ // =============================================================================
124
+ function _buildFloor() {
125
+ const THREE = _THREE;
126
+ const grid = new THREE.GridHelper(40, 40, C_GRID, 0x0f2027);
127
+ grid.material.opacity = 0.16; grid.material.transparent = true; grid.position.y = -0.01;
128
+ _group.add(grid);
129
+ _floor = grid;
130
+ }
131
+
132
+ // Prover (z-) -> Verifier (z+): stacked translucent model-layer planes forming a tunnel,
133
+ // plus a traveling proof packet and the collapsing verifier glyph.
134
+ function _buildTunnel() {
135
+ const THREE = _THREE;
136
+ const planeGeo = new THREE.PlaneGeometry(LAYER_W, LAYER_W);
137
+ const z0 = -((N_LAYERS - 1) * LAYER_GAP) / 2;
138
+
139
+ for (let i = 0; i < N_LAYERS; i++) {
140
+ const mat = new THREE.MeshStandardMaterial({
141
+ color: C_LAYER, emissive: C_LAYER, emissiveIntensity: 0.12,
142
+ transparent: true, opacity: 0.16, side: THREE.DoubleSide, wireframe: false,
143
+ });
144
+ const mesh = new THREE.Mesh(planeGeo, mat);
145
+ mesh.position.set(-6, 1.6, z0 + i * LAYER_GAP);
146
+ _group.add(mesh);
147
+ // frame outline (wire) so layers read as discrete stages
148
+ const wire = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({
149
+ color: C_LAYER, transparent: true, opacity: 0.28, wireframe: true, side: THREE.DoubleSide,
150
+ }));
151
+ wire.position.copy(mesh.position);
152
+ _group.add(wire);
153
+ _layers.push(mesh);
154
+ }
155
+
156
+ // proof packet — small proof-teal octahedron traveling prover->verifier
157
+ _packet = new THREE.Mesh(
158
+ new THREE.OctahedronGeometry(0.28, 0),
159
+ new THREE.MeshStandardMaterial({ color: C_PACKET, emissive: C_PACKET, emissiveIntensity: 0.6, transparent: true, opacity: 0.95 }),
160
+ );
161
+ _packet.position.set(-6, 1.6, z0);
162
+ _group.add(_packet);
163
+
164
+ // verifier glyph — small violet-blue icosahedron at the +z end; its scale reflects the
165
+ // MODELED proof size (succinct => small). Starts modest; updated from live data.
166
+ _verifier = new THREE.Mesh(
167
+ new THREE.IcosahedronGeometry(0.5, 0),
168
+ new THREE.MeshStandardMaterial({ color: C_MARKER, emissive: C_MARKER, emissiveIntensity: 0.35, transparent: true, opacity: 0.9, wireframe: true }),
169
+ );
170
+ _verifier.position.set(-6, 1.6, z0 + (N_LAYERS - 1) * LAYER_GAP + 1.4);
171
+ _group.add(_verifier);
172
+ }
173
+
174
+ // Cost-frontier ribbon: a plane whose vertices are displaced in Y by MODELED prover time
175
+ // over (model size × sequence length). Colored lattice-blue at low cost -> proof-teal high.
176
+ function _buildRibbon() {
177
+ const THREE = _THREE;
178
+ const segX = 5, segZ = 4; // default until live grid arrives (6 params × 5 seq)
179
+ const geo = new THREE.PlaneGeometry(7, 6, segX, segZ);
180
+ geo.rotateX(-Math.PI / 2);
181
+ const mat = new THREE.MeshStandardMaterial({
182
+ color: C_RIBBON, emissive: C_RIBBON, emissiveIntensity: 0.18,
183
+ transparent: true, opacity: 0.55, side: THREE.DoubleSide,
184
+ wireframe: false, flatShading: true,
185
+ vertexColors: true,
186
+ });
187
+ _ribbon = new THREE.Mesh(geo, mat);
188
+ _ribbon.position.set(6.5, 1.2, 0);
189
+ _group.add(_ribbon);
190
+
191
+ // baseline vertex colors (lattice-blue); recolored when live grid arrives.
192
+ const cnt = geo.attributes.position.count;
193
+ const colors = new Float32Array(cnt * 3);
194
+ const base = new THREE.Color(C_RIBBON);
195
+ for (let i = 0; i < cnt; i++) { colors[i * 3] = base.r; colors[i * 3 + 1] = base.g; colors[i * 3 + 2] = base.b; }
196
+ geo.setAttribute("color", new THREE.BufferAttribute(colors, 3));
197
+ }
198
+
199
+ // Trust-base contrast pillars: crypto (this surface) vs TEE (ccattest). The crypto pillar's
200
+ // silicon-vendor node is greyed-out to show it is OUTSIDE the trust base.
201
+ function _buildPillars() {
202
+ const THREE = _THREE;
203
+ const pillarGeo = new THREE.CylinderGeometry(0.55, 0.55, 3.4, 20, 1, true);
204
+ const nodeGeo = new THREE.SphereGeometry(0.32, 16, 12);
205
+
206
+ const specs = [
207
+ { x: -1.4, color: C_PACKET, vendorGrey: true, name: "crypto" }, // this surface
208
+ { x: 1.4, color: C_LAYER, vendorGrey: false, name: "tee" }, // ccattest
209
+ ];
210
+ for (const sp of specs) {
211
+ const mesh = new THREE.Mesh(pillarGeo, new THREE.MeshStandardMaterial({
212
+ color: sp.color, emissive: sp.color, emissiveIntensity: 0.14,
213
+ transparent: true, opacity: 0.28, side: THREE.DoubleSide, wireframe: true,
214
+ }));
215
+ mesh.position.set(sp.x, 1.9, 7.5);
216
+ _group.add(mesh);
217
+ // "silicon-vendor node" at pillar top — greyed on the crypto pillar (not in TCB).
218
+ const nodeColor = sp.vendorGrey ? C_DIM : C_MARKER;
219
+ const node = new THREE.Mesh(nodeGeo, new THREE.MeshStandardMaterial({
220
+ color: nodeColor, emissive: nodeColor,
221
+ emissiveIntensity: sp.vendorGrey ? 0.08 : 0.4,
222
+ transparent: true, opacity: sp.vendorGrey ? 0.35 : 0.9,
223
+ }));
224
+ node.position.set(sp.x, 3.9, 7.5);
225
+ _group.add(node);
226
+ _pillars.push({ mesh, node });
227
+ }
228
+ }
229
+
230
+ // =============================================================================
231
+ // live data handler — read VERBATIM, never upgrade
232
+ // =============================================================================
233
+ function _onData(j) {
234
+ S.label = (j.label || "MODELED").toUpperCase();
235
+ S.notVerified = j.not_verified === true;
236
+
237
+ const pcm = j.proof_cost_model || {};
238
+ const cf = pcm.cost_frontier || {};
239
+ S.grid = Array.isArray(cf.prover_time_grid_s) ? cf.prover_time_grid_s : null;
240
+ S.seqAxis = cf.axes && Array.isArray(cf.axes.seq_len) ? cf.axes.seq_len : null;
241
+ S.paramsAxis = cf.axes && Array.isArray(cf.axes.params_b) ? cf.axes.params_b : null;
242
+ S.proofKb = cf.proof_size_kb_modeled && typeof cf.proof_size_kb_modeled.value === "number"
243
+ ? cf.proof_size_kb_modeled.value : null;
244
+ S.anchorTime = cf.anchor && typeof cf.anchor.prover_time_s === "number"
245
+ ? cf.anchor.prover_time_s : null;
246
+
247
+ const ma = j.micro_artifact || {};
248
+ S.microLabel = typeof ma.label === "string" ? ma.label.toUpperCase() : null;
249
+ S.verifyOk = typeof ma.verify_ok === "boolean" ? ma.verify_ok : null;
250
+
251
+ const d = j.doctrine || {};
252
+ S.trustCeil = typeof d.trust_ceiling === "number" ? d.trust_ceiling : null;
253
+ S.lambda = typeof d.lambda === "string" ? d.lambda : null;
254
+
255
+ const br = (j.trust_model_matrix || {}).branches || {};
256
+ const crypto = br["cryptographic_zkml (this surface)"] || {};
257
+ const tee = br["tee_attestation (ccattest)"] || {};
258
+ S.cryptoTCB = typeof crypto.trusted_hardware_in_TCB === "boolean" ? crypto.trusted_hardware_in_TCB : null;
259
+ S.teeTCB = typeof tee.trusted_hardware_in_TCB === "boolean" ? tee.trusted_hardware_in_TCB : null;
260
+
261
+ _updateVerifier();
262
+ _updateRibbon();
263
+ _updatePillars();
264
+ // fire a roundtrip pulse only when the real micro-artifact actually reconciled.
265
+ if (S.microLabel === "MEASURED" && S.verifyOk === true) _pulseT = 0;
266
+ _paintOverlay();
267
+ }
268
+
269
+ // verifier glyph scale reflects MODELED proof size (succinct => small).
270
+ function _updateVerifier() {
271
+ if (!_verifier) return;
272
+ const live = S.state === "live";
273
+ if (live && S.proofKb != null) {
274
+ // map ~200 kB -> small glyph; keep it visibly "succinct".
275
+ const s = Math.max(0.3, Math.min(0.9, 0.3 + (S.proofKb / 200) * 0.4));
276
+ _verifier.scale.setScalar(s);
277
+ _verifier.material.color.setHex(C_MARKER);
278
+ _verifier.material.emissive.setHex(C_MARKER);
279
+ _verifier.material.opacity = 0.9;
280
+ } else {
281
+ _verifier.scale.setScalar(0.5);
282
+ _verifier.material.color.setHex(C_DIM);
283
+ _verifier.material.emissive.setHex(C_DIM);
284
+ _verifier.material.opacity = 0.3;
285
+ }
286
+ }
287
+
288
+ // recolor + displace the ribbon from the live MODELED prover-time grid.
289
+ function _updateRibbon() {
290
+ if (!_ribbon || !_ribbon.geometry) return;
291
+ const THREE = _THREE;
292
+ const geo = _ribbon.geometry;
293
+ const pos = geo.attributes.position;
294
+ const col = geo.attributes.color;
295
+ const live = S.state === "live" && S.grid && S.grid.length;
296
+
297
+ if (!live) {
298
+ // flat + dim grey when no live data
299
+ for (let i = 0; i < pos.count; i++) {
300
+ pos.setY(i, 0);
301
+ col.setXYZ(i, 0.26, 0.31, 0.36);
302
+ }
303
+ pos.needsUpdate = true; col.needsUpdate = true; geo.computeVertexNormals();
304
+ return;
305
+ }
306
+
307
+ // grid rows = params (X), cols = seq (Z). PlaneGeometry has (segX+1)*(segZ+1) verts.
308
+ const rows = S.grid; // [{params_b, prover_time_s:[...]}]
309
+ const nX = rows.length; // params count
310
+ const nZ = rows[0].prover_time_s.length; // seq count
311
+ // find max for normalization
312
+ let mx = 1;
313
+ for (const r of rows) for (const v of r.prover_time_s) if (v > mx) mx = v;
314
+
315
+ const lo = new THREE.Color(C_RIBBON); // lattice-blue (low cost)
316
+ const hi = new THREE.Color(C_PACKET); // proof-teal (high cost)
317
+ const segX = geo.parameters.widthSegments;
318
+ const segZ = geo.parameters.heightSegments;
319
+
320
+ for (let ix = 0; ix <= segX; ix++) {
321
+ for (let iz = 0; iz <= segZ; iz++) {
322
+ const vi = ix * (segZ + 1) + iz;
323
+ const gx = Math.min(nX - 1, Math.round((ix / segX) * (nX - 1)));
324
+ const gz = Math.min(nZ - 1, Math.round((iz / segZ) * (nZ - 1)));
325
+ const t = rows[gx].prover_time_s[gz] / mx; // 0..1 normalized cost
326
+ pos.setY(vi, t * 2.4); // z = prover time (height)
327
+ const c = lo.clone().lerp(hi, t);
328
+ col.setXYZ(vi, c.r, c.g, c.b);
329
+ }
330
+ }
331
+ pos.needsUpdate = true; col.needsUpdate = true; geo.computeVertexNormals();
332
+ }
333
+
334
+ function _updatePillars() {
335
+ if (_pillars.length < 2) return;
336
+ const live = S.state === "live";
337
+ // crypto pillar[0]: vendor node greyed iff crypto TCB has NO trusted hardware (expected).
338
+ const cryptoGrey = S.cryptoTCB === false || S.cryptoTCB == null;
339
+ const cNode = _pillars[0].node;
340
+ cNode.material.color.setHex(cryptoGrey ? C_DIM : C_MARKER);
341
+ cNode.material.emissive.setHex(cryptoGrey ? C_DIM : C_MARKER);
342
+ cNode.material.emissiveIntensity = cryptoGrey ? 0.08 : 0.4;
343
+ cNode.material.opacity = cryptoGrey ? 0.35 : 0.9;
344
+ // TEE pillar[1]: vendor node lit iff TEE TCB includes trusted hardware (expected true).
345
+ const teeLit = S.teeTCB === true;
346
+ const tNode = _pillars[1].node;
347
+ tNode.material.color.setHex(teeLit ? C_MARKER : C_DIM);
348
+ tNode.material.emissive.setHex(teeLit ? C_MARKER : C_DIM);
349
+ tNode.material.emissiveIntensity = teeLit ? 0.4 : 0.1;
350
+ tNode.material.opacity = teeLit ? 0.9 : 0.4;
351
+ if (!live) {
352
+ _pillars.forEach((p) => { p.mesh.material.opacity = 0.14; });
353
+ } else {
354
+ _pillars.forEach((p) => { p.mesh.material.opacity = 0.28; });
355
+ }
356
+ }
357
+
358
+ // =============================================================================
359
+ // per-frame animation
360
+ // =============================================================================
361
+ function _onFrame() {
362
+ const t = performance.now();
363
+ if (_group) _group.rotation.y = Math.sin(t * 0.00007) * 0.10;
364
+ if (_verifier) { _verifier.rotation.y += 0.02; _verifier.rotation.x += 0.006; }
365
+
366
+ // proof packet travels prover -> verifier along the tunnel, looping.
367
+ if (_packet && _layers.length) {
368
+ const z0 = _layers[0].position.z;
369
+ const z1 = _verifier ? _verifier.position.z : _layers[_layers.length - 1].position.z;
370
+ const phase = (t * 0.00035) % 1;
371
+ _packet.position.z = z0 + (z1 - z0) * phase;
372
+ _packet.rotation.y += 0.05;
373
+ const live = S.state === "live";
374
+ _packet.material.color.setHex(live ? C_PACKET : C_DIM);
375
+ _packet.material.emissive.setHex(live ? C_PACKET : C_DIM);
376
+ _packet.material.opacity = live ? 0.95 : 0.35;
377
+ // light the layer the packet is currently passing through
378
+ for (let i = 0; i < _layers.length; i++) {
379
+ const near = Math.abs(_layers[i].position.z - _packet.position.z) < LAYER_GAP * 0.6;
380
+ _layers[i].material.opacity = live ? (near ? 0.4 : 0.16) : 0.1;
381
+ }
382
+ }
383
+
384
+ // live roundtrip pulse: a single proof-teal (MEASURED) or dim-grey (STUB) surge on the
385
+ // verifier glyph when the real micro-artifact returns. NEVER a green/1.0 state.
386
+ if (_pulseT >= 0 && _verifier) {
387
+ _pulseT += 0.02;
388
+ const measured = S.microLabel === "MEASURED" && S.verifyOk === true;
389
+ const c = measured ? C_PACKET : C_DIM;
390
+ _verifier.material.emissive.setHex(c);
391
+ _verifier.material.emissiveIntensity = 0.35 + 0.5 * Math.max(0, Math.sin(_pulseT * Math.PI));
392
+ if (_pulseT >= 1) { _pulseT = -1; _verifier.material.emissiveIntensity = 0.35; }
393
+ }
394
+ }
395
+
396
+ // =============================================================================
397
+ // overlay (HUD)
398
+ // =============================================================================
399
+ function _buildOverlay() {
400
+ const ctx = _ctx;
401
+ _overlay = document.createElement("div");
402
+ Object.assign(_overlay.style, {
403
+ position: "absolute", left: "14px", top: "14px", zIndex: "6",
404
+ display: "flex", flexDirection: "column", gap: "8px",
405
+ maxWidth: "min(94%,460px)",
406
+ font: "12px ui-sans-serif,system-ui,Segoe UI,Roboto,Arial", color: "#eef3f6",
407
+ });
408
+
409
+ const h = document.createElement("div");
410
+ h.style.cssText = "font:600 13px ui-sans-serif,system-ui;letter-spacing:.4px";
411
+ h.textContent = TITLE;
412
+ _overlay.appendChild(h);
413
+
414
+ const sub = document.createElement("div");
415
+ sub.style.cssText = "color:#9fb1bf;font-size:11px;line-height:1.55";
416
+ sub.innerHTML =
417
+ 'The <b>cryptographic-proof</b> trust branch of verifiable inference: a succinct ' +
418
+ '<b>zero-knowledge</b> argument that a <b>committed</b> model produced a specific output, ' +
419
+ 'checkable against only a public weight commitment — <b>no trusted hardware, no ' +
420
+ 'vendor in the trust base</b>. Orthogonal to the estate’s TEE branch (ccattest). ' +
421
+ 'Honesty label <b>MODELED</b> — literature-parameterized cost model, explicitly ' +
422
+ '<b>NOT VERIFIED</b>; no live LLM-scale proof is produced. 0 runtime CDN.';
423
+ _overlay.appendChild(sub);
424
+
425
+ const brow = document.createElement("div");
426
+ brow.style.cssText = "display:flex;gap:8px;align-items:center;flex-wrap:wrap";
427
+ if (_badge && _badge.el) brow.appendChild(_badge.el);
428
+ _overlay.appendChild(brow);
429
+
430
+ const card = document.createElement("div");
431
+ card.style.cssText = "background:#0a1117;border:1px solid #1d2a36;border-radius:9px;padding:9px 10px;display:flex;flex-direction:column;gap:6px";
432
+
433
+ const chead = document.createElement("div");
434
+ chead.style.cssText = "display:flex;align-items:center;gap:8px;flex-wrap:wrap";
435
+ const dot = document.createElement("span");
436
+ dot.style.cssText = "width:9px;height:9px;border-radius:50%;background:#5b8dee;box-shadow:0 0 7px #5b8dee";
437
+ const nm = document.createElement("b");
438
+ nm.style.cssText = "font-size:12px;color:#5b8dee;letter-spacing:.3px";
439
+ nm.textContent = "zkinfer";
440
+ chead.appendChild(dot); chead.appendChild(nm);
441
+ card.appendChild(chead);
442
+
443
+ const grid = document.createElement("div");
444
+ grid.style.cssText = "display:grid;grid-template-columns:1fr;gap:4px";
445
+ function kpiRow(id, label) {
446
+ const r = document.createElement("div");
447
+ r.style.cssText = "display:flex;justify-content:space-between;gap:10px;font-size:11px";
448
+ const l = document.createElement("span"); l.style.cssText = "color:#9fb1bf"; l.textContent = label;
449
+ const v = document.createElement("b");
450
+ v.id = id;
451
+ v.style.cssText = "font-variant-numeric:tabular-nums;color:#eef3f6;text-align:right;max-width:62%;overflow-wrap:anywhere";
452
+ v.textContent = "—";
453
+ _el[id] = v;
454
+ r.appendChild(l); r.appendChild(v); return r;
455
+ }
456
+ grid.appendChild(kpiRow("zk-label", "honesty label (top)"));
457
+ grid.appendChild(kpiRow("zk-anchor", "prover time · zkLLM 13B (MODELED)"));
458
+ grid.appendChild(kpiRow("zk-proof", "proof size (MODELED, succinct)"));
459
+ grid.appendChild(kpiRow("zk-micro", "commit→verify roundtrip"));
460
+ grid.appendChild(kpiRow("zk-tcb", "trusted hardware in TCB (crypto)"));
461
+ grid.appendChild(kpiRow("zk-trust", "trust ceiling"));
462
+ grid.appendChild(kpiRow("zk-lambda", "Λ"));
463
+ card.appendChild(grid);
464
+
465
+ const fn = document.createElement("div");
466
+ fn.style.cssText = "font-size:9.5px;color:#6b7a86;line-height:1.5";
467
+ fn.textContent =
468
+ "Sources: zkLLM arXiv:2404.16109 (CCS’24) · Kang et al. arXiv:2210.08674 · " +
469
+ "ZKML EuroSys’24 DOI 10.1145/3627703.3650088 · South et al. arXiv:2402.02675 · " +
470
+ "Peng et al. survey arXiv:2502.18535. MODELED · not verified.";
471
+ card.appendChild(fn);
472
+ _overlay.appendChild(card);
473
+
474
+ const pl = document.createElement("button");
475
+ pl.textContent = "◑ what this means";
476
+ pl.title = "Toggle plain-language explanation for investors & consumers.";
477
+ pl.style.cssText = "font:11px ui-monospace,monospace;padding:5px 11px;border-radius:7px;border:1px solid #3af4c8;background:#08140f;color:#3af4c8;cursor:pointer;width:fit-content";
478
+ pl.addEventListener("click", () => {
479
+ _plain = !_plain;
480
+ pl.style.background = _plain ? "#0f2a20" : "#08140f";
481
+ _applyPlain();
482
+ });
483
+ _overlay.appendChild(pl);
484
+
485
+ const pd = document.createElement("div");
486
+ pd.id = "zk-plain";
487
+ pd.style.cssText = "font-size:10.5px;color:#c9d6df;line-height:1.55;border:1px dashed #26333f;border-radius:7px;padding:7px 9px;display:none";
488
+ _el["plain"] = pd;
489
+ _overlay.appendChild(pd);
490
+
491
+ (ctx.container || document.body).appendChild(_overlay);
492
+ _paintOverlay();
493
+ }
494
+
495
+ function _applyPlain() {
496
+ const pd = _el["plain"];
497
+ if (!pd) return;
498
+ pd.style.display = _plain ? "block" : "none";
499
+ if (!_plain) return;
500
+ const micro = S.microLabel === "MEASURED" && S.verifyOk === true
501
+ ? "really ran and reconciled just now"
502
+ : (S.microLabel === "HONEST-STUB" ? "is an honest stub (did not run)" : "loading…");
503
+ pd.innerHTML =
504
+ "<b>What this means:</b> zkML lets a model host prove — with a small math object " +
505
+ "anyone can check — that a <b>specific committed model</b> produced a given output, " +
506
+ "<b>without revealing the weights</b> and <b>without the checker re-running the model</b>. " +
507
+ "That is the cryptographic cousin of a hardware attestation (the estate’s ccattest " +
508
+ "tab): instead of trusting a chip vendor, you trust <b>standard math assumptions</b>. " +
509
+ "This tab shows <b>MODELED</b> costs read from five real papers (prover time, proof size, " +
510
+ "verify time) — it is <b>NOT a live proof</b> and never shows a “verified/1.0” " +
511
+ "state. The one genuinely-run piece is a tiny <b>commit→prove→verify roundtrip</b> " +
512
+ "computed on the server (it " + micro + "); it proves the <b>plumbing</b> is real, not " +
513
+ "that it scales to an LLM. Plain: honest cost map + trust contrast + one real toy check, " +
514
+ "clearly labeled, no overclaim.";
515
+ }
516
+
517
+ function _tok(s) {
518
+ if (s === "live") return null;
519
+ if (s === "missing") return "NO-LIVE-DATA";
520
+ if (s === "degraded") return "DEGRADED";
521
+ if (s === "error") return "OFFLINE";
522
+ return "…";
523
+ }
524
+ function _set(id, v) { if (_el[id]) _el[id].textContent = v; }
525
+ function _fmtTime(s) { return s == null ? "—" : (s >= 60 ? (s / 60).toFixed(1) + " min" : s + " s"); }
526
+
527
+ function _paintOverlay() {
528
+ const t = _tok(S.state);
529
+ _set("zk-label", t || (S.label || "MODELED"));
530
+ _set("zk-anchor", t || (S.anchorTime != null ? "< " + _fmtTime(S.anchorTime) : "—"));
531
+ _set("zk-proof", t || (S.proofKb != null ? "< " + S.proofKb + " kB" : "—"));
532
+ _set("zk-micro", t || (S.microLabel ? (S.microLabel + (S.verifyOk === true ? " · verify_ok" : "")) : "—"));
533
+ _set("zk-tcb", t || (S.cryptoTCB === false ? "false (none)" : (S.cryptoTCB === true ? "true" : "—")));
534
+ _set("zk-trust", t || (S.trustCeil != null ? String(S.trustCeil) : "—"));
535
+ _set("zk-lambda", t || (S.lambda || "—"));
536
+ if (_plain) _applyPlain();
537
+ }
538
+
539
+ // =============================================================================
540
+ // unmount — dispose everything; must not affect other organs
541
+ // =============================================================================
542
+ export function unmount() {
543
+ _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
544
+ try { if (_overlay && _overlay.parentNode) _overlay.parentNode.removeChild(_overlay); } catch (_) {}
545
+ try {
546
+ if (_group && _stage) {
547
+ _group.traverse((o) => {
548
+ if (o.geometry && o.geometry.dispose) o.geometry.dispose();
549
+ if (o.material) {
550
+ const ms = Array.isArray(o.material) ? o.material : [o.material];
551
+ ms.forEach((mm) => { if (mm.dispose) mm.dispose(); });
552
+ }
553
+ });
554
+ _stage.scene.remove(_group);
555
+ }
556
+ } catch (_) {}
557
+ _group = _overlay = null;
558
+ _layers = []; _packet = null; _verifier = null; _ribbon = null; _pillars = []; _floor = null;
559
+ _el = {}; _badge = null; _plain = false; _frameReg = false; _pulseT = -1;
560
+ _stage = _THREE = _ctx = null;
561
+ S.label = S.notVerified = S.microLabel = S.verifyOk = S.proofKb = S.anchorTime = null;
562
+ S.trustCeil = S.lambda = S.grid = S.seqAxis = S.paramsAxis = S.cryptoTCB = S.teeTCB = null;
563
+ S.state = "init";
564
+ }
565
+
566
+ export default { id: ID, title: TITLE, endpoints: [EP], mount, unmount };