betterwithage Claude Opus 4.7 commited on
Commit
998a0ae
·
verified ·
1 Parent(s): feb7728

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

Browse files

Reusable Dockerfile-COPY-derived deploy from szl-holdings/a11oy main.
Files: 978 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
@@ -218,6 +218,7 @@ const SURFACES = [
218
  { id: "mesh", cat: "defense", title: "Sovereign Mesh · Cross-Node Orchestration (status/route/quorum)", mod: "/static/3d/surfaces/mesh.js" },
219
  { id: "agenttts", cat: "reasoning", title: "Agent Test-Time Compute · Multi-Agent TTC (live)", mod: "/static/3d/surfaces/agenttts.js" },
220
  { id: "cryptopipeline", cat: "proof", title: "Crypto-Pipeline · End-to-End AI Lifecycle Verifiable Transcript (MODELED)", mod: "/static/3d/surfaces/cryptopipeline.js" },
 
221
  ];
222
 
223
  const stageEl = document.getElementById("stage");
 
218
  { id: "mesh", cat: "defense", title: "Sovereign Mesh · Cross-Node Orchestration (status/route/quorum)", mod: "/static/3d/surfaces/mesh.js" },
219
  { id: "agenttts", cat: "reasoning", title: "Agent Test-Time Compute · Multi-Agent TTC (live)", mod: "/static/3d/surfaces/agenttts.js" },
220
  { id: "cryptopipeline", cat: "proof", title: "Crypto-Pipeline · End-to-End AI Lifecycle Verifiable Transcript (MODELED)", mod: "/static/3d/surfaces/cryptopipeline.js" },
221
+ { id: "gateddelta", cat: "attention", title: "Gated Delta-Rule Linear Attention · state recall (MODELED)", mod: "/static/3d/surfaces/gateddelta.js" },
222
  ];
223
 
224
  const stageEl = document.getElementById("stage");
