a11oy / pages /cockpit.html
betterwithage's picture
deploy(hf): sync szl-holdings/a11oy@ac02db5a10e5b3d4c9b2260674111ff2335888bf derived COPY set
55e5019 verified
Raw
History Blame Contribute Delete
21.5 kB
<!DOCTYPE html>
<!--
a11oy Command Cockpit — a single-screen LIVE health cockpit for the whole
organism. 0 runtime CDN, 0 build step, pure inline CSS/JS (doctrine: no
fabricated data). It reads ONE real aggregate feed:
GET /api/a11oy/v1/engine/status (schema: szl.engine_status/v1)
and renders the mind, the six organs, energy and swarm exactly as the server
reports them. Every value carries an honesty state: LIVE (reachable/ok),
DOWN (reachable=false), or SAMPLE/— when the server itself returns null. No
number is invented client-side; nulls render as "—", never as a guess.
Served by serve.py @app.get("/cockpit") (registered before the SPA catch-all);
shipped by the wholesale `COPY pages/ ./pages/` in the Dockerfile.
-->
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>a11oy — Command Cockpit</title>
<style>
:root{
--bg:#070b12; --panel:#0c111b; --panel2:#0f1624; --line:#1b2740;
--ink:#e8eefb; --mut:#8a99b8; --dim:#5c6a86;
--ok:#22c55e; --okglow:rgba(34,197,94,.45);
--warn:#f5a524; --down:#ef4444; --downglow:rgba(239,68,68,.4);
--accent:#5e6fff; --accent2:#26d0ce;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{
background:
radial-gradient(1100px 620px at 12% -10%, rgba(94,111,255,.14), transparent 60%),
radial-gradient(900px 520px at 100% 0%, rgba(38,208,206,.10), transparent 55%),
var(--bg);
color:var(--ink);
font:14px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
-webkit-font-smoothing:antialiased;
}
a{color:var(--accent2);text-decoration:none}
a:hover{text-decoration:underline}
.wrap{max-width:1180px;margin:0 auto;padding:28px 22px 60px}
header{display:flex;flex-wrap:wrap;align-items:baseline;gap:14px;margin-bottom:6px}
h1{font-size:22px;margin:0;letter-spacing:.5px}
h1 .glyph{color:var(--accent);text-shadow:0 0 16px rgba(94,111,255,.7)}
.sub{color:var(--mut);font-size:12.5px}
.bar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:14px 0 22px;
padding:10px 14px;border:1px solid var(--line);border-radius:12px;background:var(--panel)}
.pill{display:inline-flex;align-items:center;gap:7px;padding:4px 11px;border-radius:999px;
border:1px solid var(--line);background:var(--panel2);font-size:12px;color:var(--mut)}
.dot{width:8px;height:8px;border-radius:50%;background:var(--dim)}
.dot.ok{background:var(--ok);box-shadow:0 0 10px var(--okglow);animation:pulse 2.2s ease-in-out infinite}
.dot.down{background:var(--down);box-shadow:0 0 10px var(--downglow)}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}
.spacer{flex:1}
.refresh{color:var(--dim);font-size:11.5px}
.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:14px}
.card{grid-column:span 4;border:1px solid var(--line);border-radius:14px;
background:linear-gradient(180deg,var(--panel2),var(--panel));padding:16px 16px 14px;
position:relative;overflow:hidden}
.card.big{grid-column:span 8}
.card.small{grid-column:span 4}
@media(max-width:860px){.card,.card.big,.card.small{grid-column:span 12}}
.card h2{margin:0 0 2px;font-size:12px;letter-spacing:1.4px;text-transform:uppercase;color:var(--mut);font-weight:600}
.metric{font-size:34px;font-weight:700;letter-spacing:.5px;margin:6px 0 2px}
.metric .unit{font-size:15px;color:var(--mut);font-weight:500}
.foot{color:var(--dim);font-size:11.5px}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.chip{display:inline-flex;align-items:center;gap:7px;padding:6px 10px;border-radius:9px;
border:1px solid var(--line);background:#0a0f19;font-size:12px}
.chip .nm{color:var(--ink)}
.chip .st{margin-left:auto;font-size:10.5px;letter-spacing:.6px;color:var(--dim)}
.state-LIVE{color:var(--ok)} .state-DOWN{color:var(--down)} .state-NA{color:var(--dim)}
.kv{display:flex;justify-content:space-between;gap:12px;padding:6px 0;border-bottom:1px dashed var(--line)}
.kv:last-child{border-bottom:0}
.kv .k{color:var(--mut)} .kv .v{color:var(--ink)}
.honest{font-size:10.5px;letter-spacing:.7px;padding:2px 7px;border-radius:6px;border:1px solid var(--line);color:var(--dim)}
.honest.live{color:var(--ok);border-color:rgba(34,197,94,.35)}
.honest.sample{color:var(--warn);border-color:rgba(245,165,36,.3)}
.err{grid-column:span 12;border:1px solid rgba(239,68,68,.4);background:rgba(239,68,68,.06);
border-radius:12px;padding:14px 16px;color:#ffd7d7}
.section-head{display:flex;align-items:baseline;gap:12px;margin:26px 2px 12px;
padding-bottom:8px;border-bottom:1px solid var(--line)}
.section-title{font-size:13px;letter-spacing:1.6px;text-transform:uppercase;color:var(--ink);font-weight:700}
.section-sub{color:var(--mut);font-size:11.5px}
.spine-head{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:12px;
border:1px solid var(--line);border-radius:14px;padding:14px 16px;background:var(--panel);margin-bottom:12px}
.spine-hero{display:flex;align-items:baseline;gap:10px}
.spine-hero .big{font-size:36px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;line-height:1}
.spine-hero .lbl{color:var(--dim);font-size:12px;max-width:280px}
.spine-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px}
.spine-col{border:1px solid var(--line);border-radius:12px;padding:11px 13px;background:var(--panel)}
.spine-col-h{font-size:11px;letter-spacing:1.2px;text-transform:uppercase;color:var(--accent);
font-weight:700;margin-bottom:8px}
.spine-col-h .cnt{color:var(--dim);margin-left:5px;font-weight:600}
.tool{padding:6px 0;border-top:1px solid rgba(255,255,255,.045)}
.tool:first-of-type{border-top:none}
.tool .tn{display:block;font-size:11.5px;color:var(--ink);
font-family:ui-monospace,SFMono-Regular,Menlo,monospace;word-break:break-word}
.tool .td{display:block;font-size:11px;color:var(--dim);line-height:1.4;margin-top:1px}
.con{grid-column:span 3;border:1px solid var(--line);border-radius:12px;background:var(--panel2);
padding:13px 14px;display:flex;flex-direction:column;gap:6px;position:relative}
@media(max-width:860px){.con{grid-column:span 6}}
@media(max-width:560px){.con{grid-column:span 12}}
.con .top{display:flex;align-items:center;gap:8px}
.con .nm{font-weight:700;color:var(--ink);font-size:14px}
.con .kind{color:var(--mut);font-size:11.5px}
.con .blurb{color:var(--dim);font-size:11.5px;line-height:1.45;margin-top:2px}
.con .chips{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}
.con .chip{font-size:10px;letter-spacing:.3px;padding:2px 6px;border-radius:5px;
background:rgba(94,111,255,.10);border:1px solid rgba(94,111,255,.22);color:var(--dim);
font-variant-numeric:tabular-nums;white-space:nowrap}
.con .chip.ok{background:rgba(52,199,132,.12);border-color:rgba(52,199,132,.30);color:#8fe6b8}
.con .chip.down{background:rgba(255,90,90,.12);border-color:rgba(255,90,90,.30);color:#ff9a9a}
.con .meta{display:flex;justify-content:space-between;color:var(--dim);font-size:11px;margin-top:2px}
.con a.open{font-size:11.5px}
.group-label{grid-column:1/-1;color:var(--mut);font-size:10.5px;letter-spacing:1.4px;
text-transform:uppercase;margin:8px 2px 0;font-weight:700}
footer{margin-top:26px;color:var(--dim);font-size:11.5px;display:flex;flex-wrap:wrap;gap:16px}
.scan{position:absolute;inset:0;pointer-events:none;
background:linear-gradient(180deg,transparent,rgba(94,111,255,.05) 50%,transparent);
background-size:100% 8px;opacity:.5}
</style>
<link rel="stylesheet" href="/assets/szl-flow.css" data-szl-flow-asset="style" />
<link rel="stylesheet" href="/assets/szl-holo-v2.css" data-szl-holo-asset="style-v2" />
</head>
<body>
<div class="wrap">
<header>
<h1><span class="glyph">&#9880;</span> a11oy Command Cockpit</h1>
<span class="sub">one screen · the whole organism · live from <code>engine/status</code></span>
</header>
<div class="bar">
<span class="pill"><span class="dot" id="live-dot"></span><span id="live-label">connecting…</span></span>
<span class="pill">schema <span id="schema" style="color:var(--ink)"></span></span>
<span class="pill">as of <span id="ts" style="color:var(--ink)"></span></span>
<span class="spacer"></span>
<span class="refresh">auto-refresh 15s · <a href="/code">full command center &rarr;</a></span>
</div>
<div class="grid" id="grid">
<div class="card small"><h2>loading</h2><div class="metric"></div></div>
</div>
<div class="section-head">
<span class="section-title">The Spine</span>
<span class="section-sub">hatun-mcp federates the org&rsquo;s tools &middot; live from its own manifest &middot; <span id="spine-count"></span></span>
</div>
<div id="spine">
<div class="err" style="border-color:var(--line);background:var(--panel);color:var(--mut)">probing the spine…</div>
</div>
<div class="section-head">
<span class="section-title">Constellation</span>
<span class="section-sub">every SZL flagship surface &middot; live HTTP probe &middot; <span id="con-count"></span></span>
</div>
<div class="grid" id="constellation">
<div class="card small"><h2>probing…</h2><div class="metric"></div></div>
</div>
<footer>
<span>Honest by design — nulls render as “—”, never invented.</span>
<span><a href="/">a11oy home</a></span>
<span><a href="/api/a11oy/v1/engine/status">raw engine/status JSON</a></span>
</footer>
</div>
<script>
(function(){
var ENDPOINT = "/api/a11oy/v1/engine/status";
var grid = document.getElementById("grid");
var liveDot = document.getElementById("live-dot");
var liveLabel = document.getElementById("live-label");
function esc(s){return String(s==null?"":s).replace(/[&<>"]/g,function(c){
return ({"&":"&amp;","<":"&lt;",">":"&gt;","\"":"&quot;"})[c];});}
function stateOf(reach){ return reach===true?"LIVE":(reach===false?"DOWN":"NA"); }
function fmtTs(iso){ if(!iso) return "—"; try{ var d=new Date(iso);
return d.toISOString().replace("T"," ").replace(/\.\d+Z$/,"Z"); }catch(e){ return esc(iso); } }
function organCard(organs){
organs = organs || {};
var names = Object.keys(organs);
var chips = names.map(function(n){
var o = organs[n]||{}; var st = stateOf(o.reachable);
return '<span class="chip"><span class="dot '+(st==="LIVE"?"ok":(st==="DOWN"?"down":""))+'"></span>'+
'<span class="nm">'+esc(n)+'</span><span class="st state-'+st+'">'+
esc((o.status||st)).toUpperCase()+'</span></span>';
}).join("");
return chips || '<span class="foot">no organs reported</span>';
}
function render(d){
var mind = d.mind||{}, energy = d.energy||{}, swarm = d.swarm||{};
var healthy = (d.organs_healthy!=null)?d.organs_healthy:"—";
var total = (d.organs_total!=null)?d.organs_total:"—";
var allUp = (d.organs_healthy!=null && d.organs_total!=null && d.organs_healthy===d.organs_total);
var eJ = (energy.joules&&energy.joules.value!=null)?energy.joules.value:null;
var eLabel = (energy.joules&&energy.joules.label)?energy.joules.label:"sample";
// Honesty (Doctrine v11): the backend engine/status endpoint is the single source of
// truth for the MEASURED/SAMPLE label — it only says "measured" when a fresh on-box NVML
// exporter sample exists (szl_joules_truth), and never upgrades to measured otherwise.
// Do NOT infer MEASURED merely because a joules VALUE is present: that produced a
// contradiction where the cockpit showed MEASURED while the header and /energy showed
// SAMPLE for the same metric. Trust the source label.
var eMeasured = (eLabel.toLowerCase()==="measured");
var eHonest = eMeasured
? '<span class="honest live">MEASURED</span>'
: '<span class="honest sample">'+esc(eLabel).toUpperCase()+'</span>';
grid.innerHTML = ''+
'<div class="card big"><div class="scan"></div><h2>Organism health</h2>'+
'<div class="metric">'+esc(healthy)+' <span class="unit">/ '+esc(total)+' organs '+(allUp?'nominal':'')+'</span></div>'+
'<div class="foot">brain · heart · blood · immune · skeleton · nervous</div>'+
'<div class="chips">'+organCard(d.organs)+'</div>'+
'</div>'+
'<div class="card small"><h2>Mind</h2>'+
'<div class="metric" style="font-size:22px">'+esc((mind.posture||"—")).toUpperCase()+'</div>'+
'<div class="kv"><span class="k">sovereign</span><span class="v">'+esc(mind.sovereign===true?"yes":(mind.sovereign===false?"no":"—"))+'</span></div>'+
'<div class="kv"><span class="k">inference</span><span class="v state-'+stateOf(mind.inference&&mind.inference.reachable)+'">'+stateOf(mind.inference&&mind.inference.reachable)+'</span></div>'+
'<div class="kv"><span class="k">gpu</span><span class="v">'+esc(mind.gpu!=null?mind.gpu:"—")+'</span></div>'+
'</div>'+
'<div class="card small"><h2>Energy &nbsp;'+eHonest+'</h2>'+
'<div class="metric" style="font-size:24px">'+(eJ!=null?esc(eJ)+' <span class="unit">J'+(eMeasured?'':' ('+esc(eLabel)+')')+'</span>':'<span class="unit">no measured sample</span>')+'</div>'+
'<div class="kv"><span class="k">within bound</span><span class="v">'+esc(energy.within_bound==null?"—":energy.within_bound)+'</span></div>'+
'<div class="kv"><span class="k">source</span><span class="v">'+esc(energy.source!=null?energy.source:"—")+'</span></div>'+
'</div>'+
'<div class="card small"><h2>Swarm</h2>'+
(swarm.status==="standalone"
? '<div class="metric state-NA" style="font-size:22px">STANDALONE</div>'+
'<div class="foot">'+esc(swarm.detail||"no swarm mesh on this Space (single-node)")+'</div>'
: '<div class="metric state-'+stateOf(swarm.reachable)+'" style="font-size:22px">'+stateOf(swarm.reachable)+'</div>'+
'<div class="foot">'+esc(swarm.reachable===false?"no swarm peers reachable":"mesh peers")+'</div>')+
'</div>'+
'<div class="card small"><h2>Sections</h2>'+
'<div class="kv"><span class="k">Formulas</span><a class="v" href="/formulas">open &rarr;</a></div>'+
'<div class="kv"><span class="k">Signed Receipts</span><a class="v" href="/code">open &rarr;</a></div>'+
'<div class="kv"><span class="k">Governance / Eval</span><a class="v" href="/governance">open &rarr;</a></div>'+
'<div class="kv"><span class="k">Energy / Compute</span><a class="v" href="/energy-ops">open &rarr;</a></div>'+
'</div>';
document.getElementById("schema").textContent = d.schema||"—";
document.getElementById("ts").textContent = fmtTs(d.ts_utc);
liveDot.className = "dot ok"; liveLabel.textContent = "LIVE";
}
function fail(msg){
liveDot.className = "dot down"; liveLabel.textContent = "UNREACHABLE";
grid.innerHTML = '<div class="err">Engine status is unreachable ('+esc(msg)+
'). No data is shown rather than fabricated — retrying every 15s.</div>';
}
function tick(){
fetch(ENDPOINT, {headers:{"accept":"application/json"}, cache:"no-store"})
.then(function(r){ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(render)
.catch(function(e){ fail(e.message||String(e)); });
}
var conEl = document.getElementById("constellation");
var conCount = document.getElementById("con-count");
function renderCon(d){
var s = (d && d.surfaces) || [];
conCount.textContent = (d.reachable!=null?d.reachable:"—")+" / "+(d.total!=null?d.total:"—")+" reachable";
function reportChips(r){
if(!r) return '';
var chips = [];
if(r.service) chips.push('<span class="chip">'+esc(r.service)+'</span>');
if(r.version) chips.push('<span class="chip">v'+esc(String(r.version).replace(/^v/,''))+'</span>');
if(r.doctrine) chips.push('<span class="chip">doctrine '+esc(r.doctrine)+'</span>');
if(r.commit) chips.push('<span class="chip">@'+esc(String(r.commit).slice(0,8))+'</span>');
if(r.protocol) chips.push('<span class="chip">mcp '+esc(r.protocol)+'</span>');
if(r.chain_verified===true) chips.push('<span class="chip ok">chain \u2713'+(r.signer?' '+esc(r.signer):'')+'</span>');
if(r.chain_verified===false) chips.push('<span class="chip down">chain \u2717</span>');
if(r.honesty_tier) chips.push('<span class="chip">'+esc(r.honesty_tier)+'</span>');
if(!chips.length) return '';
return '<div class="chips" title="Self-reported by the surface\u2019s own /healthz">'+chips.join('')+'</div>';
}
function tile(x){
var live = x.reachable===true;
return '<div class="con"><div class="top">'+
'<span class="dot '+(live?"ok":"down")+'"></span>'+
'<span class="nm">'+esc(x.name)+'</span>'+
'<span class="st state-'+(live?"LIVE":"DOWN")+'" style="margin-left:auto;font-size:10.5px;letter-spacing:.6px">'+(live?"LIVE":"DOWN")+'</span></div>'+
'<div class="kind">'+esc(x.kind)+'</div>'+
(x.blurb ? '<div class="blurb">'+esc(x.blurb)+'</div>' : '')+
(live ? reportChips(x.report) : '')+
'<div class="meta"><span>HTTP '+esc(x.http_status)+'</span><span>'+esc(x.latency_ms)+' ms</span></div>'+
'<a class="open" href="'+esc(x.url)+'" target="_blank" rel="noopener">open &rarr;</a>'+
'</div>';
}
if(!s.length){ conEl.innerHTML = '<div class="err">No surfaces reported.</div>'; return; }
var groups = [], seen = {};
s.forEach(function(x){ var g=x.group||"Other"; if(!seen[g]){seen[g]=[];groups.push(g);} seen[g].push(x); });
conEl.innerHTML = groups.map(function(g){
return '<div class="group-label">'+esc(g)+'</div>'+ seen[g].map(tile).join("");
}).join("");
}
function conFail(msg){
conCount.textContent = "probe unreachable";
conEl.innerHTML = '<div class="err">Constellation probe unreachable ('+esc(msg)+'). Retrying.</div>';
}
function tickCon(){
fetch("/api/a11oy/v1/constellation", {headers:{"accept":"application/json"}, cache:"no-store"})
.then(function(r){ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(renderCon)
.catch(function(e){ conFail(e.message||String(e)); });
}
var spineEl = document.getElementById("spine");
var spineCount = document.getElementById("spine-count");
var SPINE_LABELS = {a11oy:"a11oy", killinchu:"killinchu", immune:"immune", governance:"governance / doctrine"};
var SPINE_ORDER = ["a11oy","killinchu","immune","governance"];
function renderSpine(d){
if(!d || d.reachable===false){
spineCount.textContent = "spine unreachable";
spineEl.innerHTML = '<div class="err">hatun-mcp manifest unreachable (HTTP '+esc(d&&d.http_status)+'). Retrying.</div>';
return;
}
var gov = d.governance||{}, locked = gov.doctrine_locked||{}, srv = d.server||{};
spineCount.textContent = (d.tool_count!=null?d.tool_count:"—")+" federated tools";
var chips = [];
if(srv.version) chips.push('<span class="chip">hatun v'+esc(srv.version)+'</span>');
if(gov.protocol_revision) chips.push('<span class="chip">mcp '+esc(gov.protocol_revision)+'</span>');
if(gov.signer_mode) chips.push('<span class="chip ok">signer '+esc(gov.signer_mode)+'</span>');
if(locked.lean_declarations!=null) chips.push('<span class="chip">'+esc(locked.lean_declarations)+' lean decls</span>');
if(locked.yuyay_axes!=null) chips.push('<span class="chip">Yuyay-'+esc(locked.yuyay_axes)+'</span>');
if(d.auth_required) chips.push('<span class="chip">calls need an SZL key</span>');
var byp = {}; (d.tools||[]).forEach(function(t){ (byp[t.product]=byp[t.product]||[]).push(t); });
var seen = SPINE_ORDER.filter(function(p){return byp[p];});
Object.keys(byp).forEach(function(p){ if(seen.indexOf(p)<0) seen.push(p); });
var cols = seen.map(function(p){
var list = byp[p].map(function(t){
return '<div class="tool"><span class="tn">'+esc(t.name)+'</span>'+
(t.description?'<span class="td">'+esc(t.description)+'</span>':'')+'</div>';
}).join("");
return '<div class="spine-col"><div class="spine-col-h">'+esc(SPINE_LABELS[p]||p)+
'<span class="cnt">'+byp[p].length+'</span></div>'+list+'</div>';
}).join("");
spineEl.innerHTML =
'<div class="spine-head">'+
'<div class="spine-hero"><span class="big">'+esc(d.tool_count)+'</span>'+
'<span class="lbl">tools federated through one signed gateway — read live from hatun-mcp&rsquo;s own manifest</span></div>'+
(chips.length?'<div class="chips">'+chips.join("")+'</div>':'')+
'</div>'+
'<div class="spine-cols">'+cols+'</div>';
}
function tickSpine(){
fetch("/api/a11oy/v1/spine", {headers:{"accept":"application/json"}, cache:"no-store"})
.then(function(r){ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
.then(renderSpine)
.catch(function(e){ spineCount.textContent="spine unreachable";
spineEl.innerHTML='<div class="err">Spine probe unreachable ('+esc(e.message||String(e))+'). Retrying.</div>'; });
}
tick(); setInterval(tick, 15000);
tickSpine(); setInterval(tickSpine, 60000);
tickCon(); setInterval(tickCon, 30000);
})();
</script>
<script src="/assets/szl-flow.js" defer data-szl-flow-asset="script"></script>
<script src="/assets/szl-holo-v2.js" defer data-szl-holo-asset="script-v2"></script>
</body>
</html>