betterwithage commited on
Commit
60ef701
·
verified ·
1 Parent(s): 91ffe61

F2: Factory3D + AutoReview3D holographic enhancements (additive, 2D fallback)

Browse files

F2 Factory3D + AutoReview3D enhancements — direct Space push. Doctrine: locked=8 @ c7c0ba17; Lambda=Conjecture 1 < 1.0; 0 runtime CDN; signed receipts real; trust < 100%.

Files changed (1) hide show
  1. web/autoreview.html +289 -0
web/autoreview.html CHANGED
@@ -19,6 +19,8 @@
19
  <script src="/vendor/chart.umd.min.js"></script>
20
  <script src="/static/shared/szl_label_engine.js"></script>
21
  <script src="/static/shared/szl_receipt_cosign.js"></script>
 
 
22
  <style>
23
  :root{
24
  --bg:#0a0e14; --panel:#121823; --panel2:#0f141d; --line:#1f2a3a;
@@ -95,6 +97,37 @@
95
  .explain{color:#cfd8e3;font-size:12px;margin-top:6px;border-top:1px dotted #1a2435;
96
  padding-top:6px}
97
  .selfc{color:var(--acc);font-size:11px;margin-top:4px}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  </style>
99
  </head>
100
  <body>
@@ -108,8 +141,51 @@
108
  <b>OPA/Rego</b> rules mapped to <b>OSCAL</b> controls + <b>NIST AI RMF MANAGE</b>, and
109
  conformal-calibrated. On block we return an explanation so the parent self-corrects;
110
  we escalate to a human only when truly needed. Effectors stay SIMULATED.</div>
 
111
  </header>
112
  <div class="wrap">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  <div class="grid">
114
 
115
  <!-- AUTONOMY DIAL -->
@@ -375,5 +451,218 @@ try{ if(window.SZLLabels&&SZLLabels.auditText){
375
  if(flags&&flags.length){console.warn("[autoreview] label audit flags:",flags);}
376
  }}catch(_){}
377
  </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  </body>
379
  </html>
 
19
  <script src="/vendor/chart.umd.min.js"></script>
20
  <script src="/static/shared/szl_label_engine.js"></script>
21
  <script src="/static/shared/szl_receipt_cosign.js"></script>
22
+ <!-- F2: vendored F1 holographic kit (0 runtime CDN) for the optional 3D autonomy dial + verdict trust-sphere. -->
23
+ <script src="/static/shared/szl_holo3d.js"></script>
24
  <style>
25
  :root{
26
  --bg:#0a0e14; --panel:#121823; --panel2:#0f141d; --line:#1f2a3a;
 
97
  .explain{color:#cfd8e3;font-size:12px;margin-top:6px;border-top:1px dotted #1a2435;
98
  padding-top:6px}
99
  .selfc{color:var(--acc);font-size:11px;margin-top:4px}
100
+ /* F2 — 3D autonomy dial + verdict trust-sphere (additive; 2D content stays). */
101
+ #ar3d-toggle{background:#0e1622;border:1px solid var(--acc);color:var(--acc);border-radius:7px;
102
+ padding:6px 12px;font:12px ui-monospace,monospace;cursor:pointer;margin-top:8px}
103
+ #ar3d-panel{display:none;margin:16px 0;background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:16px}
104
+ #ar3d-panel h2{margin:0 0 8px;font-size:14px;letter-spacing:.4px;color:var(--acc)}
105
+ .ar3d-stage{display:grid;grid-template-columns:1.4fr 1fr;gap:14px}
106
+ @media(max-width:860px){.ar3d-stage{grid-template-columns:1fr}}
107
+ #ar3d-canvas{width:100%;height:400px;background:#070b12;border:1px solid var(--line);border-radius:8px;position:relative}
108
+ #ar3d-mode{position:absolute;top:8px;right:10px;font-size:10px;color:var(--mut);z-index:5}
109
+ .ar3d-side{display:flex;flex-direction:column;gap:10px}
110
+ .ar3d-box{background:#0e1622;border:1px solid var(--line);border-radius:8px;padding:10px}
111
+ .ar3d-box h3{margin:0 0 6px;font-size:11px;text-transform:uppercase;letter-spacing:.8px;color:var(--mut)}
112
+ .ar3d-dialrow{display:flex;gap:5px;flex-wrap:wrap;margin-bottom:8px}
113
+ .ar3d-dlv{flex:1;min-width:42px;text-align:center;padding:6px 4px;border:1px solid var(--line);
114
+ border-radius:7px;background:#0b121c;cursor:pointer;font-size:11px}
115
+ .ar3d-dlv.sel{border-color:var(--acc);color:var(--acc);background:#0a201e}
116
+ .ar3d-ctl{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:8px}
117
+ .ar3d-ctl input{background:#0e1622;color:var(--ink);border:1px solid var(--line);border-radius:6px;
118
+ padding:6px 9px;font:12px ui-monospace,monospace}
119
+ .ar3d-ctl button{background:#0e1622;color:var(--ink);border:1px solid var(--line);border-radius:6px;
120
+ padding:6px 11px;font:12px ui-monospace,monospace;cursor:pointer}
121
+ .ar3d-ctl button:hover{border-color:var(--acc)}
122
+ #ar3d-verdict{font-size:12px;color:var(--ink);line-height:1.6;min-height:18px}
123
+ #ar3d-lam{font-size:30px;font-weight:700;letter-spacing:.5px}
124
+ .ar3d-board{display:flex;gap:6px;flex-wrap:wrap;min-height:30px;align-items:center}
125
+ .ar3d-rcpt{padding:3px 8px;border-radius:7px;border:1px solid var(--line);background:#0b121c;
126
+ font-size:10px;animation:ar3d-in .5s ease}
127
+ @keyframes ar3d-in{from{opacity:0;transform:translateX(18px)}to{opacity:1;transform:none}}
128
+ .ar3d-rcpt.allow{border-color:var(--ok);color:var(--ok)}.ar3d-rcpt.narrow{border-color:var(--warn);color:var(--warn)}
129
+ .ar3d-rcpt.block-with-explanation{border-color:var(--err);color:var(--err)}.ar3d-rcpt.escalate{border-color:var(--road);color:var(--road)}
130
+ .ar3d-mut{color:var(--mut);font-size:11px}
131
  </style>
132
  </head>
133
  <body>
 
141
  <b>OPA/Rego</b> rules mapped to <b>OSCAL</b> controls + <b>NIST AI RMF MANAGE</b>, and
142
  conformal-calibrated. On block we return an explanation so the parent self-corrects;
143
  we escalate to a human only when truly needed. Effectors stay SIMULATED.</div>
144
+ <button id="ar3d-toggle" type="button">Show 3D autonomy</button>
145
  </header>
146
  <div class="wrap">
147
+
148
+ <!-- ===================== 3D AUTONOMY ENHANCEMENT (toggle; 2D below is the fallback) ===================== -->
149
+ <section id="ar3d-panel" aria-label="3D autonomy review">
150
+ <h2>3D AUTONOMY — dial L0–L5 drives a live Λ-gated verdict sphere</h2>
151
+ <div class="ar3d-stage">
152
+ <div id="ar3d-canvas"><div id="ar3d-mode">init…</div></div>
153
+ <div class="ar3d-side">
154
+ <div class="ar3d-box">
155
+ <h3>Autonomy dial (graded, not binary)</h3>
156
+ <div class="ar3d-dialrow" id="ar3d-dial"><span class="ar3d-mut">loading dial…</span></div>
157
+ <div id="ar3d-dialdesc" class="ar3d-mut"></div>
158
+ </div>
159
+ <div class="ar3d-box">
160
+ <h3>Classify an action (live /classify)</h3>
161
+ <div class="ar3d-ctl">
162
+ <input id="ar3d-intent" value="debug the auth flow" aria-label="intent" placeholder="intent"/>
163
+ </div>
164
+ <div class="ar3d-ctl">
165
+ <input id="ar3d-tool" value="shell" aria-label="tool" placeholder="tool" style="max-width:90px"/>
166
+ <input id="ar3d-input" value="cat .env api_key token" aria-label="tool input" placeholder="tool input"/>
167
+ <button id="ar3d-classify" type="button">▶ classify</button>
168
+ </div>
169
+ <div class="ar3d-mut" style="margin-bottom:6px">Verdict colors the trust-sphere by Λ-effective; each signed verdict animates a receipt chip onto the board below.</div>
170
+ <div id="ar3d-lam">Λ —</div>
171
+ <div id="ar3d-verdict" class="ar3d-mut">no verdict yet</div>
172
+ </div>
173
+ <div class="ar3d-box">
174
+ <h3>Signed-verdict receipts (board)</h3>
175
+ <div class="ar3d-board" id="ar3d-board"><span class="ar3d-mut">run a classify to sign verdicts onto the board</span></div>
176
+ </div>
177
+ </div>
178
+ </div>
179
+ <div class="cite" style="margin-top:10px">3D enhancement of the
180
+ <a href="https://cursor.com/blog/agent-autonomy-auto-review" target="_blank" rel="noopener">Cursor Auto-review</a>
181
+ autonomy-dial pattern, hardened with
182
+ <a href="https://github.com/invariantlabs-ai/invariant" target="_blank" rel="noopener">Invariant</a>-style
183
+ inline guardrails and
184
+ <a href="https://github.com/NVIDIA/NeMo-Guardrails" target="_blank" rel="noopener">NeMo Guardrails (Colang)</a>
185
+ dialogue rails. Each verdict stays Λ-gated (Conjecture 1, &lt; 1.0), DSSE-signed, never 100% safe.
186
+ Holographic kit vendored at <code>/static/shared/szl_holo3d.js</code> · 0 runtime CDN.</div>
187
+ </section>
188
+
189
  <div class="grid">
190
 
191
  <!-- AUTONOMY DIAL -->
 
451
  if(flags&&flags.length){console.warn("[autoreview] label audit flags:",flags);}
452
  }}catch(_){}
453
  </script>
454
+ <script>
455
+ /* F2 Auto-Review 3D (additive) */
456
+ /* F2 — Auto-Review 3D controller (additive enhancement; 2D content is the fallback).
457
+ * 0 runtime CDN: kit is vendored at /static/shared/szl_holo3d.js (imported only).
458
+ * Reads LIVE /api/a11oy/v1/autoreview/{dial,classify}. Λ-gated (Conjecture 1, <1.0),
459
+ * DSSE-signed verdicts, trust < 100%. Never fabricates metrics. */
460
+ (function () {
461
+ "use strict";
462
+ var BASE = "/api/a11oy/v1/autoreview";
463
+ var Q = function (id) { return document.getElementById(id); };
464
+ var ESC = function (s) {
465
+ return String(s == null ? "" : s).replace(/[&<>]/g, function (c) {
466
+ return { "&": "&amp;", "<": "&lt;", ">": "&gt;" }[c];
467
+ });
468
+ };
469
+ // verdict -> board chip class (matches .ar3d-rcpt.<verdict> CSS)
470
+ var VCLASS = {
471
+ "allow": "allow", "narrow": "narrow",
472
+ "block-with-explanation": "block-with-explanation", "escalate": "escalate"
473
+ };
474
+
475
+ var scene = null, sphere = null, dial = 3, dialLevels = [], built = false, signed = 0;
476
+
477
+ function getj(u) {
478
+ return fetch(u).then(function (r) {
479
+ if (!r.ok) { throw new Error(u + " -> " + r.status); }
480
+ return r.json();
481
+ });
482
+ }
483
+ function postj(u, b) {
484
+ return fetch(u, {
485
+ method: "POST",
486
+ headers: { "content-type": "application/json" },
487
+ body: JSON.stringify(b || {})
488
+ }).then(function (r) {
489
+ if (!r.ok) { throw new Error(u + " -> " + r.status); }
490
+ return r.json();
491
+ });
492
+ }
493
+
494
+ function setMode() {
495
+ var el = Q("ar3d-mode");
496
+ if (!el) { return; }
497
+ if (!window.SZLHolo) { el.textContent = "3D kit unavailable — using 2D content below"; return; }
498
+ try {
499
+ var caps = SZLHolo.capabilities();
500
+ el.textContent = "render: " + (caps.mode || "?") + (caps.webgl2 ? " (webgl2)" : "");
501
+ } catch (_) { el.textContent = "render: ready"; }
502
+ }
503
+
504
+ // ---- AUTONOMY DIAL (live /dial) ----
505
+ function loadDial() {
506
+ return getj(BASE + "/dial").then(function (d) {
507
+ dialLevels = d.levels || [];
508
+ dial = (d.default != null) ? d.default : 3;
509
+ renderDial();
510
+ }).catch(function (e) {
511
+ var r = Q("ar3d-dial");
512
+ if (r) { r.innerHTML = '<span class="ar3d-mut">dial unavailable: ' + ESC(e.message) + "</span>"; }
513
+ });
514
+ }
515
+ function renderDial() {
516
+ var row = Q("ar3d-dial");
517
+ if (!row) { return; }
518
+ row.innerHTML = dialLevels.map(function (l) {
519
+ return '<div class="ar3d-dlv' + (l.level === dial ? " sel" : "") +
520
+ '" data-lv="' + l.level + '">L' + l.level + "</div>";
521
+ }).join("");
522
+ var cells = row.querySelectorAll(".ar3d-dlv");
523
+ for (var i = 0; i < cells.length; i++) {
524
+ cells[i].addEventListener("click", function (ev) {
525
+ dial = parseInt(ev.currentTarget.getAttribute("data-lv"), 10);
526
+ renderDial();
527
+ describeDial();
528
+ });
529
+ }
530
+ describeDial();
531
+ }
532
+ function describeDial() {
533
+ var el = Q("ar3d-dialdesc");
534
+ if (!el) { return; }
535
+ var sel = null;
536
+ for (var i = 0; i < dialLevels.length; i++) {
537
+ if (dialLevels[i].level === dial) { sel = dialLevels[i]; break; }
538
+ }
539
+ sel = sel || {};
540
+ var label = (sel.label || "").replace(/^L\d+\s*[\u2014-]\s*/, "");
541
+ el.innerHTML = '<b style="color:var(--acc)">L' + dial + " — " + ESC(label) + "</b>: " +
542
+ ESC(sel.desc || sel.policy || sel.description || "");
543
+ }
544
+
545
+ // ---- 3D SCENE + verdict trust-sphere ----
546
+ function ensureScene() {
547
+ if (built) { return true; }
548
+ var mount = Q("ar3d-canvas");
549
+ if (!mount || !window.SZLHolo) { return false; }
550
+ try {
551
+ scene = SZLHolo.createScene(mount, { sample: false });
552
+ // verdict trust-sphere — starts at a neutral, honest sub-1.0 Λ
553
+ sphere = scene.addTrustSphere({ center: [0, 0, 0], radius: 0.8, lambda: 0.5, label: "VERDICT" });
554
+ scene.setLambda(0.5);
555
+ scene.start();
556
+ built = true;
557
+ setMode();
558
+ return true;
559
+ } catch (e) {
560
+ var el = Q("ar3d-mode");
561
+ if (el) { el.textContent = "3D init failed — 2D content below is intact"; }
562
+ return false;
563
+ }
564
+ }
565
+
566
+ // map a verdict to a board chip + animate it onto the board
567
+ function pushReceipt(d) {
568
+ var board = Q("ar3d-board");
569
+ if (!board) { return; }
570
+ if (signed === 0) { board.innerHTML = ""; }
571
+ signed += 1;
572
+ var v = d.verdict || "—";
573
+ var lam = (typeof d.lambda_effective === "number") ? d.lambda_effective : null;
574
+ var sig = d.receipt && d.receipt.envelope && d.receipt.envelope.signed;
575
+ var hash = (d.decision_hash || "").slice(0, 12);
576
+ var chip = document.createElement("div");
577
+ chip.className = "ar3d-rcpt " + (VCLASS[v] || "");
578
+ chip.innerHTML = "#" + signed + " " + ESC(v) +
579
+ (lam != null ? " · Λ" + lam.toFixed(2) : "") +
580
+ (sig ? " · ✔signed" : " · unsigned") +
581
+ (hash ? ' · <span style="opacity:.7">' + ESC(hash) + "…</span>" : "");
582
+ board.appendChild(chip);
583
+ }
584
+
585
+ // ---- CLASSIFY (live /classify) -> recolor sphere by Λ, sign receipt onto board ----
586
+ function classify() {
587
+ var btn = Q("ar3d-classify");
588
+ if (btn) { btn.disabled = true; }
589
+ var verdEl = Q("ar3d-verdict");
590
+ if (verdEl) { verdEl.textContent = "classifying…"; }
591
+ var body = {
592
+ intent: (Q("ar3d-intent") || {}).value || "",
593
+ tool: (Q("ar3d-tool") || {}).value || "",
594
+ tool_input: (Q("ar3d-input") || {}).value || "",
595
+ dial: dial,
596
+ workspace: "demo"
597
+ };
598
+ return postj(BASE + "/classify", body).then(function (d) {
599
+ var lam = (typeof d.lambda_effective === "number") ? d.lambda_effective : 0.5;
600
+ // honest: Λ stays < 1.0 (Conjecture 1) — clamp just under 1
601
+ if (lam >= 1.0) { lam = 0.999; }
602
+ if (sphere) { sphere.lambda = lam; }
603
+ if (scene) { scene.setLambda(lam); }
604
+ var lamEl = Q("ar3d-lam");
605
+ if (lamEl) {
606
+ lamEl.textContent = "Λ " + lam.toFixed(3);
607
+ if (window.SZLHolo && SZLHolo.lambdaColor) { lamEl.style.color = SZLHolo.lambdaColor(lam); }
608
+ }
609
+ if (verdEl) {
610
+ verdEl.innerHTML = "<b>" + ESC(d.verdict || "—") + "</b> (L" +
611
+ ESC(d.dial != null ? d.dial : dial) + ") · rule <b>" + ESC(d.rule_id || "—") +
612
+ "</b> · OSCAL " + ESC((d.oscal_controls || []).join(", ") || "—") +
613
+ "<br>" + ESC(d.explanation || "");
614
+ verdEl.className = "";
615
+ }
616
+ pushReceipt(d);
617
+ }).catch(function (e) {
618
+ if (verdEl) { verdEl.innerHTML = '<span style="color:var(--err)">classify failed: ' + ESC(e.message) + "</span>"; }
619
+ }).then(function () {
620
+ if (btn) { btn.disabled = false; }
621
+ });
622
+ }
623
+
624
+ // ---- TOGGLE (keeps 2D content as fallback) ----
625
+ function toggle() {
626
+ var panel = Q("ar3d-panel");
627
+ var btn = Q("ar3d-toggle");
628
+ if (!panel) { return; }
629
+ var showing = panel.style.display !== "none" && panel.style.display !== "";
630
+ if (showing) {
631
+ panel.style.display = "none";
632
+ if (btn) { btn.textContent = "Show 3D autonomy"; }
633
+ if (scene && scene.stop) { try { scene.stop(); } catch (_) {} }
634
+ } else {
635
+ panel.style.display = "block";
636
+ if (btn) { btn.textContent = "Hide 3D autonomy"; }
637
+ if (ensureScene() && scene && scene.start) { try { scene.start(); } catch (_) {} }
638
+ }
639
+ }
640
+
641
+ function init() {
642
+ var btn = Q("ar3d-toggle");
643
+ if (btn) { btn.addEventListener("click", toggle); }
644
+ var cb = Q("ar3d-classify");
645
+ if (cb) { cb.addEventListener("click", classify); }
646
+ loadDial();
647
+ setMode();
648
+ if (!window.SZLHolo) {
649
+ var el = Q("ar3d-mode");
650
+ if (el) { el.textContent = "3D kit unavailable — 2D content below is the fallback"; }
651
+ }
652
+ // expose hooks for live verification
653
+ window.__AR3D_toggle = toggle;
654
+ window.__AR3D_classify = classify;
655
+ window.__AR3D_state = function () {
656
+ return { built: built, dial: dial, signed: signed, lambda: sphere ? sphere.lambda : null };
657
+ };
658
+ }
659
+
660
+ if (document.readyState === "loading") {
661
+ document.addEventListener("DOMContentLoaded", init);
662
+ } else {
663
+ init();
664
+ }
665
+ })();
666
+ </script>
667
  </body>
668
  </html>