betterwithage commited on
Commit
ab59652
·
verified ·
1 Parent(s): 6c5196d

a11oy app: REAL VISUALS — 3D mesh organism, Lambda radar+gauge, gate/formula doughnuts, throughput bars. Product face, not JSON dumps. Signed-off-by: Stephen P. Lutar Jr. <stephenlutar2@gmail.com>

Browse files
Files changed (1) hide show
  1. pages/console.html +92 -11
pages/console.html CHANGED
@@ -7,6 +7,8 @@
7
  <meta name="description" content="a11oy is the orchestrating brain of the SZL governed-AI substrate: a full operator application — command center, five superpowers, Warhacker orchestration, observability, the constitution (wires), formulas, and the evidence ledger. Every view reads a live endpoint."/>
8
  <link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
9
  <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
 
 
10
  <style>/* ============ SZL UNIFIED APP SHELL — house style (gold+teal on dark) ============ */
11
  /* Shared by all 5 flagship full-applications. One product family. */
12
  :root{
@@ -103,6 +105,23 @@ pre.out{font-family:var(--mono);font-size:11.5px;line-height:1.55;color:var(--pa
103
  .menu-btn{display:inline-flex!important;}
104
  }
105
  .menu-btn{display:none;background:none;border:1px solid var(--gold-line);color:var(--gold);border-radius:6px;padding:.2rem .5rem;cursor:pointer;font-family:var(--mono);font-size:11px;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  </style>
107
  </head>
108
  <body>
@@ -162,6 +181,32 @@ function setOut(id,obj){const e=el(id);if(e)e.textContent=typeof obj==='string'?
162
  function setHTML(id,html){const e=el(id);if(e)e.innerHTML=html;}
163
  function setTxt(id,t){const e=el(id);if(e)e.textContent=t;}
164
  function addHTML(id,html){const e=el(id);if(e)e.insertAdjacentHTML('beforeend',html);}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
  const HONEST='<div class="honesty"><b>Honesty.</b> Every panel reads a live a11oy endpoint — no mock data. Λ is <b>Conjecture 1</b>, never a theorem. Proved formulas = <b>5</b> {F1,F11,F12,F18,F19}. SLSA <b>Build L2</b> on all 5 organ images. No L3 / FedRAMP / Iron Bank / CMMC. Receipts are real DSSE when a key is present, honest UNSIGNED otherwise.</div>';
167
 
@@ -242,22 +287,40 @@ const VIEWS={
242
  wires:{title:'Wires · The Constitution',badge:'LIVE',sub:'The mesh is the constitution: five wires that bind the organs into one signed organism. Each row reads the live mesh-state endpoint. Honest labels distinguish a cross-Space wire from an in-process one.',
243
  render:async(c)=>{c.innerHTML=`<div class="btns"><button class="btn teal" onclick="wires_load()">▶ Refresh the mesh</button></div><div id="wires-host"><div class="row mono dim">loading…</div></div>${HONEST}`;window.wires_load();}},
244
  mesh:{title:'Mesh Reach',badge:'5 ORGANS',sub:'Live per-organ reachability probes from a11oy to every flagship\u2019s public health endpoint. Real URL + HTTP code + latency. An unreachable organ is shown honestly — never faked green.',
245
- render:async(c)=>{c.innerHTML=`<div class="btns"><button class="btn teal" onclick="mesh_load()">▶ Probe all organs</button></div><div id="mesh-host"><div class="row mono dim">probing…</div></div>${HONEST}`;window.mesh_load();}},
 
 
246
  formulas:{title:'PURIQ Formulas',badge:'23 AGENTS',sub:'The 23 FormulaAgents. The proved set — exactly five {F1,F11,F12,F18,F19}, Lean sorry-free — is honestly distinguished from the open conjectures, including Λ (F23), which is Conjecture 1, never a theorem.',
247
- render:async(c)=>{c.innerHTML=`<div class="card"><div class="card-h"><span class="card-t">Formula registry</span><span class="card-ep">/v1/puriq/formulas</span></div><pre class="out" id="f-out">loading…</pre></div>${HONEST}`;
248
- try{const d=await getJSON(API+'/v1/puriq/formulas');setOut('f-out',d);}catch(e){setOut('f-out','Proved (Lean, sorry-free): F1, F11, F12, F18, F19 (5).\nΛ = F23 = Conjecture 1 — NOT a theorem.\nAll other F-numbers: open / roadmap.\n(live registry endpoint retrying: '+e.message+')');}}},
 
 
 
 
 
 
249
  evidence:{title:'Evidence Ledger',badge:'LEAN-ANCHORED',sub:'The audit trail anchored to the lutar-lean repository: declarations, axioms, sorries, and the assertion suite — read live from the evidence endpoint.',
250
  render:async(c)=>{c.innerHTML=`<div class="card"><div class="card-h"><span class="card-t">Evidence</span><span class="card-ep">/v1/evidence</span></div><pre class="out" id="e-out">loading…</pre></div>${HONEST}`;
251
  try{setOut('e-out',await getJSON(API+'/v1/evidence'));}catch(e){setOut('e-out','retrying… '+e.message);}}},
252
  llm:{title:'LLM Router',badge:'5-TIER',sub:'The five-tier model roster a11oy routes through. A real model call when a key is present, an honest stub otherwise — the tier selection and Λ-receipt are always real.',
253
- render:async(c)=>{c.innerHTML=`<div class="card"><div class="card-h"><span class="card-t">Model tiers</span><span class="card-ep">/v1/llm/tiers</span></div><pre class="out" id="l-out">loading…</pre></div>${HONEST}`;
254
- try{setOut('l-out',await getJSON(API+'/v1/llm/tiers').catch(()=>getJSON('/api/amaru/v1/llm/tiers')));}catch(e){setOut('l-out','5-tier router (real call when a model key is present; honest stub otherwise). retrying… '+e.message);}}},
 
 
 
 
 
255
  gates:{title:'Policy Gates',badge:'49 GATES',sub:'Every policy gate the orchestrator composes \u2014 each named to a Lean theorem and file. lean_status and lean_verified are reported honestly: \u201creal\u201d means a Lean theorem exists; verified=false means it is not yet sorry-free.',
256
  render:async(c)=>{c.innerHTML=`<div class="kpis"><div class="kpi"><div class="k">Gates</div><div class="v" id="g-count">\u2014</div></div><div class="kpi"><div class="k">Lean-verified</div><div class="v teal" id="g-ver">\u2014</div><div class="d">sorry-free</div></div><div class="kpi"><div class="k">Lean-cited</div><div class="v" id="g-cite">\u2014</div><div class="d">theorem named</div></div></div>
257
- <div class="card"><div class="card-h"><span class="card-t">Gate registry</span><span class="card-ep">/v1/gates</span></div><div id="g-host"><div class="row mono dim">loading\u2026</div></div></div>${HONEST}`;window.gates_load();}},
 
258
  lambda:{title:'\u039b Trust Axes',badge:'13 AXES',sub:'The 13-axis trust vector and the aggregate \u039b the gate floor evaluates. \u039b is Conjecture 1 (NOT a theorem): the aggregator is one honest choice, not a uniquely-pinned function \u2014 shown via the uniqueness field.',
259
  render:async(c)=>{c.innerHTML=`<div class="kpis"><div class="kpi"><div class="k">\u039b aggregate</div><div class="v teal" id="la-val">\u2014</div></div><div class="kpi"><div class="k">Floor</div><div class="v" id="la-floor">\u2014</div></div><div class="kpi"><div class="k">Gate</div><div class="v" id="la-pass">\u2014</div></div><div class="kpi"><div class="k">Uniqueness</div><div class="v warn">Conjecture 1</div></div></div>
260
- <div class="card"><div class="card-h"><span class="card-t">Per-axis scores</span><span class="card-ep">/v1/lambda</span></div><div id="la-host"><div class="row mono dim">loading\u2026</div></div></div>${HONEST}`;window.lambda_load();}},
 
 
 
 
261
  audit:{title:'Audit Log',badge:'RING BUFFER',sub:'The orchestrator\u2019s in-memory audit ring (maxlen 200, resets on rebuild \u2014 disclosed honestly). Every governed decision a11oy makes lands here; durable storage is on the tower/UDS deploy, not the HF Space.',
262
  render:async(c)=>{c.innerHTML=`<div class="btns"><button class="btn teal" onclick="audit_load()">\u25b6 Refresh log</button></div><div class="card"><div class="card-h"><span class="card-t">Recent governed decisions</span><span class="card-ep">/v1/audit-log</span></div><pre class="out" id="o-audit">loading\u2026</pre></div>${HONEST}`;window.audit_load();}},
263
  brain:{title:'Brain \u00b7 Gate Composition',badge:'LIVE',sub:'How the orchestrating brain composes governance: the gate-composition rules, the \u039b floor, and the formula roster it draws on. This is the wiring diagram of the decision substrate, read live.',
@@ -291,7 +354,17 @@ async function obs_load(){try{const d=await getJSON(API+'/v1/observability/summa
291
  async function wires_load(){try{const d=await getJSON(API+'/v1/mesh/state');const w=d.wires||{};setHTML('wires-host','');
292
  Object.entries(w).forEach(([k,v])=>addHTML('wires-host',`<div class="card"><div class="card-h"><span class="badge b-teal">Wire ${k}</span><span class="card-t">${esc(v.edge)}</span><span class="spacer badge ${String(v.status).includes('PROCESS')?'b-gold':'b-live'}">${esc(v.status)}</span></div><div class="mono" style="font-size:11.5px;color:var(--paragraph)">${esc(v.detail)}</div></div>`));}catch(e){setHTML('wires-host','<div class="row mono dim">retry: '+e.message+'</div>');}}
293
  // mesh
294
- async function mesh_load(){try{const d=await getJSON(API+'/v1/observability/summary');const mr=d.mesh_reach||{};setHTML('mesh-host','');
 
 
 
 
 
 
 
 
 
 
295
  if(!Object.keys(mr).length){setHTML('mesh-host','<pre class="out">'+esc(JSON.stringify(d,null,2))+'</pre>');return;}
296
  Object.entries(mr).forEach(([k,v])=>addHTML('mesh-host',`<div class="row"><span class="badge ${(v.status==='ok')?'b-live':'b-err'}">${esc(v.status)}</span><span>${esc(k)}</span><span class="spacer mono dim">${v.latency_ms?Math.round(v.latency_ms)+'ms':''} · ${esc(v.url||'')}</span></div>`));}catch(e){setHTML('mesh-host','<div class="row mono dim">retry: '+e.message+'</div>');}}
297
 
@@ -315,11 +388,16 @@ async function mcp_call(name){try{setOut('o-mcp','invoking '+name+'\u2026');
315
  : {receipt:{actionId:'mcp-demo'}};
316
  const d=await postJSON(API+'/v1/mcp/call',{name,arguments:args});setOut('o-mcp','TOOL '+esc(d.tool||name)+' \u00b7 '+esc(d.status||'')+' \u00b7 kernel '+esc(d.kernel_commit||'')+'\n\n'+JSON.stringify(d,null,2));}catch(e){setOut('o-mcp','retry: '+e.message);}}
317
  async function gates_load(){try{const d=await getJSON(API+'/v1/gates');const g=d.gates||[];setTxt('g-count',d.count||g.length);
318
- const ver=g.filter(x=>x.lean_verified===true).length;const cite=g.filter(x=>x.lean_theorem).length;setTxt('g-ver',ver);setTxt('g-cite',cite);
 
319
  setHTML('g-host','');g.slice(0,60).forEach(x=>{const v=x.lean_verified===true;addHTML('g-host',`<div class="row"><span class="badge ${v?'b-live':'b-gold'}">${v?'VERIFIED':(x.lean_status||'real')}</span><span>${esc(x.name)}</span><span class="spacer mono dim">${esc(x.lean_theorem||'')}</span></div>`);});
320
  addHTML('g-host',`<div class="row"><span class="mono dim">Honest: \u201creal\u201d = a Lean theorem is named; \u201cVERIFIED\u201d = sorry-free. Most gates cite a theorem; few are sorry-free yet \u2014 shown truthfully.</span></div>`);}catch(e){setHTML('g-host','<div class="row mono dim">retry: '+esc(e.message)+'</div>');}}
321
- async function lambda_load(){try{const d=await getJSON(API+'/v1/lambda');setTxt('la-val',(d.lambda!=null?d.lambda.toFixed?d.lambda.toFixed(4):d.lambda:'\u2014'));setTxt('la-floor',d.lambda_floor??'\u2014');setTxt('la-pass',d.pass?'ALLOW':(d.pass===false?'DENY':'\u2014'));
322
- const axes=d.axes||[];setHTML('la-host','');axes.forEach(a=>{const pct=Math.round((a.score||0)*100);addHTML('la-host',`<div class="row"><span style="min-width:9rem">${esc(a.name)}</span><span style="flex:1;height:7px;background:#161616;border-radius:4px;overflow:hidden"><span style="display:block;height:100%;width:${pct}%;background:linear-gradient(90deg,var(--teal),var(--gold))"></span></span><span class="mono dim" style="min-width:3rem;text-align:right">${(a.score||0).toFixed(2)}</span></div>`);});}catch(e){setHTML('la-host','<div class="row mono dim">retry: '+esc(e.message)+'</div>');}}
 
 
 
 
323
  async function audit_load(){try{const d=await getJSON(API+'/v1/audit-log');const e=d.entries||[];setOut('o-audit',e.length?JSON.stringify(d,null,2):'Audit ring is empty (total_buffered '+(d.total_buffered??0)+'). '+(d.note||'')+'\n\nRun a Superpower or Reasoner action, then refresh \u2014 governed decisions append here.');}catch(e){setOut('o-audit','retry: '+e.message);}}
324
  async function brain_load(){try{const d=await getJSON(API+'/v1/brain');const b=d.brain||{};setHTML('br-host','');
325
  addHTML('br-host',`<div class="row"><span>Role</span><span class="spacer b-gold badge">${esc(b.role||'')}</span></div>`);
@@ -343,6 +421,9 @@ async function honest_load(){try{const d=await getJSON(API+'/v1/honest');const d
343
  setOut('o-honest',d);}catch(e){setHTML('ho-host','<div class="row mono dim">retry: '+esc(e.message)+'</div>');}}
344
 
345
  function go(view){
 
 
 
346
  document.querySelectorAll('.nav-item').forEach(n=>n.classList.toggle('active',n.dataset.view===view));
347
  const v=VIEWS[view];const c=el('content');
348
  c.innerHTML=`<div class="view-head"><h1 class="view-title">${v.title}</h1><span class="view-badge">${v.badge}</span></div><p class="view-sub">${v.sub}</p><div id="vbody"></div>`;
 
7
  <meta name="description" content="a11oy is the orchestrating brain of the SZL governed-AI substrate: a full operator application — command center, five superpowers, Warhacker orchestration, observability, the constitution (wires), formulas, and the evidence ledger. Every view reads a live endpoint."/>
8
  <link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
9
  <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
10
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/3d-force-graph@1.73.4/dist/3d-force-graph.min.js"></script>
12
  <style>/* ============ SZL UNIFIED APP SHELL — house style (gold+teal on dark) ============ */
13
  /* Shared by all 5 flagship full-applications. One product family. */
14
  :root{
 
105
  .menu-btn{display:inline-flex!important;}
106
  }
107
  .menu-btn{display:none;background:none;border:1px solid var(--gold-line);color:var(--gold);border-radius:6px;padding:.2rem .5rem;cursor:pointer;font-family:var(--mono);font-size:11px;}
108
+ /* ===== VISUALS ===== */
109
+ .chartbox{position:relative;height:260px;width:100%;}
110
+ .chartbox.tall{height:320px;}
111
+ .graph3d{height:420px;width:100%;border-radius:9px;background:radial-gradient(circle at 50% 40%,#0c1410,#070707);overflow:hidden;border:1px solid var(--gold-line);}
112
+ .gauge-wrap{display:flex;align-items:center;gap:1.4rem;flex-wrap:wrap;}
113
+ .gauge{position:relative;width:150px;height:150px;}
114
+ .gauge .lbl{position:absolute;inset:0;display:grid;place-items:center;flex-direction:column;text-align:center;}
115
+ .gauge .lbl .big{font-size:1.8rem;font-weight:600;color:var(--gold);line-height:1;}
116
+ .gauge .lbl .sm{font-family:var(--mono);font-size:9px;color:var(--muted);letter-spacing:.12em;text-transform:uppercase;margin-top:.2rem;}
117
+ .legend{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:.6rem;font-family:var(--mono);font-size:10px;color:var(--muted);}
118
+ .legend i{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:.35rem;vertical-align:middle;}
119
+ .spark{height:46px;width:100%;}
120
+ .bar-track{flex:1;height:9px;background:#161616;border-radius:5px;overflow:hidden;}
121
+ .bar-fill{display:block;height:100%;background:linear-gradient(90deg,var(--teal),var(--gold));border-radius:5px;transition:width .6s cubic-bezier(.2,.8,.2,1);}
122
+ details.raw{margin-top:1rem;}
123
+ details.raw summary{cursor:pointer;font-family:var(--mono);font-size:10px;color:var(--dim);letter-spacing:.1em;text-transform:uppercase;}
124
+ details.raw[open] summary{color:var(--muted);}
125
  </style>
126
  </head>
127
  <body>
 
181
  function setHTML(id,html){const e=el(id);if(e)e.innerHTML=html;}
182
  function setTxt(id,t){const e=el(id);if(e)e.textContent=t;}
183
  function addHTML(id,html){const e=el(id);if(e)e.insertAdjacentHTML('beforeend',html);}
184
+ // ===== VISUAL HELPERS (Chart.js + 3d-force-graph) =====
185
+ const GOLD='#c9b787',TEAL='#5fb3a3',CREAM='#f5f5f5',DIM='#555',GRID='rgba(201,183,135,0.08)';
186
+ let _charts={};
187
+ function killChart(id){if(_charts[id]){try{_charts[id].destroy();}catch(e){}delete _charts[id];}}
188
+ function mkChart(id,cfg){const cv=el(id);if(!cv||!window.Chart)return;killChart(id);
189
+ Chart.defaults.color=DIM;Chart.defaults.font.family="'JetBrains Mono',monospace";Chart.defaults.font.size=10;
190
+ _charts[id]=new Chart(cv.getContext('2d'),cfg);return _charts[id];}
191
+ // doughnut gauge 0..1
192
+ function gauge(id,val,label,color){const v=Math.max(0,Math.min(1,val||0));
193
+ mkChart(id,{type:'doughnut',data:{datasets:[{data:[v,1-v],backgroundColor:[color||GOLD,'#191919'],borderWidth:0,circumference:270,rotation:225}]},
194
+ options:{cutout:'76%',plugins:{legend:{display:false},tooltip:{enabled:false}},responsive:true,maintainAspectRatio:false,animation:{duration:900}}});}
195
+ function radar(id,labels,data,label){mkChart(id,{type:'radar',data:{labels,datasets:[{label:label||'',data,fill:true,backgroundColor:'rgba(95,179,163,0.18)',borderColor:TEAL,pointBackgroundColor:GOLD,borderWidth:1.5,pointRadius:2}]},
196
+ options:{scales:{r:{min:0,max:1,grid:{color:GRID},angleLines:{color:GRID},pointLabels:{color:'#9a9a9a',font:{size:9}},ticks:{display:false}}},plugins:{legend:{display:false}},responsive:true,maintainAspectRatio:false}});}
197
+ function barH(id,labels,data,colors){mkChart(id,{type:'bar',data:{labels,datasets:[{data,backgroundColor:colors||TEAL,borderRadius:4,barThickness:14}]},
198
+ options:{indexAxis:'y',scales:{x:{grid:{color:GRID},ticks:{color:DIM}},y:{grid:{display:false},ticks:{color:'#9a9a9a',font:{size:9}}}},plugins:{legend:{display:false}},responsive:true,maintainAspectRatio:false}});}
199
+ function lineSpark(id,labels,data,color){mkChart(id,{type:'line',data:{labels,datasets:[{data,borderColor:color||TEAL,backgroundColor:'rgba(95,179,163,0.12)',fill:true,tension:.35,pointRadius:0,borderWidth:1.6}]},
200
+ options:{scales:{x:{display:false},y:{display:false}},plugins:{legend:{display:false},tooltip:{enabled:false}},responsive:true,maintainAspectRatio:false}});}
201
+ function doughnut(id,labels,data,colors){mkChart(id,{type:'doughnut',data:{labels,datasets:[{data,backgroundColor:colors,borderColor:'#0a0a0a',borderWidth:2}]},
202
+ options:{cutout:'62%',plugins:{legend:{display:false},tooltip:{enabled:true}},responsive:true,maintainAspectRatio:false}});}
203
+ let _fg=null;
204
+ function mesh3d(id,nodes,links){const host=el(id);if(!host||!window.ForceGraph3D)return;host.innerHTML='';
205
+ try{_fg=ForceGraph3D()(host).backgroundColor('rgba(0,0,0,0)').width(host.clientWidth).height(host.clientHeight)
206
+ .graphData({nodes,links}).nodeLabel('name').nodeColor(n=>n.color||TEAL).nodeVal(n=>n.val||4)
207
+ .linkColor(()=>'rgba(201,183,135,0.45)').linkWidth(1.2).linkDirectionalParticles(2).linkDirectionalParticleSpeed(0.006).linkDirectionalParticleColor(()=>TEAL)
208
+ .showNavInfo(false);
209
+ setTimeout(()=>{try{_fg.width(host.clientWidth).height(host.clientHeight);}catch(e){}},300);}catch(e){host.innerHTML='<div class="row mono dim" style="padding:1rem">3D init: '+e.message+'</div>';}}
210
 
211
  const HONEST='<div class="honesty"><b>Honesty.</b> Every panel reads a live a11oy endpoint — no mock data. Λ is <b>Conjecture 1</b>, never a theorem. Proved formulas = <b>5</b> {F1,F11,F12,F18,F19}. SLSA <b>Build L2</b> on all 5 organ images. No L3 / FedRAMP / Iron Bank / CMMC. Receipts are real DSSE when a key is present, honest UNSIGNED otherwise.</div>';
212
 
 
287
  wires:{title:'Wires · The Constitution',badge:'LIVE',sub:'The mesh is the constitution: five wires that bind the organs into one signed organism. Each row reads the live mesh-state endpoint. Honest labels distinguish a cross-Space wire from an in-process one.',
288
  render:async(c)=>{c.innerHTML=`<div class="btns"><button class="btn teal" onclick="wires_load()">▶ Refresh the mesh</button></div><div id="wires-host"><div class="row mono dim">loading…</div></div>${HONEST}`;window.wires_load();}},
289
  mesh:{title:'Mesh Reach',badge:'5 ORGANS',sub:'Live per-organ reachability probes from a11oy to every flagship\u2019s public health endpoint. Real URL + HTTP code + latency. An unreachable organ is shown honestly — never faked green.',
290
+ render:async(c)=>{c.innerHTML=`<div class="btns"><button class="btn teal" onclick="mesh_load()">▶ Re-probe + rebuild graph</button></div>
291
+ <div class="card"><div class="card-h"><span class="card-t">Organism — live 3D mesh</span><span class="card-ep">drag to orbit</span></div><div class="graph3d" id="mesh-3d"></div></div>
292
+ <div class="card"><div class="card-h"><span class="card-t">Per-organ reachability</span><span class="card-ep">/v1/observability/summary</span></div><div id="mesh-host"><div class="row mono dim">probing…</div></div></div>${HONEST}`;window.mesh_load();}},
293
  formulas:{title:'PURIQ Formulas',badge:'23 AGENTS',sub:'The 23 FormulaAgents. The proved set — exactly five {F1,F11,F12,F18,F19}, Lean sorry-free — is honestly distinguished from the open conjectures, including Λ (F23), which is Conjecture 1, never a theorem.',
294
+ render:async(c)=>{c.innerHTML=`<div class="kpis"><div class="kpi"><div class="k">Agents</div><div class="v" id="f-n">23</div></div><div class="kpi"><div class="k">Proved (locked)</div><div class="v teal" id="f-proved">5</div><div class="d">Lean sorry-free</div></div><div class="kpi"><div class="k">\u039b (F23)</div><div class="v warn">Conjecture 1</div><div class="d">NOT a theorem</div></div></div>
295
+ <div class="grid2"><div class="card"><div class="card-h"><span class="card-t">Proof status (locked kernel)</span><span class="card-ep">/v1/puriq/formulas</span></div><div class="chartbox"><canvas id="f-donut"></canvas></div><div class="legend"><span><i style="background:#5fb3a3"></i>proved {F1,F11,F12,F18,F19}</span><span><i style="background:#c9b787"></i>open / roadmap</span><span><i style="background:#b06a5a"></i>\u039b F23 conjecture</span></div></div>
296
+ <div class="card"><div class="card-h"><span class="card-t">Harness</span><span class="card-ep">live</span></div><div id="f-host"><div class="row mono dim">loading\u2026</div></div></div></div>
297
+ <details class="raw"><summary>raw /v1/puriq/formulas</summary><pre class="out" id="f-out">loading…</pre></details>${HONEST}`;
298
+ try{const d=await getJSON(API+'/v1/puriq/formulas');setOut('f-out',d);
299
+ const n=d.summary?.n_agents||23;setTxt('f-n',n);doughnut('f-donut',['proved','open','\u039b F23'],[5,Math.max(0,n-6),1],[TEAL,GOLD,'#b06a5a']);
300
+ const s=d.summary||{};setHTML('f-host',`<div class="row"><span>Agents</span><span class="spacer b-gold badge">${esc(s.n_agents??23)}</span></div><div class="row"><span>Harness baseline</span><span class="spacer mono dim">${esc(s.harness_baseline??'')}</span></div><div class="row"><span>\u039b status</span><span class="spacer badge b-err">Conjecture 1</span></div>`);}
301
+ catch(e){doughnut('f-donut',['proved','open','\u039b F23'],[5,17,1],[TEAL,GOLD,'#b06a5a']);setHTML('f-host','<div class="row mono dim">Proved sorry-free: F1,F11,F12,F18,F19 (5). \u039b=F23=Conjecture 1. retry: '+esc(e.message)+'</div>');setOut('f-out','retry: '+e.message);}}},
302
  evidence:{title:'Evidence Ledger',badge:'LEAN-ANCHORED',sub:'The audit trail anchored to the lutar-lean repository: declarations, axioms, sorries, and the assertion suite — read live from the evidence endpoint.',
303
  render:async(c)=>{c.innerHTML=`<div class="card"><div class="card-h"><span class="card-t">Evidence</span><span class="card-ep">/v1/evidence</span></div><pre class="out" id="e-out">loading…</pre></div>${HONEST}`;
304
  try{setOut('e-out',await getJSON(API+'/v1/evidence'));}catch(e){setOut('e-out','retrying… '+e.message);}}},
305
  llm:{title:'LLM Router',badge:'5-TIER',sub:'The five-tier model roster a11oy routes through. A real model call when a key is present, an honest stub otherwise — the tier selection and Λ-receipt are always real.',
306
+ render:async(c)=>{c.innerHTML=`<div class="grid2"><div class="card"><div class="card-h"><span class="card-t">Tier throughput</span><span class="card-ep">/v1/router/stats</span></div><div class="chartbox"><canvas id="l-bars"></canvas></div></div>
307
+ <div class="card"><div class="card-h"><span class="card-t">Model roster</span><span class="card-ep">/v1/llm/tiers</span></div><div id="l-host" style="max-height:300px;overflow-y:auto"><div class="row mono dim">loading\u2026</div></div></div></div>
308
+ <details class="raw"><summary>raw /v1/llm/tiers</summary><pre class="out" id="l-out">loading…</pre></details>${HONEST}`;
309
+ try{const d=await getJSON(API+'/v1/llm/tiers').catch(()=>getJSON('/api/amaru/v1/llm/tiers'));setOut('l-out',d);
310
+ const tiers=d.tiers||[];setHTML('l-host','');tiers.forEach(t=>addHTML('l-host',`<div class="row"><span class="badge b-teal">T${esc(t.rank??'')}</span><span>${esc(t.id||t.model||'')}</span><span class="spacer mono dim">${esc(t.use||'')}</span></div>`));}
311
+ catch(e){setHTML('l-host','<div class="row mono dim">retry: '+esc(e.message)+'</div>');setOut('l-out','retry: '+e.message);}
312
+ try{const r=await getJSON(API+'/v1/router/stats');const routes=r.routes||[];barH('l-bars',routes.map(x=>x.organ+' \u00b7 '+(x.tier||'')),routes.map(x=>x.throughput||0),routes.map(x=>x.license==='GREEN'?TEAL:GOLD));}catch(e){}}},
313
  gates:{title:'Policy Gates',badge:'49 GATES',sub:'Every policy gate the orchestrator composes \u2014 each named to a Lean theorem and file. lean_status and lean_verified are reported honestly: \u201creal\u201d means a Lean theorem exists; verified=false means it is not yet sorry-free.',
314
  render:async(c)=>{c.innerHTML=`<div class="kpis"><div class="kpi"><div class="k">Gates</div><div class="v" id="g-count">\u2014</div></div><div class="kpi"><div class="k">Lean-verified</div><div class="v teal" id="g-ver">\u2014</div><div class="d">sorry-free</div></div><div class="kpi"><div class="k">Lean-cited</div><div class="v" id="g-cite">\u2014</div><div class="d">theorem named</div></div></div>
315
+ <div class="grid2"><div class="card"><div class="card-h"><span class="card-t">Lean status mix</span><span class="card-ep">/v1/gates</span></div><div class="chartbox"><canvas id="g-donut"></canvas></div><div class="legend"><span><i style="background:#5fb3a3"></i>verified (sorry-free)</span><span><i style="background:#c9b787"></i>cited (theorem named)</span><span><i style="background:#b06a5a"></i>phantom (no theorem)</span></div></div>
316
+ <div class="card"><div class="card-h"><span class="card-t">Gate registry</span><span class="card-ep">live</span></div><div id="g-host" style="max-height:300px;overflow-y:auto"><div class="row mono dim">loading\u2026</div></div></div></div>${HONEST}`;window.gates_load();}},
317
  lambda:{title:'\u039b Trust Axes',badge:'13 AXES',sub:'The 13-axis trust vector and the aggregate \u039b the gate floor evaluates. \u039b is Conjecture 1 (NOT a theorem): the aggregator is one honest choice, not a uniquely-pinned function \u2014 shown via the uniqueness field.',
318
  render:async(c)=>{c.innerHTML=`<div class="kpis"><div class="kpi"><div class="k">\u039b aggregate</div><div class="v teal" id="la-val">\u2014</div></div><div class="kpi"><div class="k">Floor</div><div class="v" id="la-floor">\u2014</div></div><div class="kpi"><div class="k">Gate</div><div class="v" id="la-pass">\u2014</div></div><div class="kpi"><div class="k">Uniqueness</div><div class="v warn">Conjecture 1</div></div></div>
319
+ <div class="grid2">
320
+ <div class="card"><div class="card-h"><span class="card-t">\u039b aggregate gauge</span><span class="card-ep">/v1/lambda</span></div><div class="gauge-wrap" style="justify-content:center"><div class="gauge"><canvas id="la-gauge"></canvas><div class="lbl"><div><div class="big" id="la-gbig">\u2014</div><div class="sm">\u039b vs floor 0.90</div></div></div></div></div></div>
321
+ <div class="card"><div class="card-h"><span class="card-t">13-axis trust radar</span><span class="card-ep">live</span></div><div class="chartbox"><canvas id="la-radar"></canvas></div></div>
322
+ </div>
323
+ <div class="card"><div class="card-h"><span class="card-t">Per-axis scores</span></div><div class="chartbox tall"><canvas id="la-bars"></canvas></div><div id="la-host" style="margin-top:.6rem"></div></div>${HONEST}`;window.lambda_load();}},
324
  audit:{title:'Audit Log',badge:'RING BUFFER',sub:'The orchestrator\u2019s in-memory audit ring (maxlen 200, resets on rebuild \u2014 disclosed honestly). Every governed decision a11oy makes lands here; durable storage is on the tower/UDS deploy, not the HF Space.',
325
  render:async(c)=>{c.innerHTML=`<div class="btns"><button class="btn teal" onclick="audit_load()">\u25b6 Refresh log</button></div><div class="card"><div class="card-h"><span class="card-t">Recent governed decisions</span><span class="card-ep">/v1/audit-log</span></div><pre class="out" id="o-audit">loading\u2026</pre></div>${HONEST}`;window.audit_load();}},
326
  brain:{title:'Brain \u00b7 Gate Composition',badge:'LIVE',sub:'How the orchestrating brain composes governance: the gate-composition rules, the \u039b floor, and the formula roster it draws on. This is the wiring diagram of the decision substrate, read live.',
 
354
  async function wires_load(){try{const d=await getJSON(API+'/v1/mesh/state');const w=d.wires||{};setHTML('wires-host','');
355
  Object.entries(w).forEach(([k,v])=>addHTML('wires-host',`<div class="card"><div class="card-h"><span class="badge b-teal">Wire ${k}</span><span class="card-t">${esc(v.edge)}</span><span class="spacer badge ${String(v.status).includes('PROCESS')?'b-gold':'b-live'}">${esc(v.status)}</span></div><div class="mono" style="font-size:11.5px;color:var(--paragraph)">${esc(v.detail)}</div></div>`));}catch(e){setHTML('wires-host','<div class="row mono dim">retry: '+e.message+'</div>');}}
356
  // mesh
357
+ async function mesh_load(){
358
+ try{const d=await getJSON(API+'/v1/observability/summary');const mrArr=Object.values(d.mesh_reach||{});
359
+ const names=['a11oy','sentra','amaru','rosie','killinchu'];
360
+ const nodes=[{id:'a11oy',name:'a11oy (orchestrator)',color:GOLD,val:14}];
361
+ const links=[];
362
+ mrArr.forEach((p,i)=>{const nm=names[i]||('organ'+i);if(nm==='a11oy')return;const up=p.status==='ok';
363
+ nodes.push({id:nm,name:nm+(up?' \u00b7 ok '+(p.latency_ms?Math.round(p.latency_ms)+'ms':''):' \u00b7 unreachable'),color:up?TEAL:'#b06a5a',val:7});
364
+ links.push({source:'a11oy',target:nm});});
365
+ mesh3d('mesh-3d',nodes,links);
366
+ }catch(e){const h=el('mesh-3d');if(h)h.innerHTML='<div class="row mono dim" style="padding:1rem">graph retry: '+esc(e.message)+'</div>';}
367
+ try{const d=await getJSON(API+'/v1/observability/summary');const mr=d.mesh_reach||{};setHTML('mesh-host','');
368
  if(!Object.keys(mr).length){setHTML('mesh-host','<pre class="out">'+esc(JSON.stringify(d,null,2))+'</pre>');return;}
369
  Object.entries(mr).forEach(([k,v])=>addHTML('mesh-host',`<div class="row"><span class="badge ${(v.status==='ok')?'b-live':'b-err'}">${esc(v.status)}</span><span>${esc(k)}</span><span class="spacer mono dim">${v.latency_ms?Math.round(v.latency_ms)+'ms':''} · ${esc(v.url||'')}</span></div>`));}catch(e){setHTML('mesh-host','<div class="row mono dim">retry: '+e.message+'</div>');}}
370
 
 
388
  : {receipt:{actionId:'mcp-demo'}};
389
  const d=await postJSON(API+'/v1/mcp/call',{name,arguments:args});setOut('o-mcp','TOOL '+esc(d.tool||name)+' \u00b7 '+esc(d.status||'')+' \u00b7 kernel '+esc(d.kernel_commit||'')+'\n\n'+JSON.stringify(d,null,2));}catch(e){setOut('o-mcp','retry: '+e.message);}}
390
  async function gates_load(){try{const d=await getJSON(API+'/v1/gates');const g=d.gates||[];setTxt('g-count',d.count||g.length);
391
+ const ver=g.filter(x=>x.lean_verified===true).length;const cite=g.filter(x=>x.lean_theorem&&x.lean_verified!==true).length;const phantom=g.length-ver-cite;setTxt('g-ver',ver);setTxt('g-cite',g.filter(x=>x.lean_theorem).length);
392
+ doughnut('g-donut',['verified','cited','phantom'],[ver,cite,Math.max(0,phantom)],[TEAL,GOLD,'#b06a5a']);
393
  setHTML('g-host','');g.slice(0,60).forEach(x=>{const v=x.lean_verified===true;addHTML('g-host',`<div class="row"><span class="badge ${v?'b-live':'b-gold'}">${v?'VERIFIED':(x.lean_status||'real')}</span><span>${esc(x.name)}</span><span class="spacer mono dim">${esc(x.lean_theorem||'')}</span></div>`);});
394
  addHTML('g-host',`<div class="row"><span class="mono dim">Honest: \u201creal\u201d = a Lean theorem is named; \u201cVERIFIED\u201d = sorry-free. Most gates cite a theorem; few are sorry-free yet \u2014 shown truthfully.</span></div>`);}catch(e){setHTML('g-host','<div class="row mono dim">retry: '+esc(e.message)+'</div>');}}
395
+ async function lambda_load(){try{const d=await getJSON(API+'/v1/lambda');const L=d.lambda||0;setTxt('la-val',L.toFixed?L.toFixed(4):L);setTxt('la-floor',d.lambda_floor??'\u2014');setTxt('la-pass',d.pass?'ALLOW':(d.pass===false?'DENY':'\u2014'));
396
+ const axes=d.axes||[];const labels=axes.map(a=>a.name);const vals=axes.map(a=>a.score||0);
397
+ gauge('la-gauge',L,'\u039b',L>=(d.lambda_floor||0.9)?TEAL:'#b06a5a');setTxt('la-gbig',(L.toFixed?L.toFixed(3):L));
398
+ radar('la-radar',labels,vals);
399
+ barH('la-bars',labels,vals,vals.map(v=>v>=0.9?TEAL:(v>=0.7?GOLD:'#b06a5a')));
400
+ setHTML('la-host','<details class="raw"><summary>raw /v1/lambda</summary><pre class="out">'+esc(JSON.stringify(d,null,2))+'</pre></details>');}catch(e){setHTML('la-host','<div class="row mono dim">retry: '+esc(e.message)+'</div>');}}
401
  async function audit_load(){try{const d=await getJSON(API+'/v1/audit-log');const e=d.entries||[];setOut('o-audit',e.length?JSON.stringify(d,null,2):'Audit ring is empty (total_buffered '+(d.total_buffered??0)+'). '+(d.note||'')+'\n\nRun a Superpower or Reasoner action, then refresh \u2014 governed decisions append here.');}catch(e){setOut('o-audit','retry: '+e.message);}}
402
  async function brain_load(){try{const d=await getJSON(API+'/v1/brain');const b=d.brain||{};setHTML('br-host','');
403
  addHTML('br-host',`<div class="row"><span>Role</span><span class="spacer b-gold badge">${esc(b.role||'')}</span></div>`);
 
421
  setOut('o-honest',d);}catch(e){setHTML('ho-host','<div class="row mono dim">retry: '+esc(e.message)+'</div>');}}
422
 
423
  function go(view){
424
+ // tear down any live charts / 3D graph from the previous view to avoid canvas reuse errors
425
+ Object.keys(_charts).forEach(killChart);
426
+ if(_fg){try{_fg._destructor&&_fg._destructor();}catch(e){}_fg=null;}
427
  document.querySelectorAll('.nav-item').forEach(n=>n.classList.toggle('active',n.dataset.view===view));
428
  const v=VIEWS[view];const c=el('content');
429
  c.innerHTML=`<div class="view-head"><h1 class="view-title">${v.title}</h1><span class="view-badge">${v.badge}</span></div><p class="view-sub">${v.sub}</p><div id="vbody"></div>`;