static/3d/surfaces/gateddelta.js ADDED
@@ -0,0 +1,401 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // © 2026 Lutar, Stephen P. — SZL Holdings · ORCID 0009-0001-0110-4173 · Doctrine v11
3
+ //
4
+ // surfaces/gateddelta.js — GATED DELTA-RULE LINEAR ATTENTION organ for the
5
+ // holographic frontier ring. Renders the associative-memory "register file" of a
6
+ // linear-attention layer: one node per register (key), lit by how well each update
7
+ // rule recalls that register's LAST written value. Delta-rule registers glow
8
+ // proof-teal (near-exact in-place overwrite), gated-delta registers glow lattice-
9
+ // blue (direction kept, magnitude adaptively decayed), and plain linear-attention
10
+ // error rises as a grey column (writes accumulate, overwrites collide). A HUD shows
11
+ // per-policy recall error / cosine, the gate retention, and the chunk-parallel
12
+ // invariant (chunked delta state == sequential state) from the live snapshot at
13
+ // /api/a11oy/v1/gateddelta/recall. Honesty label "MODELED" is read VERBATIM from
14
+ // the JSON and displayed as-is; it is never upgraded.
15
+ //
16
+ // Surface export shape (mirrors kvcache.js / testtime.js exactly):
17
+ // export default { id, title, endpoints, mount(ctx), unmount() }
18
+ // ctx = { stage, container, live, label, THREE, szl3d }
19
+ //
20
+ // DATA SHOWN (all from live endpoint):
21
+ // seq_len, dim, n_keys, chunk, gate, beta, n_overwrites,
22
+ // linear_recall_error, delta_recall_error, gated_recall_error,
23
+ // linear_recall_cos, delta_recall_cos, gated_recall_cos, gated_retention,
24
+ // delta_vs_linear_gain, chunk_max_state_diff, state_track_acc{}, per_register[]
25
+ //
26
+ // LEADERS ADOPTED & CITED (clean-room; NOT claimed as SZL's own; VERIFY real):
27
+ // Gated DeltaNet — Yang, Kautz, Hatamizadeh 2024, arXiv:2412.06464
28
+ // Parallel Delta Rule — Yang et al. 2024, arXiv:2406.06484
29
+ // DeltaProduct (state-tracking) — Siems et al. 2025, arXiv:2502.10297
30
+ // GLA — Yang et al. 2023, arXiv:2312.06635
31
+ //
32
+ // HONESTY LABELS: MODELED (deterministic simulation of the delta-rule / gated-delta
33
+ // / linear-attention state updates over a synthetic key/value write trace; NOT a
34
+ // real trained model or GPU). Read verbatim from JSON; never upgraded here.
35
+ // COLOURS: proof-teal 0x3af4c8 (delta rule / HUD accent), lattice-blue 0x5b8dee
36
+ // (gated delta), greys (linear-attention error / degraded state). Purple BANNED.
37
+ // 0 RUNTIME CDN. Vendored three.js r170 via page importmap.
38
+ // DOCTRINE v11: degrades gracefully (grey) on 404/error; honesty label still shown.
39
+ // Nothing here is in the locked-8. Λ stays Conjecture 1. Trust never 100%.
40
+
41
+ import { createShowcase } from "./_showcase.js";
42
+
43
+ const ID = "gateddelta";
44
+ const TITLE = "Gated Delta-Rule Linear Attention · state recall (live)";
45
+
46
+ // PRIMARY endpoint is the a11oy-NATIVE self-hosted twin (same-origin, szl_gated_delta.py):
47
+ // real delta-rule / gated-delta / linear-attention state updates over a seeded key/value
48
+ // write trace (label MODELED, read verbatim). No cross-origin dependency.
49
+ const EP = "/api/a11oy/v1/gateddelta/recall?seed=42&seq_len=48&dim=8&n_keys=6&chunk=8&gate=0.98&beta=1.0";
50
+
51
+ // data-viz hues — purple BANNED
52
+ const C_DELTA = 0x3af4c8; // proof-teal (delta rule / HUD accent)
53
+ const C_GATED = 0x5b8dee; // lattice-blue (gated delta)
54
+ const C_LINEAR = 0x5a6570; // grey (linear-attention error)
55
+ const C_DIM = 0x42505d; // grey (degraded / no-live-data)
56
+ const C_GRID = 0x1b3a44; // floor / link colour
57
+
58
+ // register-row layout geometry
59
+ const REG_GAP = 1.1; // world-units between register nodes along X
60
+ const MAX_REGS = 16; // cap on registers rendered (perf; backend clamps n_keys<=16)
61
+ const BASE_Y = 0.4; // resting height of a register node
62
+
63
+ let _stage = null, _THREE = null, _ctx = null, _group = null, _show = null;
64
+ let _frameReg = false, _polls = [], _el = {}, _badge = null;
65
+
66
+ // geometry handles
67
+ let _spine = null; // THREE.Line — the register-file spine
68
+ let _regMesh = []; // Array<THREE.Mesh> — one delta node per register
69
+ let _errBar = []; // Array<THREE.Mesh> — linear-attention error column per reg
70
+ let _marker = null; // THREE.Mesh — HUD pulsing marker (gate retention cue)
71
+
72
+ // live state
73
+ const S = {
74
+ label: null,
75
+ seqLen: null,
76
+ dim: null,
77
+ nKeys: null,
78
+ chunk: null,
79
+ gate: null,
80
+ beta: null,
81
+ nOverwrites: null,
82
+ linearErr: null, // linear_recall_error
83
+ deltaErr: null, // delta_recall_error
84
+ gatedErr: null, // gated_recall_error
85
+ linearCos: null,
86
+ deltaCos: null,
87
+ gatedCos: null,
88
+ gatedRetention: null,
89
+ deltaVsLinear: null, // delta_vs_linear_gain
90
+ chunkDiff: null, // chunk_max_state_diff
91
+ trackAcc: null, // state_track_acc {}
92
+ perReg: null, // per_register[]
93
+ state: "init",
94
+ };
95
+
96
+ // =============================================================================
97
+ // mount(ctx)
98
+ // =============================================================================
99
+ export function mount(ctx) {
100
+ _ctx = ctx; _stage = ctx.stage; _THREE = ctx.THREE;
101
+ _group = new _THREE.Group();
102
+ _stage.scene.add(_group);
103
+ _stage.camera.position.set(4, 6, 16);
104
+ try { if (_stage.controls && _stage.controls.target) { _stage.controls.target.set(4, 1, 0); _stage.controls.update(); } } catch (_) {}
105
+ try { _stage.setBloom(true); } catch (_) {}
106
+
107
+ _buildFloor();
108
+ _buildRegisterRow();
109
+ _buildMarker();
110
+
111
+ if (!_frameReg) { _stage.onFrame(_onFrame); _frameReg = true; }
112
+
113
+ _badge = ctx.live.createBadge();
114
+ _polls.push(ctx.live.poll(EP, 5000, _onGatedDelta, { badge: _badge, onState: (m) => { S.state = m.state; _paintOverlay(); } }));
115
+
116
+ _buildOverlay();
117
+ return { id: ID, started: true };
118
+ }
119
+
120
+ // =============================================================================
121
+ // builders
122
+ // =============================================================================
123
+ function _buildFloor() {
124
+ const THREE = _THREE;
125
+ const grid = new THREE.GridHelper(36, 36, C_GRID, 0x0f2027);
126
+ grid.material.opacity = 0.18; grid.material.transparent = true; grid.position.y = -0.01;
127
+ _group.add(grid);
128
+ }
129
+
130
+ // Pre-allocate a fixed register file: MAX_REGS slots. Each slot has a delta/gated
131
+ // node (recall quality) + a linear-attention error column. Toggled in-place as
132
+ // live data arrives (no per-poll geometry churn).
133
+ function _buildRegisterRow() {
134
+ const THREE = _THREE;
135
+
136
+ // register-file spine along X
137
+ {
138
+ const pts = [new THREE.Vector3(0, 0, 0), new THREE.Vector3(REG_GAP * (MAX_REGS - 1) + 1, 0, 0)];
139
+ const geo = new THREE.BufferGeometry().setFromPoints(pts);
140
+ const mat = new THREE.LineBasicMaterial({ color: C_DELTA, transparent: true, opacity: 0.4 });
141
+ _spine = new THREE.Line(geo, mat);
142
+ _group.add(_spine);
143
+ }
144
+
145
+ const nodeGeo = new THREE.IcosahedronGeometry(0.22, 0);
146
+ const barGeo = new THREE.BoxGeometry(0.22, 1.0, 0.22);
147
+ for (let r = 0; r < MAX_REGS; r++) {
148
+ const x = r * REG_GAP;
149
+ const node = new THREE.Mesh(
150
+ nodeGeo,
151
+ new THREE.MeshStandardMaterial({ color: C_DELTA, emissive: C_DELTA, emissiveIntensity: 0.3, transparent: true, opacity: 0.0 }),
152
+ );
153
+ node.position.set(x, BASE_Y, 0);
154
+ node.visible = false;
155
+ _group.add(node);
156
+ _regMesh.push(node);
157
+
158
+ const bar = new THREE.Mesh(
159
+ barGeo,
160
+ new THREE.MeshStandardMaterial({ color: C_LINEAR, emissive: C_LINEAR, emissiveIntensity: 0.15, transparent: true, opacity: 0.0 }),
161
+ );
162
+ bar.position.set(x, 0.5, -1.1);
163
+ bar.visible = false;
164
+ _group.add(bar);
165
+ _errBar.push(bar);
166
+ }
167
+ }
168
+
169
+ function _buildMarker() {
170
+ const THREE = _THREE;
171
+ _marker = new THREE.Mesh(
172
+ new THREE.IcosahedronGeometry(0.3, 1),
173
+ new THREE.MeshStandardMaterial({ color: C_GATED, emissive: C_GATED, emissiveIntensity: 0.5, wireframe: true, transparent: true, opacity: 0.85 }),
174
+ );
175
+ _marker.position.set(0, -1.0, 0);
176
+ _group.add(_marker);
177
+ }
178
+
179
+ // =============================================================================
180
+ // live data handler
181
+ // =============================================================================
182
+ function _onGatedDelta(j) {
183
+ // read honesty label VERBATIM — never upgrade
184
+ S.label = (j.label || "MODELED").toUpperCase();
185
+ S.seqLen = typeof j.seq_len === "number" ? j.seq_len : null;
186
+ S.dim = typeof j.dim === "number" ? j.dim : null;
187
+ S.nKeys = typeof j.n_keys === "number" ? j.n_keys : null;
188
+ S.chunk = typeof j.chunk === "number" ? j.chunk : null;
189
+ S.gate = typeof j.gate === "number" ? j.gate : null;
190
+ S.beta = typeof j.beta === "number" ? j.beta : null;
191
+ S.nOverwrites = typeof j.n_overwrites === "number" ? j.n_overwrites : null;
192
+ S.linearErr = typeof j.linear_recall_error === "number" ? j.linear_recall_error : null;
193
+ S.deltaErr = typeof j.delta_recall_error === "number" ? j.delta_recall_error : null;
194
+ S.gatedErr = typeof j.gated_recall_error === "number" ? j.gated_recall_error : null;
195
+ S.linearCos = typeof j.linear_recall_cos === "number" ? j.linear_recall_cos : null;
196
+ S.deltaCos = typeof j.delta_recall_cos === "number" ? j.delta_recall_cos : null;
197
+ S.gatedCos = typeof j.gated_recall_cos === "number" ? j.gated_recall_cos : null;
198
+ S.gatedRetention = typeof j.gated_retention === "number" ? j.gated_retention : null;
199
+ S.deltaVsLinear = typeof j.delta_vs_linear_gain === "number" ? j.delta_vs_linear_gain : null;
200
+ S.chunkDiff = typeof j.chunk_max_state_diff === "number" ? j.chunk_max_state_diff : null;
201
+ S.trackAcc = (j.state_track_acc && typeof j.state_track_acc === "object") ? j.state_track_acc : null;
202
+ S.perReg = Array.isArray(j.per_register) ? j.per_register : null;
203
+
204
+ _updateRegisterRow();
205
+ _paintOverlay();
206
+ }
207
+
208
+ // =============================================================================
209
+ // geometry updater — drives the register file from live data
210
+ // =============================================================================
211
+ function _updateRegisterRow() {
212
+ const live = S.state === "live";
213
+ const regs = live && S.perReg && S.perReg.length ? S.perReg.slice(0, MAX_REGS) : [];
214
+
215
+ for (let r = 0; r < MAX_REGS; r++) {
216
+ const node = _regMesh[r];
217
+ const bar = _errBar[r];
218
+ if (!live || r >= regs.length) {
219
+ node.visible = false;
220
+ bar.visible = false;
221
+ continue;
222
+ }
223
+ node.visible = true;
224
+ bar.visible = true;
225
+ const rec = regs[r];
226
+
227
+ // delta node: taller + proof-teal when recall is faithful (low delta_err, high cos).
228
+ const deltaGood = typeof rec.delta_cos === "number" ? Math.max(0, rec.delta_cos) : 0;
229
+ node.material.color.setHex(C_DELTA);
230
+ node.material.emissive.setHex(C_DELTA);
231
+ node.material.emissiveIntensity = 0.3 + 0.5 * deltaGood;
232
+ node.material.opacity = 0.95;
233
+ node.position.y = BASE_Y + deltaGood * 0.9;
234
+ // gated ring cue: scale by gated magnitude retention (fades for stale registers)
235
+ const ret = typeof rec.gated_retention === "number" ? Math.min(1.2, rec.gated_retention) : 1.0;
236
+ node.scale.setScalar(0.7 + 0.5 * ret);
237
+
238
+ // linear-attention error column: height grows with lin_err (overwrite collision).
239
+ const le = typeof rec.lin_err === "number" ? rec.lin_err : 0;
240
+ const h = Math.max(0.05, Math.min(4.0, le));
241
+ bar.scale.y = h;
242
+ bar.position.y = h * 0.5;
243
+ // blend grey -> lattice-blue by write count so heavily-overwritten regs read hot
244
+ const writes = typeof rec.writes === "number" ? rec.writes : 1;
245
+ bar.material.color.setHex(writes > 1 ? C_GATED : C_LINEAR);
246
+ bar.material.emissive.setHex(writes > 1 ? C_GATED : C_LINEAR);
247
+ bar.material.emissiveIntensity = writes > 1 ? 0.35 : 0.12;
248
+ bar.material.opacity = 0.55;
249
+ }
250
+
251
+ // spine degrades to grey when not live
252
+ _spine.material.color.setHex(live ? C_DELTA : C_DIM);
253
+ _spine.material.opacity = live ? 0.4 : 0.15;
254
+
255
+ if (_marker) {
256
+ if (live && S.gatedRetention != null) {
257
+ _marker.material.color.setHex(C_GATED);
258
+ _marker.material.emissive.setHex(C_GATED);
259
+ _marker.material.opacity = 0.85;
260
+ const x = Math.min(REG_GAP * (MAX_REGS - 1), (S.gatedRetention || 0) * REG_GAP * (MAX_REGS - 1));
261
+ _marker.position.set(x, -1.0, 0);
262
+ } else {
263
+ _marker.material.color.setHex(C_DIM);
264
+ _marker.material.emissive.setHex(C_DIM);
265
+ _marker.material.opacity = 0.3;
266
+ }
267
+ }
268
+ }
269
+
270
+ // =============================================================================
271
+ // per-frame animation
272
+ // =============================================================================
273
+ function _onFrame() {
274
+ const t = performance.now();
275
+ if (_group) _group.rotation.y = Math.sin(t * 0.00009) * 0.12;
276
+ if (_marker) {
277
+ _marker.rotation.y += 0.025;
278
+ _marker.rotation.x += 0.012;
279
+ const pulse = 1.0 + 0.15 * Math.sin(t * 0.004);
280
+ _marker.scale.setScalar(pulse);
281
+ }
282
+ }
283
+
284
+ // =============================================================================
285
+ // overlay
286
+ // =============================================================================
287
+ function _buildOverlay() {
288
+ const ctx = _ctx;
289
+ _show = createShowcase(ctx, {
290
+ id: ID, title: TITLE, accent: "#3af4c8",
291
+ badge: _badge,
292
+ chips: [{ label: "MODELED", text: "delta-rule recall", name: "gd" }],
293
+ legend: ["MODELED", "SAMPLE"],
294
+ description:
295
+ 'A linear-attention layer keeps an associative-memory <b>state matrix</b> that maps a ' +
296
+ 'key to a recalled value. <b>Plain linear attention</b> just ADDS every write, so ' +
297
+ 're-writing a key accumulates values and a later read of an overwritten key is wrong. ' +
298
+ 'The <b>delta rule</b> (a Householder reflection I − β k kᵀ) first ' +
299
+ 'REMOVES the old association then writes the new one — recalling the LAST write ' +
300
+ 'exactly. <b>Gated delta</b> adds a data-dependent decay gate α so stale memories ' +
301
+ 'fade (magnitude × α per step) while identity is kept. HUD also verifies the ' +
302
+ 'chunk-parallel invariant (chunked state == sequential state). Honesty label ' +
303
+ '<b>MODELED</b> (deterministic simulation on a synthetic key/value trace; NOT a real ' +
304
+ 'trained model or GPU). 0 runtime CDN.',
305
+ citations:
306
+ "Gated DeltaNet — Yang et al. arXiv:2412.06464 · Parallel Delta — arXiv:2406.06484 · " +
307
+ "DeltaProduct — arXiv:2502.10297 · GLA — arXiv:2312.06635. MODELED · not claimed-as.",
308
+ plain: { html: _plainHtml },
309
+ });
310
+
311
+ _el["gd-seqlen"] = _show.addField("seq_len (writes)");
312
+ _el["gd-dims"] = _show.addField("dim × n_keys (state / registers)");
313
+ _el["gd-overw"] = _show.addField("overwrites in trace");
314
+ _el["gd-linerr"] = _show.addField("linear-attention recall error");
315
+ _el["gd-deltaerr"] = _show.addField("delta-rule recall error — MODELED");
316
+ _el["gd-gatederr"] = _show.addField("gated-delta recall error");
317
+ _el["gd-gatedcos"] = _show.addField("gated-delta recall cosine (direction)");
318
+ _el["gd-retention"]= _show.addField("gate retention (α magnitude decay)");
319
+ _el["gd-gain"] = _show.addField("delta vs linear error gain");
320
+ _el["gd-chunk"] = _show.addField("chunk≡sequential state diff");
321
+ _el["gd-track"] = _show.addField("state-tracking acc (lin/delta/gated)");
322
+ _el["gd-label"] = _show.addField("honesty label");
323
+
324
+ _paintOverlay();
325
+ }
326
+
327
+ function _plainHtml() {
328
+ const le = S.linearErr != null ? S.linearErr.toFixed(2) : "loading…";
329
+ const de = S.deltaErr != null ? S.deltaErr.toFixed(3) : "loading…";
330
+ const gr = S.gatedRetention != null ? (S.gatedRetention * 100).toFixed(0) + "%" : "loading…";
331
+ return (
332
+ "<b>What this means:</b> Imagine a whiteboard where the model writes down “variable X = value” " +
333
+ "as it reads. If it just KEEPS ADDING new values without erasing the old one, then asking " +
334
+ "“what is X now?” gives a garbled sum — that is plain linear attention, and here its recall " +
335
+ "is off by <b>" + le + "</b>. The <b>delta rule</b> ERASES the old value of X before writing the " +
336
+ "new one, so it recalls the latest value almost perfectly (error <b>" + de + "</b>). The " +
337
+ "<b>gated</b> version also lets very old, untouched notes gently fade — here it keeps about " +
338
+ "<b>" + gr + "</b> of a note's strength while never confusing which note is which. This view is a " +
339
+ "<b>MODELED</b> deterministic simulation of those write/erase rules on a synthetic trace, not a " +
340
+ "run of a real trained model.");
341
+ }
342
+
343
+ function _tok(s) {
344
+ if (s === "live") return null;
345
+ if (s === "missing") return "NO-LIVE-DATA";
346
+ if (s === "degraded") return "DEGRADED";
347
+ if (s === "error") return "OFFLINE";
348
+ return "…";
349
+ }
350
+
351
+ function fx(v, d) { return typeof v === "number" ? v.toFixed(d) : "—"; }
352
+ function _set(id, v) { if (_el[id]) _el[id].textContent = v; }
353
+
354
+ function _paintOverlay() {
355
+ const t = _tok(S.state);
356
+ _set("gd-seqlen", t || (S.seqLen != null ? String(S.seqLen) : "—"));
357
+ _set("gd-dims", t || ((S.dim != null && S.nKeys != null) ? (S.dim + " × " + S.nKeys) : "—"));
358
+ _set("gd-overw", t || (S.nOverwrites != null ? String(S.nOverwrites) : "—"));
359
+ _set("gd-linerr", t || fx(S.linearErr, 3));
360
+ _set("gd-deltaerr", t || fx(S.deltaErr, 4));
361
+ _set("gd-gatederr", t || fx(S.gatedErr, 4));
362
+ _set("gd-gatedcos", t || fx(S.gatedCos, 4));
363
+ _set("gd-retention",t || (S.gatedRetention != null ? (S.gatedRetention * 100).toFixed(1) + "%" : "—"));
364
+ _set("gd-gain", t || (S.deltaVsLinear != null ? "−" + fx(S.deltaVsLinear, 3) + " err" : "—"));
365
+ _set("gd-chunk", t || (S.chunkDiff != null ? S.chunkDiff.toExponential(1) : "—"));
366
+ _set("gd-track", t || (S.trackAcc ? [S.trackAcc.linear, S.trackAcc.delta, S.trackAcc.gated].map((x) => fx(x, 2)).join(" / ") : "—"));
367
+ // honesty label verbatim — never upgraded
368
+ _set("gd-label", t || (S.label || "MODELED"));
369
+ if (_show) { _show.setChip("gd", S.label || "MODELED", { text: "delta-rule recall" }); _show.refreshPlain(); }
370
+ }
371
+
372
+ // =============================================================================
373
+ // unmount — clean up everything; must not affect other organs
374
+ // =============================================================================
375
+ export function unmount() {
376
+ _polls.forEach((p) => { try { p.stop(); } catch (_) {} }); _polls = [];
377
+ try { if (_show) _show.destroy(); } catch (_) {}
378
+ try {
379
+ if (_group && _stage) {
380
+ _group.traverse((o) => {
381
+ if (o.geometry && o.geometry.dispose) o.geometry.dispose();
382
+ if (o.material) {
383
+ const ms = Array.isArray(o.material) ? o.material : [o.material];
384
+ ms.forEach((m) => { if (m.dispose) m.dispose(); });
385
+ }
386
+ });
387
+ _stage.scene.remove(_group);
388
+ }
389
+ } catch (_) {}
390
+ _group = _show = null;
391
+ _spine = null; _regMesh = []; _errBar = []; _marker = null;
392
+ _el = {}; _badge = null; _frameReg = false;
393
+ _stage = _THREE = _ctx = null;
394
+ S.label = S.seqLen = S.dim = S.nKeys = S.chunk = S.gate = S.beta = null;
395
+ S.nOverwrites = S.linearErr = S.deltaErr = S.gatedErr = null;
396
+ S.linearCos = S.deltaCos = S.gatedCos = S.gatedRetention = null;
397
+ S.deltaVsLinear = S.chunkDiff = S.trackAcc = S.perReg = null;
398
+ S.state = "init";
399
+ }
400
+
401
+ export default { id: ID, title: TITLE, endpoints: [EP], mount, unmount };