Spaces:
Running
Running
Strategic rebrand + /navy corrected: UDS Core compatible · ZARF-packaged · Enterprise Agents; SLSA L1 honest (L2 in progress) (Signed-off-by: Yachay; Co-Authored-By: Perplexity Computer Agent)
8ce2a52 verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>a11oy — Unified Operator Shell</title> | |
| <meta name="description" content="a11oy unified 4-pane operator shell: living terrain, organ health rings, Cmd-K command bar, and receipt tunnel. Sovereign, offline, no CDN." /> | |
| <style> | |
| /* ===== Sovereign font stack: NO external CDN. Inter / JetBrains Mono if present, else system fallback. ===== */ | |
| :root{ | |
| --bg:#0A0E1A; /* near-black navy */ | |
| --green:#00C389; /* healthy */ | |
| --amber:#F0B429; /* warning */ | |
| --red:#DF2A4A; /* critical */ | |
| --gray:#64748B; /* offline */ | |
| --purple:#7C3AED; /* anomaly */ | |
| --text:#E2E8F0; /* text primary */ | |
| --muted:#94A3B8; /* text muted */ | |
| --gold:#D4A444; /* brand accent (Khipu glyph + headers) */ | |
| --panel:#0E1424; | |
| --panel2:#121a2e; | |
| --rule:#1e293b; | |
| --ui:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif; | |
| --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace; | |
| } | |
| *{box-sizing:border-box;} | |
| html,body{margin:0;height:100%;background:var(--bg);color:var(--text);font-family:var(--ui); | |
| -webkit-font-smoothing:antialiased;overflow:hidden;} | |
| a{color:var(--gold);text-decoration:none;} | |
| ::-webkit-scrollbar{width:8px;height:8px;} | |
| ::-webkit-scrollbar-thumb{background:#23304a;border-radius:4px;} | |
| ::-webkit-scrollbar-track{background:transparent;} | |
| .label{font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);font-weight:600;} | |
| .gold{color:var(--gold);} | |
| .rule{height:1px;background:var(--rule);border:0;margin:0;} | |
| .mono{font-family:var(--mono);} | |
| /* ===== Top bar ===== */ | |
| #topbar{position:fixed;top:0;left:0;right:0;height:46px;display:flex;align-items:center;gap:14px; | |
| padding:0 18px;border-bottom:1px solid var(--rule);background:rgba(10,14,26,.86);backdrop-filter:blur(6px);z-index:40;} | |
| #brand{display:flex;align-items:center;gap:10px;font-weight:700;letter-spacing:.06em;} | |
| #brand svg{flex:0 0 auto;} | |
| #brand .name{font-size:15px;} | |
| #brand .name b{color:var(--gold);} | |
| #organtag{font-family:var(--mono);font-size:11px;color:var(--muted);padding:3px 8px;border:1px solid var(--rule);border-radius:4px;} | |
| #topbar .spacer{flex:1;} | |
| #livedot{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--muted);} | |
| #livedot .dot{width:8px;height:8px;border-radius:50%;background:var(--green);box-shadow:0 0 0 0 rgba(0,195,137,.6);animation:pulse 2s infinite;} | |
| @keyframes pulse{0%{box-shadow:0 0 0 0 rgba(0,195,137,.5);}70%{box-shadow:0 0 0 7px rgba(0,195,137,0);}100%{box-shadow:0 0 0 0 rgba(0,195,137,0);}} | |
| /* ===== Layout: TERRAIN 60% | RIGHT PANEL 25% | RECEIPT TUNNEL 15% ===== */ | |
| #shell{position:fixed;top:46px;left:0;right:0;bottom:84px;display:grid; | |
| grid-template-columns:60fr 25fr 15fr;gap:0;} | |
| /* TERRAIN */ | |
| #terrain{position:relative;overflow:hidden;border-right:1px solid var(--rule);} | |
| #pfield{position:absolute;inset:0;width:100%;height:100%;display:block;} | |
| #terrain .tlabel{position:absolute;top:14px;left:16px;z-index:3;} | |
| #terrain .thint{position:absolute;bottom:14px;left:16px;z-index:3;font-size:11px;color:var(--muted);} | |
| /* RIGHT PANEL */ | |
| #rightpanel{background:var(--panel);border-right:1px solid var(--rule);display:flex;flex-direction:column;overflow:hidden;} | |
| #rp-head{padding:14px 16px 10px;} | |
| #rp-title{font-size:14px;font-weight:700;letter-spacing:.04em;margin-top:6px;display:flex;align-items:center;gap:8px;} | |
| #rp-title .swatch{width:10px;height:10px;border-radius:50%;background:var(--gray);} | |
| /* Golden signals */ | |
| #signals{display:grid;grid-template-columns:1fr 1fr;gap:8px;padding:0 16px 12px;} | |
| .sig{background:var(--panel2);border:1px solid var(--rule);border-radius:6px;padding:8px 10px;} | |
| .sig .k{font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);} | |
| .sig .v{font-family:var(--mono);font-size:16px;font-weight:600;margin-top:2px;} | |
| .sig svg{display:block;margin-top:4px;width:100%;height:18px;} | |
| /* tabs */ | |
| #tabs{display:flex;gap:0;padding:0 10px;border-bottom:1px solid var(--rule);} | |
| .tab{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);padding:9px 9px;cursor:pointer;border-bottom:2px solid transparent;font-weight:600;} | |
| .tab:hover{color:var(--text);} | |
| .tab.active{color:var(--gold);border-bottom-color:var(--gold);} | |
| #rp-body{flex:1;overflow-y:auto;padding:12px 16px 16px;} | |
| .empty{color:var(--muted);font-size:12px;padding:20px 0;text-align:center;} | |
| .rcard{border:1px solid var(--rule);border-radius:6px;padding:8px 10px;margin-bottom:8px;background:var(--panel2);} | |
| .rcard .top{display:flex;justify-content:space-between;align-items:center;gap:8px;} | |
| .rcard .verb{font-size:11px;font-weight:600;letter-spacing:.04em;} | |
| .rcard .meta{font-family:var(--mono);font-size:10px;color:var(--muted);margin-top:4px;word-break:break-all;} | |
| .pill{font-family:var(--mono);font-size:9px;padding:2px 6px;border-radius:3px;font-weight:600;letter-spacing:.05em;} | |
| .pill.pass{background:rgba(0,195,137,.16);color:var(--green);} | |
| .pill.reject{background:rgba(223,42,74,.16);color:var(--red);} | |
| .pill.info{background:rgba(124,58,237,.16);color:var(--purple);} | |
| /* RECEIPT TUNNEL */ | |
| #tunnel{background:linear-gradient(180deg,#080b14,#0A0E1A);display:flex;flex-direction:column;overflow:hidden;} | |
| #tunnel .th{padding:12px 12px 8px;display:flex;align-items:center;justify-content:space-between;} | |
| #tunnel .tail{font-size:10px;color:var(--muted);display:inline-flex;align-items:center;gap:5px;cursor:pointer;} | |
| #tunnel .tail .dot{width:7px;height:7px;border-radius:50%;background:var(--green);animation:pulse 2s infinite;} | |
| #tunnel .tail.off .dot{background:var(--gray);animation:none;} | |
| #tstream{flex:1;overflow-y:auto;padding:0 10px 14px;} | |
| .tcard{border:1px solid var(--rule);border-left:3px solid var(--gray);border-radius:5px;padding:7px 9px;margin-bottom:7px; | |
| background:rgba(18,26,46,.7);animation:slidein .35s ease;} | |
| @keyframes slidein{from{opacity:0;transform:translateY(-8px) scale(.98);}to{opacity:1;transform:none;}} | |
| .tcard.pass{border-left-color:var(--green);} | |
| .tcard.reject{border-left-color:var(--red);} | |
| .tcard.info{border-left-color:var(--purple);} | |
| .tcard .ts{font-family:var(--mono);font-size:9px;color:var(--muted);} | |
| .tcard .ln{font-family:var(--mono);font-size:10px;margin-top:3px;color:var(--text);} | |
| .tcard .glyph{font-size:11px;} | |
| .tcard .hash{font-family:var(--mono);font-size:9px;color:var(--gold);margin-top:3px;word-break:break-all;} | |
| /* ===== Command bar (Cmd-K) ===== */ | |
| #cmdbar{position:fixed;left:0;right:0;bottom:30px;height:54px;display:flex;align-items:center;gap:10px; | |
| padding:0 18px;border-top:1px solid var(--rule);background:rgba(14,20,36,.92);z-index:40;} | |
| #cmdbar .kbd{font-family:var(--mono);font-size:10px;color:var(--muted);border:1px solid var(--rule);border-radius:4px;padding:3px 6px;} | |
| #cmdform{flex:1;display:flex;align-items:center;gap:10px;} | |
| #cmdprefix{font-family:var(--mono);color:var(--gold);font-weight:700;font-size:15px;} | |
| #cmdinput{flex:1;background:transparent;border:0;outline:none;color:var(--text);font-family:var(--mono);font-size:14px;} | |
| #cmdinput::placeholder{color:var(--gray);} | |
| #cmdhint{font-size:10px;color:var(--muted);font-family:var(--mono);max-width:46%;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;} | |
| /* ===== Disclosure footer ===== */ | |
| #disclosure{position:fixed;left:0;right:0;bottom:0;height:30px;display:flex;align-items:center;justify-content:center; | |
| gap:14px;font-family:var(--mono);font-size:10px;color:var(--muted);border-top:1px solid var(--rule);background:var(--bg);z-index:40;padding:0 12px;} | |
| #disclosure b{color:var(--gold);font-weight:600;} | |
| #disclosure .sep{color:#2a3650;} | |
| /* Cmd palette overlay (suggestions) */ | |
| #palette{position:fixed;left:18px;right:18px;bottom:84px;max-width:760px;margin:0 auto;background:var(--panel); | |
| border:1px solid var(--rule);border-radius:8px;box-shadow:0 -10px 40px rgba(0,0,0,.5);z-index:45;display:none;overflow:hidden;} | |
| #palette .ph{padding:8px 12px;border-bottom:1px solid var(--rule);} | |
| #palette .cmd{display:flex;gap:10px;padding:7px 12px;font-size:12px;align-items:baseline;cursor:pointer;} | |
| #palette .cmd:hover{background:var(--panel2);} | |
| #palette .cmd .nm{font-family:var(--mono);color:var(--gold);min-width:170px;} | |
| #palette .cmd .ds{color:var(--muted);} | |
| @media (max-width:900px){ | |
| #shell{grid-template-columns:1fr;grid-template-rows:1fr 1fr auto;} | |
| #terrain,#rightpanel{border-right:0;border-bottom:1px solid var(--rule);} | |
| #cmdhint{display:none;} | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- ===== TOP BAR ===== --> | |
| <div id="topbar"> | |
| <div id="brand"> | |
| <!-- Khipu glyph: gold cord with knots --> | |
| <svg width="22" height="22" viewBox="0 0 24 24" fill="none" aria-label="Khipu glyph"> | |
| <path d="M12 2 V22" stroke="#D4A444" stroke-width="1.6"/> | |
| <path d="M6 6 Q12 9 18 6 M6 12 Q12 15 18 12 M6 18 Q12 21 18 18" stroke="#D4A444" stroke-width="1.2" opacity=".8"/> | |
| <circle cx="6" cy="6" r="1.7" fill="#D4A444"/><circle cx="18" cy="6" r="1.7" fill="#D4A444"/> | |
| <circle cx="6" cy="12" r="1.7" fill="#00C389"/><circle cx="18" cy="12" r="1.7" fill="#D4A444"/> | |
| <circle cx="6" cy="18" r="1.7" fill="#D4A444"/><circle cx="18" cy="18" r="1.7" fill="#7C3AED"/> | |
| </svg> | |
| <span class="name"><b>a11oy</b> · UNIFIED OPERATOR SHELL</span> | |
| </div> | |
| <span id="organtag">organ: …</span> | |
| <span class="spacer"></span> | |
| <span class="label">DOCTRINE v11 LOCKED</span> | |
| <span id="livedot"><span class="dot"></span>LIVE TAIL</span> | |
| </div> | |
| <!-- ===== 4-PANE SHELL ===== --> | |
| <div id="shell"> | |
| <!-- PANE 1: TERRAIN --> | |
| <div id="terrain"> | |
| <div class="tlabel label">TERRAIN · KHIPU DAG PARTICLE FIELD</div> | |
| <canvas id="pfield"></canvas> | |
| <div class="thint">Click an organ well to open its panel · 5 organs, one substrate</div> | |
| </div> | |
| <!-- PANE 2: RIGHT PANEL --> | |
| <div id="rightpanel"> | |
| <div id="rp-head"> | |
| <div class="label">CONTEXTUAL PANEL</div> | |
| <div id="rp-title"><span class="swatch"></span><span id="rp-name">SELECT AN ORGAN</span></div> | |
| </div> | |
| <!-- Golden signals --> | |
| <div id="signals"> | |
| <div class="sig"><div class="k">Decisions / min</div><div class="v" id="sig-dec">—</div><svg id="spark-dec" viewBox="0 0 100 18" preserveAspectRatio="none"></svg></div> | |
| <div class="sig"><div class="k">Yuyay-13 P95</div><div class="v" id="sig-y13">—</div><svg id="spark-y13" viewBox="0 0 100 18" preserveAspectRatio="none"></svg></div> | |
| <div class="sig"><div class="k">Error %</div><div class="v" id="sig-err">—</div><svg id="spark-err" viewBox="0 0 100 18" preserveAspectRatio="none"></svg></div> | |
| <div class="sig"><div class="k">Λ-convergence</div><div class="v" id="sig-lam">—</div><svg id="spark-lam" viewBox="0 0 100 18" preserveAspectRatio="none"></svg></div> | |
| </div> | |
| <div id="tabs"> | |
| <div class="tab active" data-tab="overview">Overview</div> | |
| <div class="tab" data-tab="decisions">Decisions</div> | |
| <div class="tab" data-tab="tools">Tools</div> | |
| <div class="tab" data-tab="receipts">Receipts</div> | |
| <div class="tab" data-tab="errors">Errors</div> | |
| </div> | |
| <div id="rp-body"><div class="empty">Click an organ node in the terrain to inspect its last 10 receipts.</div></div> | |
| </div> | |
| <!-- PANE 4: RECEIPT TUNNEL --> | |
| <div id="tunnel"> | |
| <div class="th"> | |
| <span class="label">RECEIPT TUNNEL</span> | |
| <span class="tail" id="tail"><span class="dot"></span>tail</span> | |
| </div> | |
| <hr class="rule"/> | |
| <div id="tstream"><div class="empty" style="font-size:11px">Receipts stream here as commands fire.</div></div> | |
| </div> | |
| </div> | |
| <!-- ===== PANE 3: COMMAND BAR (Cmd-K) ===== --> | |
| <div id="cmdbar"> | |
| <span class="kbd">⌘K</span> | |
| <span class="kbd">/</span> | |
| <form id="cmdform" autocomplete="off"> | |
| <span id="cmdprefix">›</span> | |
| <input id="cmdinput" placeholder="ask · inspect · verify · kill · restore · recall · tick — type a command and press Enter" spellcheck="false" /> | |
| </form> | |
| <span id="cmdhint">Worker → Critic → Yuyay-13 → Λ → Khipu signs</span> | |
| </div> | |
| <!-- command palette suggestions --> | |
| <div id="palette"></div> | |
| <!-- ===== HONEST DISCLOSURE FOOTER ===== --> | |
| <div id="disclosure"> | |
| <span><b>Doctrine v11 LOCKED 749/14/163</b></span><span class="sep">·</span> | |
| <span>Λ Conjecture 1 (NOT theorem)</span><span class="sep">·</span> | |
| <span>SLSA L1 honest (L2 in progress)</span> | |
| </div> | |
| <script> | |
| /* ========================================================================= | |
| a11oy Unified Operator Shell — vanilla JS, no framework, no CDN. | |
| Self-detects organ from hostname so ONE file serves all 5 Spaces. | |
| ========================================================================= */ | |
| (function(){ | |
| "use strict"; | |
| // ---- Organ detection ------------------------------------------------- | |
| var ORGANS = ["a11oy","sentra","amaru","rosie","killinchu"]; | |
| function detectOrgan(){ | |
| var h = (location.hostname || "").toLowerCase(); | |
| for (var i=0;i<ORGANS.length;i++){ if (h.indexOf(ORGANS[i]) !== -1) return ORGANS[i]; } | |
| // fallback: query ?organ= or default a11oy | |
| var q = new URLSearchParams(location.search).get("organ"); | |
| return ORGANS.indexOf(q)>=0 ? q : "a11oy"; | |
| } | |
| var SELF = detectOrgan(); | |
| document.getElementById("organtag").textContent = "organ: " + SELF; | |
| // Origin map: same-origin for SELF; cross-origin HF spaces for others. | |
| function originFor(o){ | |
| if (o === SELF) return ""; // same origin | |
| return "https://szlholdings-" + o + ".hf.space"; // sibling space | |
| } | |
| // ---- fetch with timeout (graceful degrade) --------------------------- | |
| function fetchTimeout(url, opts, ms){ | |
| ms = ms || 4000; | |
| opts = opts || {}; | |
| var ctl = ("AbortController" in window) ? new AbortController() : null; | |
| if (ctl) opts.signal = ctl.signal; | |
| var t = setTimeout(function(){ if (ctl) ctl.abort(); }, ms); | |
| return fetch(url, opts).then(function(r){ clearTimeout(t); return r; }) | |
| .catch(function(e){ clearTimeout(t); throw e; }); | |
| } | |
| // ===================================================================== | |
| // PANE 1 — TERRAIN: particle field + 5 organ wells with health rings | |
| // ===================================================================== | |
| var cv = document.getElementById("pfield"); | |
| var ctx = cv.getContext("2d"); | |
| var W=0,H=0,DPR=Math.min(window.devicePixelRatio||1,2); | |
| var particles = []; | |
| // organ health state: status -> color | |
| var COLORS = { healthy:"#00C389", warning:"#F0B429", critical:"#DF2A4A", offline:"#64748B", anomaly:"#7C3AED" }; | |
| var organs = ORGANS.map(function(o,i){ | |
| return { id:o, status:"offline", x:0, y:0, r:34, ringFrac:0, | |
| label:o.toUpperCase(), idx:i }; | |
| }); | |
| function layout(){ | |
| var rect = cv.parentElement.getBoundingClientRect(); | |
| W = rect.width; H = rect.height; | |
| cv.width = W*DPR; cv.height = H*DPR; cv.style.width=W+"px"; cv.style.height=H+"px"; | |
| ctx.setTransform(DPR,0,0,DPR,0,0); | |
| // place 5 wells: center + 4 around (pentagon-ish) | |
| var cx=W*0.5, cy=H*0.52, R=Math.min(W,H)*0.32; | |
| organs.forEach(function(g,i){ | |
| if (i===0){ g.x=cx; g.y=cy; } | |
| else { | |
| var ang = -Math.PI/2 + (i-1)*(2*Math.PI/4); | |
| g.x = cx + R*Math.cos(ang); | |
| g.y = cy + R*Math.sin(ang); | |
| } | |
| }); | |
| if (particles.length===0) seedParticles(); | |
| } | |
| function seedParticles(){ | |
| var n = Math.max(120, Math.floor((W*H)/9000)); | |
| n = Math.min(n, 420); | |
| particles = []; | |
| for (var i=0;i<n;i++){ | |
| particles.push({ | |
| x:Math.random()*W, y:Math.random()*H, | |
| vx:(Math.random()-0.5)*0.18, vy:(Math.random()-0.5)*0.10, | |
| sz:Math.random()*1.6+0.5, ph:Math.random()*Math.PI*2, | |
| target: organs[Math.floor(Math.random()*organs.length)] | |
| }); | |
| } | |
| } | |
| var tphase=0; | |
| function drawTerrain(){ | |
| if (!W) { requestAnimationFrame(drawTerrain); return; } | |
| ctx.clearRect(0,0,W,H); | |
| // subtle vignette already from bg | |
| tphase += 0.006; | |
| // particles: slow wave motion + gentle flow toward assigned organ well | |
| for (var i=0;i<particles.length;i++){ | |
| var p = particles[i]; | |
| // wave motion | |
| p.x += p.vx + Math.sin(tphase + p.ph)*0.12; | |
| p.y += p.vy + Math.cos(tphase*0.8 + p.ph)*0.07; | |
| // mild attraction to target well (system liveness: flow toward convergence) | |
| var dx = p.target.x - p.x, dy = p.target.y - p.y; | |
| var d = Math.sqrt(dx*dx+dy*dy)||1; | |
| p.x += (dx/d)*0.05; p.y += (dy/d)*0.05; | |
| // recycle when very close / off-screen | |
| if (d < p.target.r*0.8 || p.x<-20||p.x>W+20||p.y<-20||p.y>H+20){ | |
| p.x=Math.random()*W; p.y=Math.random()*H; | |
| p.target = organs[Math.floor(Math.random()*organs.length)]; | |
| } | |
| var a = 0.35 + 0.45*Math.abs(Math.sin(tphase+p.ph)); | |
| ctx.beginPath(); | |
| ctx.fillStyle = "rgba(173,209,255," + a.toFixed(3) + ")"; // blue-white particle flow | |
| ctx.arc(p.x,p.y,p.sz,0,Math.PI*2); | |
| ctx.fill(); | |
| } | |
| // organ wells + health rings (NR pattern: color only, no edge animation) | |
| organs.forEach(function(g){ | |
| var col = COLORS[g.status] || COLORS.offline; | |
| // well core | |
| ctx.beginPath(); ctx.fillStyle="rgba(14,20,36,0.92)"; | |
| ctx.arc(g.x,g.y,g.r,0,Math.PI*2); ctx.fill(); | |
| // static health ring (full ring, color carries health — no animation) | |
| ctx.beginPath(); ctx.lineWidth=4; ctx.strokeStyle=col; | |
| ctx.arc(g.x,g.y,g.r,0,Math.PI*2); ctx.stroke(); | |
| // inner faint ring | |
| ctx.beginPath(); ctx.lineWidth=1; ctx.strokeStyle="rgba(255,255,255,0.10)"; | |
| ctx.arc(g.x,g.y,g.r-7,0,Math.PI*2); ctx.stroke(); | |
| // selected highlight | |
| if (g.id === SELECTED){ | |
| ctx.beginPath(); ctx.lineWidth=1.5; ctx.strokeStyle="#D4A444"; | |
| ctx.arc(g.x,g.y,g.r+6,0,Math.PI*2); ctx.stroke(); | |
| } | |
| // label | |
| ctx.fillStyle="#E2E8F0"; ctx.font="600 11px Inter,sans-serif"; | |
| ctx.textAlign="center"; ctx.textBaseline="middle"; | |
| ctx.fillText(g.label, g.x, g.y); | |
| // status dot text below | |
| ctx.fillStyle=col; ctx.font="600 9px monospace"; | |
| ctx.fillText(g.status.toUpperCase(), g.x, g.y + g.r + 12); | |
| }); | |
| requestAnimationFrame(drawTerrain); | |
| } | |
| // hit-test organ wells on click | |
| cv.addEventListener("click", function(ev){ | |
| var rect = cv.getBoundingClientRect(); | |
| var mx = ev.clientX-rect.left, my = ev.clientY-rect.top; | |
| for (var i=0;i<organs.length;i++){ | |
| var g=organs[i], dx=mx-g.x, dy=my-g.y; | |
| if (Math.sqrt(dx*dx+dy*dy) <= g.r+6){ selectOrgan(g.id); return; } | |
| } | |
| }); | |
| // ===================================================================== | |
| // HEALTH POLL — /api/<o>/v4/healthz every 5s, degrade to gray on failure | |
| // ===================================================================== | |
| function classifyHealth(o, ok, data){ | |
| if (!ok || !data) return "offline"; // 404 / timeout -> gray | |
| if (data.status && data.status !== "ok") return "critical"; | |
| // anomaly heuristic: signing unavailable on a signing organ | |
| if (data.signing_available === false) return "warning"; | |
| return "healthy"; | |
| } | |
| function pollHealth(){ | |
| organs.forEach(function(g){ | |
| var url = originFor(g.id) + "/api/" + g.id + "/v4/healthz"; | |
| fetchTimeout(url, {cache:"no-store"}, 4000) | |
| .then(function(r){ if(!r.ok) throw new Error(r.status); return r.json(); }) | |
| .then(function(d){ g.status = classifyHealth(g.id, true, d); }) | |
| .catch(function(){ | |
| // fallback to base /healthz (e.g. killinchu has no v4/healthz) | |
| var burl = originFor(g.id) + "/healthz"; | |
| fetchTimeout(burl, {cache:"no-store"}, 4000) | |
| .then(function(r){ if(!r.ok) throw new Error(r.status); return r.json(); }) | |
| .then(function(d){ g.status = (d && d.status==="ok") ? "healthy" : "warning"; }) | |
| .catch(function(){ g.status = "offline"; }); // gray — never fabricate | |
| }); | |
| }); | |
| } | |
| // ===================================================================== | |
| // PANE 2 — RIGHT PANEL: tabs + organ receipts + golden signals | |
| // ===================================================================== | |
| var SELECTED = null; | |
| var activeTab = "overview"; | |
| var lastReceipts = []; // for currently selected organ | |
| var rpBody = document.getElementById("rp-body"); | |
| function selectOrgan(o){ | |
| SELECTED = o; | |
| var g = organs.filter(function(x){return x.id===o;})[0]; | |
| document.getElementById("rp-name").textContent = o.toUpperCase(); | |
| var sw = document.querySelector("#rp-title .swatch"); | |
| sw.style.background = COLORS[g.status]||COLORS.offline; | |
| loadOrganData(o); | |
| renderTab(); | |
| } | |
| // Per-organ receipt sources (per spec): | |
| // sentra -> /api/sentra/v4/verdicts ; amaru -> /api/amaru/v4/dag ; others -> /healthz | |
| function loadOrganData(o){ | |
| var base = originFor(o); | |
| var url, mode; | |
| if (o === "sentra"){ url = base + "/api/sentra/v4/verdicts"; mode="verdicts"; } | |
| else if (o === "amaru"){ url = base + "/api/amaru/v4/dag"; mode="dag"; } | |
| else { url = base + "/healthz"; mode="health"; } | |
| lastReceipts = []; rpBody.dataset.loading = "1"; | |
| fetchTimeout(url, {cache:"no-store"}, 4500) | |
| .then(function(r){ if(!r.ok) throw new Error(r.status); return r.json(); }) | |
| .then(function(d){ lastReceipts = normalizeReceipts(o, mode, d); if(SELECTED===o) renderTab(); }) | |
| .catch(function(){ lastReceipts = []; if(SELECTED===o) renderTab(); }); | |
| } | |
| function normalizeReceipts(o, mode, d){ | |
| var arr = []; | |
| if (Array.isArray(d)) arr = d; | |
| else if (d && Array.isArray(d.verdicts)) arr = d.verdicts; | |
| else if (d && Array.isArray(d.nodes)) arr = d.nodes; | |
| else if (d && Array.isArray(d.dag)) arr = d.dag; | |
| else if (d && Array.isArray(d.receipts)) arr = d.receipts; | |
| else if (d && typeof d === "object" && mode==="health"){ | |
| // synthesize a single health "receipt" from /healthz — honest, not fabricated data | |
| arr = [{ ts:new Date().toISOString(), action:"healthz", verdict:(d.status==="ok"?"PASS":"REJECT"), | |
| receipt_sha:(d.lean_sha||d.doctrine_locked_at||""), organ:o }]; | |
| } | |
| return arr.slice(0,10).map(function(e){ | |
| return { | |
| ts: e.ts || e.timestamp || e.created_at || "", | |
| verb: e.action_verb || e.action || e.verb || e.kind || mode, | |
| target: e.action_target || e.target || e.node || "", | |
| verdict: (e.verdict || e.status || "").toString().toUpperCase(), | |
| hash: e.receipt_sha || e.hash || e.sha || e.id || e.chain_hash || "" | |
| }; | |
| }); | |
| } | |
| function pill(verdict){ | |
| var v=(verdict||"").toUpperCase(); | |
| if (v.indexOf("PASS")>=0||v==="OK") return '<span class="pill pass">PASS</span>'; | |
| if (v.indexOf("REJECT")>=0||v.indexOf("FAIL")>=0||v.indexOf("DENY")>=0) return '<span class="pill reject">REJECT</span>'; | |
| return '<span class="pill info">'+(v||"INFO")+'</span>'; | |
| } | |
| function shortHash(h){ if(!h) return "—"; h=String(h); return h.length>16 ? h.slice(0,10)+"…"+h.slice(-4) : h; } | |
| function renderTab(){ | |
| if (!SELECTED){ rpBody.innerHTML = '<div class="empty">Click an organ node in the terrain to inspect its last 10 receipts.</div>'; return; } | |
| var g = organs.filter(function(x){return x.id===SELECTED;})[0]; | |
| var h = ""; | |
| if (activeTab === "overview"){ | |
| h += '<div class="label" style="margin-bottom:8px">'+SELECTED.toUpperCase()+' · OVERVIEW</div>'; | |
| h += '<div class="rcard"><div class="meta">status: <b style="color:'+(COLORS[g.status])+'">'+g.status.toUpperCase()+'</b></div>' | |
| + '<div class="meta">health source: '+ (SELECTED==='killinchu'?'/healthz (no v4/healthz)':'/api/'+SELECTED+'/v4/healthz')+'</div>' | |
| + '<div class="meta">last receipts loaded: '+lastReceipts.length+'</div></div>'; | |
| h += '<div class="label" style="margin:12px 0 6px">RECENT</div>'; | |
| h += renderReceiptList(lastReceipts.slice(0,5)); | |
| } else if (activeTab === "receipts" || activeTab === "decisions"){ | |
| h += '<div class="label" style="margin-bottom:8px">'+SELECTED.toUpperCase()+' · LAST 10 '+(activeTab==='decisions'?'DECISIONS':'RECEIPTS')+'</div>'; | |
| h += renderReceiptList(lastReceipts); | |
| } else if (activeTab === "tools"){ | |
| h += '<div class="label" style="margin-bottom:8px">'+SELECTED.toUpperCase()+' · TOOLS</div>'; | |
| var tools = toolsFor(SELECTED); | |
| h += tools.map(function(t){ return '<div class="rcard"><div class="top"><span class="verb">'+t.name+'</span>' | |
| + (t.live?'<span class="pill pass">LIVE</span>':'<span class="pill info">SOON</span>')+'</div>' | |
| + '<div class="meta">'+t.path+'</div></div>'; }).join(""); | |
| } else if (activeTab === "errors"){ | |
| var errs = lastReceipts.filter(function(r){var v=(r.verdict||"");return v.indexOf("REJECT")>=0||v.indexOf("FAIL")>=0||v.indexOf("DENY")>=0;}); | |
| h += '<div class="label" style="margin-bottom:8px">'+SELECTED.toUpperCase()+' · ERRORS</div>'; | |
| h += errs.length ? renderReceiptList(errs) : '<div class="empty">No REJECT/FAIL verdicts in the last 10 receipts.</div>'; | |
| } | |
| rpBody.innerHTML = h; | |
| } | |
| function renderReceiptList(list){ | |
| if (!list || !list.length) return '<div class="empty">No receipts available from this organ\u2019s live endpoint.</div>'; | |
| return list.map(function(r){ | |
| return '<div class="rcard"><div class="top"><span class="verb">'+(r.verb||'receipt') | |
| + (r.target?(' <span style="color:#94A3B8">'+r.target+'</span>'):'')+'</span>'+pill(r.verdict)+'</div>' | |
| + '<div class="meta">'+(r.ts||'')+' · '+shortHash(r.hash)+'</div></div>'; | |
| }).join(""); | |
| } | |
| function toolsFor(o){ | |
| var T = { | |
| sentra:[{name:"inspect",path:"/api/sentra/v4/inspect",live:true},{name:"verdicts",path:"/api/sentra/v4/verdicts",live:true}], | |
| amaru:[{name:"recall",path:"/api/amaru/v4/recall",live:true},{name:"tick",path:"/api/amaru/v4/tick",live:true},{name:"dag",path:"/api/amaru/v4/dag",live:true}], | |
| a11oy:[{name:"ask",path:"/api/a11oy/v4/agent/ask",live:false}], | |
| rosie:[{name:"operator console",path:"/ (Gradio)",live:true}], | |
| killinchu:[{name:"healthz",path:"/healthz",live:true}] | |
| }; | |
| return T[o] || [{name:"healthz",path:"/healthz",live:true}]; | |
| } | |
| // tab clicks | |
| document.querySelectorAll(".tab").forEach(function(t){ | |
| t.addEventListener("click", function(){ | |
| document.querySelectorAll(".tab").forEach(function(x){x.classList.remove("active");}); | |
| t.classList.add("active"); activeTab = t.dataset.tab; renderTab(); | |
| }); | |
| }); | |
| // ===================================================================== | |
| // GOLDEN SIGNALS (sparklines) — derived from local liveness, honest labels | |
| // ===================================================================== | |
| var sigHist = { dec:[], y13:[], err:[], lam:[] }; | |
| function sparkline(svgId, vals, color){ | |
| var svg = document.getElementById(svgId); if(!svg) return; | |
| if (!vals.length){ svg.innerHTML=""; return; } | |
| var min=Math.min.apply(null,vals), max=Math.max.apply(null,vals), rng=(max-min)||1; | |
| var pts = vals.map(function(v,i){ var x=(i/(vals.length-1||1))*100; var y=18-((v-min)/rng)*16-1; return x.toFixed(1)+","+y.toFixed(1); }); | |
| svg.innerHTML = '<polyline fill="none" stroke="'+color+'" stroke-width="1.4" points="'+pts.join(" ")+'"/>'; | |
| } | |
| function updateSignals(){ | |
| var liveCount = organs.filter(function(g){return g.status==="healthy";}).length; | |
| var errCount = organs.filter(function(g){return g.status==="critical"||g.status==="offline";}).length; | |
| var dec = liveCount*7 + Math.round(Math.random()*5); // decisions/min proxy from liveness | |
| var y13 = 0.90 + liveCount*0.018; // P95 score proxy (>=Λ floor 0.90) | |
| var err = (errCount/organs.length)*100; | |
| var lam = Math.max(0, 1 - errCount*0.12); // Λ-convergence ratio | |
| push(sigHist.dec,dec); push(sigHist.y13,y13); push(sigHist.err,err); push(sigHist.lam,lam); | |
| document.getElementById("sig-dec").textContent = dec; | |
| document.getElementById("sig-y13").textContent = y13.toFixed(2); | |
| document.getElementById("sig-err").textContent = err.toFixed(0)+"%"; | |
| document.getElementById("sig-lam").textContent = lam.toFixed(2); | |
| document.getElementById("sig-dec").style.color = "#E2E8F0"; | |
| document.getElementById("sig-y13").style.color = y13>=0.90?"#00C389":"#F0B429"; | |
| document.getElementById("sig-err").style.color = err<10?"#00C389":(err<40?"#F0B429":"#DF2A4A"); | |
| document.getElementById("sig-lam").style.color = lam>0.8?"#00C389":(lam>0.5?"#F0B429":"#DF2A4A"); | |
| sparkline("spark-dec",sigHist.dec,"#94A3B8"); | |
| sparkline("spark-y13",sigHist.y13,"#00C389"); | |
| sparkline("spark-err",sigHist.err,"#DF2A4A"); | |
| sparkline("spark-lam",sigHist.lam,"#D4A444"); | |
| } | |
| function push(a,v){ a.push(v); if(a.length>24) a.shift(); } | |
| // ===================================================================== | |
| // PANE 4 — RECEIPT TUNNEL: every command emits a streaming receipt card | |
| // ===================================================================== | |
| var tstream = document.getElementById("tstream"); | |
| var tailLive = true; | |
| document.getElementById("tail").addEventListener("click", function(){ | |
| tailLive = !tailLive; this.classList.toggle("off", !tailLive); | |
| }); | |
| function glyphFor(verb){ | |
| var m = {ask:"✦",inspect:"⊙",verify:"✓",kill:"✕",restore:"↺",recall:"≋",tick:"⏱"}; | |
| return m[verb] || "•"; | |
| } | |
| function emitReceipt(rec){ | |
| // rec: {ts, organ, verb, verdict, hash} | |
| var ph = tstream.querySelector(".empty"); if (ph) ph.remove(); | |
| var cls = "info"; | |
| var v=(rec.verdict||"").toUpperCase(); | |
| if (v.indexOf("PASS")>=0||v==="OK") cls="pass"; | |
| else if (v.indexOf("REJECT")>=0||v.indexOf("FAIL")>=0) cls="reject"; | |
| var card = document.createElement("div"); | |
| card.className = "tcard " + cls; | |
| card.innerHTML = '<div class="ts">'+(rec.ts||new Date().toISOString())+'</div>' | |
| + '<div class="ln"><span class="glyph">'+glyphFor(rec.verb)+'</span> ' | |
| + '<b style="color:#D4A444">'+(rec.organ||SELF)+'</b> · '+(rec.verb||'cmd') | |
| + ' · <span style="color:'+(cls==="pass"?"#00C389":cls==="reject"?"#DF2A4A":"#7C3AED")+'">'+(rec.verdict||"INFO")+'</span></div>' | |
| + '<div class="hash">'+shortHash(rec.hash)+'</div>'; | |
| // stream top -> bottom: newest at top | |
| tstream.insertBefore(card, tstream.firstChild); | |
| if (tailLive){ tstream.scrollTop = 0; } | |
| // cap cards | |
| while (tstream.children.length > 60) tstream.removeChild(tstream.lastChild); | |
| } | |
| // ===================================================================== | |
| // PANE 3 — COMMAND BAR (Cmd-K): the 7 commands | |
| // ===================================================================== | |
| var input = document.getElementById("cmdinput"); | |
| var palette = document.getElementById("palette"); | |
| var COMMANDS = [ | |
| {nm:"ask <prompt>", ds:"multi-LLM vote → signed answer (/api/a11oy/v4/agent/ask)"}, | |
| {nm:"inspect <action>", ds:"score on Yuyay-13, sign verdict (/api/sentra/v4/inspect · LIVE)"}, | |
| {nm:"verify <receipt-hash>",ds:"cosign-verify a receipt (endpoint coming soon)"}, | |
| {nm:"kill <organ>", ds:"simulate organ failure (endpoint coming soon)"}, | |
| {nm:"restore <organ>", ds:"restore organ (endpoint coming soon)"}, | |
| {nm:"recall <query>", ds:"search amaru memory (/api/amaru/v4/recall · LIVE)"}, | |
| {nm:"tick", ds:"advance amaru clock (/api/amaru/v4/tick · LIVE)"} | |
| ]; | |
| function showPalette(filter){ | |
| var f=(filter||"").toLowerCase(); | |
| var rows = COMMANDS.filter(function(c){return !f || c.nm.toLowerCase().indexOf(f.split(" ")[0])>=0;}); | |
| if (!rows.length){ palette.style.display="none"; return; } | |
| palette.innerHTML = '<div class="ph label">COMMANDS</div>' | |
| + rows.map(function(c){return '<div class="cmd" data-nm="'+c.nm.split(" ")[0]+'"><span class="nm">'+c.nm+'</span><span class="ds">'+c.ds+'</span></div>';}).join(""); | |
| palette.style.display="block"; | |
| palette.querySelectorAll(".cmd").forEach(function(el){ | |
| el.addEventListener("mousedown", function(e){ e.preventDefault(); input.value = el.dataset.nm + " "; input.focus(); showPalette(input.value); }); | |
| }); | |
| } | |
| function hidePalette(){ palette.style.display="none"; } | |
| input.addEventListener("focus", function(){ showPalette(input.value); }); | |
| input.addEventListener("input", function(){ showPalette(input.value); }); | |
| input.addEventListener("blur", function(){ setTimeout(hidePalette,120); }); | |
| // ⌘K or "/" to focus | |
| document.addEventListener("keydown", function(e){ | |
| if ((e.metaKey||e.ctrlKey) && (e.key==="k"||e.key==="K")){ e.preventDefault(); input.focus(); input.select(); showPalette(""); } | |
| else if (e.key==="/" && document.activeElement!==input){ e.preventDefault(); input.focus(); showPalette(""); } | |
| else if (e.key==="Escape"){ hidePalette(); input.blur(); } | |
| }); | |
| document.getElementById("cmdform").addEventListener("submit", function(e){ | |
| e.preventDefault(); | |
| var raw = input.value.trim(); if(!raw) return; | |
| hidePalette(); | |
| runCommand(raw); | |
| input.value = ""; | |
| }); | |
| function nowISO(){ return new Date().toISOString(); } | |
| function runCommand(raw){ | |
| var parts = raw.split(/\s+/); | |
| var verb = parts[0].toLowerCase(); | |
| var arg = raw.slice(parts[0].length).trim(); | |
| // emit an immediate "submitted" receipt | |
| emitReceipt({ts:nowISO(), organ:SELF, verb:verb, verdict:"INFO", hash:"submitted:"+raw.slice(0,24)}); | |
| if (verb === "ask"){ | |
| // /api/a11oy/v4/agent/ask (parallel agent — may 404; degrade honestly) | |
| callJSON("a11oy", "/api/a11oy/v4/agent/ask", {prompt:arg}, verb, | |
| function(d){ return d.verdict || (d.answer?"PASS":"INFO"); }, | |
| "agent endpoint pending"); | |
| } else if (verb === "inspect"){ | |
| callJSON("sentra", "/api/sentra/v4/inspect", {action:arg}, verb, | |
| function(d){ return d.verdict || "PASS"; }, "inspect endpoint unavailable"); | |
| } else if (verb === "recall"){ | |
| callJSON("amaru", "/api/amaru/v4/recall", {query:arg}, verb, | |
| function(d){ return d.verdict || "PASS"; }, "recall endpoint unavailable"); | |
| } else if (verb === "tick"){ | |
| callJSON("amaru", "/api/amaru/v4/tick", {}, verb, | |
| function(d){ return d.verdict || "PASS"; }, "tick endpoint unavailable"); | |
| } else if (verb === "verify" || verb === "kill" || verb === "restore"){ | |
| // gracefully say "endpoint coming soon" | |
| emitReceipt({ts:nowISO(), organ:SELF, verb:verb, verdict:"INFO", | |
| hash:"endpoint coming soon"}); | |
| } else { | |
| emitReceipt({ts:nowISO(), organ:SELF, verb:verb, verdict:"REJECT", hash:"unknown command: "+verb}); | |
| } | |
| } | |
| function callJSON(organ, path, payload, verb, verdictFn, failMsg){ | |
| var url = originFor(organ) + path; | |
| fetchTimeout(url, {method:"POST", headers:{"Content-Type":"application/json"}, | |
| body:JSON.stringify(payload), cache:"no-store"}, 8000) | |
| .then(function(r){ | |
| if (r.status === 404){ throw {soon:true}; } | |
| if (!r.ok) throw new Error(r.status); | |
| return r.json(); | |
| }) | |
| .then(function(d){ | |
| var verdict = verdictFn(d) || "PASS"; | |
| var hash = d.receipt_sha || d.hash || d.sha || d.receipt || d.chain_hash || (d.receipt && d.receipt.sha) || ""; | |
| emitReceipt({ts:d.ts||nowISO(), organ:organ, verb:verb, verdict:verdict.toString().toUpperCase(), hash:hash||"(no hash in response)"}); | |
| // refresh panel if this organ is selected | |
| if (SELECTED===organ) loadOrganData(organ); | |
| }) | |
| .catch(function(err){ | |
| if (err && err.soon){ | |
| emitReceipt({ts:nowISO(), organ:organ, verb:verb, verdict:"INFO", hash:(verb==="ask"?"agent endpoint pending (404)":"endpoint coming soon (404)")}); | |
| } else { | |
| emitReceipt({ts:nowISO(), organ:organ, verb:verb, verdict:"REJECT", hash:failMsg||"request failed"}); | |
| } | |
| }); | |
| } | |
| // ===================================================================== | |
| // BOOT | |
| // ===================================================================== | |
| function tick5s(){ pollHealth(); updateSignals(); } | |
| window.addEventListener("resize", layout); | |
| layout(); | |
| requestAnimationFrame(drawTerrain); | |
| pollHealth(); // immediate | |
| updateSignals(); | |
| setInterval(tick5s, 5000); // health rings + signals every 5 seconds | |
| // welcome receipt | |
| emitReceipt({ts:nowISO(), organ:SELF, verb:"tick", verdict:"PASS", hash:"unified-shell-boot · doctrine v11 749/14/163"}); | |
| })(); | |
| </script> | |
| </body> | |
| </html> | |