Spaces:
Running
Running
File size: 11,900 Bytes
a6a5d8e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | <!DOCTYPE html>
<!-- SPDX-License-Identifier: Apache-2.0 © 2026 Lutar, Stephen P. — SZL Holdings · Doctrine v13 -->
<!-- WASI-RIKUQ surface — observability single-pane + chaos/resilience organ. ADDITIVE per Doctrine v13 §2.3. -->
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>a11oy · WASI-RIKUQ — the House-Watcher (dashboard of everything)</title>
<style>
:root{--bg:#0b0d12;--panel:#12151d;--ink:#e7ecf3;--mut:#8a93a6;--acc:#7cc4ff;--ok:#54d18c;--warn:#ffcf5c;--bad:#ff6b6b;--line:#222838;--mono:'SF Mono',ui-monospace,'JetBrains Mono',Menlo,Consolas,monospace}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.55 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}
a{color:var(--acc)}
.wrap{max-width:1100px;margin:0 auto;padding:28px 20px 80px}
.top{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;border-bottom:1px solid var(--line);padding-bottom:16px}
.brand{font-weight:700;letter-spacing:.5px}.tag{font-size:12px;color:var(--mut)}
.nav a{margin-left:14px;font-size:13px;text-decoration:none;color:var(--mut)}.nav a:hover{color:var(--acc)}
h1{font-size:26px;margin:24px 0 6px}.sub{color:var(--mut);margin:0 0 18px}
.card{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:18px;margin:14px 0;border-left:3px solid var(--ok)}
.path{font-family:var(--mono);font-size:12.5px;color:var(--acc);margin:6px 0}
pre{width:100%;background:#0a0c11;color:var(--ink);border:1px solid var(--line);border-radius:8px;font-family:var(--mono);font-size:12px;padding:10px;overflow:auto;max-height:300px;white-space:pre-wrap;word-break:break-word}
button{background:var(--acc);color:#06121f;border:0;border-radius:8px;padding:9px 16px;font-weight:600;cursor:pointer;font-size:13px;margin:8px 8px 8px 0}
input,select{background:#0a0c11;color:var(--ink);border:1px solid var(--line);border-radius:8px;padding:8px 10px;font-size:13px}
.mut{color:var(--mut);font-size:13px}
.scene{width:100%;height:340px;border:1px solid var(--line);border-radius:12px;background:radial-gradient(circle at 50% 25%,#10131c,#080a0f);margin:14px 0}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-top:8px}
.tile{background:#0a0c11;border:1px solid var(--line);border-radius:10px;padding:12px}
.tile .n{font-size:24px;font-weight:700} .tile .l{font-size:11px;color:var(--mut);text-transform:uppercase;letter-spacing:.5px}
.big{font-size:54px;font-weight:800} .verdict{font-size:14px;font-weight:700;padding:3px 12px;border-radius:20px}
.verdict.GREEN{color:var(--ok);background:#0f2a1c}.verdict.AMBER{color:var(--warn);background:#2a2410}.verdict.RED{color:var(--bad);background:#2a1414}
.honest{background:#0e1117;border:1px solid #2a2030;border-left:3px solid var(--warn);border-radius:10px;padding:14px 16px;margin:22px 0;font-size:13px}
.honest b{color:var(--warn)} code{font-family:var(--mono);color:var(--acc);font-size:12.5px}
footer{margin-top:34px;border-top:1px solid var(--line);padding-top:14px;color:var(--mut);font-size:12px}
</style>
<script type="importmap">
{"imports":{"three":"https://esm.sh/three@0.160.0"}}
</script>
</head>
<body>
<div class="wrap">
<div class="top">
<div><span class="brand">a11oy</span> <span class="tag">· WASI-RIKUQ — the House-Watcher · Doctrine v13 §2.3</span></div>
<div class="nav"><a href="/">home</a><a href="/chaski">chaski</a><a href="/wallpa">wallpa</a><a href="/wasi-rikuq">wasi-rikuq</a></div>
</div>
<h1>WASI-RIKUQ — the House-Watcher</h1>
<p class="sub">Quechua <code>wasi</code> (house) + <code>rikuq</code> (one who watches, from <code>rikuy</code> = to see/watch over). The founder's dashboard of everything: it watches every flagship, owns the incident log + runbooks, runs 2-person-gated chaos, and computes one health number. Factor: <code>Wasi(a)=(∏ₒ hₒ)·𝟙[error-budget intact] ∈ [0,1]</code> — <b>advisory only; HUKLLA stays the sole halt-authority</b>.</p>
<div class="scene"><canvas id="watcher3d" style="width:100%;height:100%;display:block;border-radius:12px"></canvas></div>
<p class="mut" style="text-align:center;margin-top:-6px">A watchman atop a tower, eyes on every organ. Node color = health. Drag to orbit.</p>
<div class="card">
<h3>Health of the empire — single number</h3>
<div class="path">GET /api/a11oy/wasi-rikuq/health-of-the-empire</div>
<button onclick="loadHealth()">Compute health</button>
<div style="display:flex;align-items:center;gap:20px;margin-top:8px">
<div class="big" id="healthnum">—</div><div class="verdict" id="verdict">—</div>
</div>
<pre id="healthout">— one number in [0,1] expressing overall house health —</pre>
</div>
<div class="card">
<h3>Single-pane dashboard</h3>
<div class="path">GET /api/a11oy/wasi-rikuq/dashboard</div>
<button onclick="loadDash()">Load dashboard</button>
<div class="grid" id="tiles"></div>
<pre id="dashout">— uptime · latency · error rate · Khipu DAG depth · Yuyay distribution · HUKLLA firings · wire pulse —</pre>
</div>
<div class="card">
<h3>Incidents + auto-loaded runbook</h3>
<div class="path">GET /incidents · GET /runbook?incident_type=…</div>
<select id="itype"><option>flagship_down</option><option>khipu_integrity_fail</option><option>all_llm_down</option><option>breaker_open</option><option>chaos_regression</option><option>sorry_drift</option></select>
<button onclick="loadRunbook()">Load runbook</button>
<button onclick="loadIncidents()" style="background:transparent;color:var(--acc);border:1px solid var(--acc)">Incident log (30d)</button>
<pre id="incout">— live + 30d incident log; runbook auto-loads by incident type —</pre>
</div>
<div class="card">
<h3>Chaos experiment — 2-person Yuyay gate</h3>
<div class="path">POST /api/a11oy/wasi-rikuq/chaos</div>
<input id="exp" placeholder="experiment, e.g. kill-amaru-pod" size="28"/>
<button onclick="chaos(1)">Try with 1 approver (should DENY)</button>
<button onclick="chaos(2)">Try with 2 approvers (should ALLOW)</button>
<pre id="chaosout">— chaos is gated: needs 2 DISTINCT approvers, each with 13-axis yuyay_score ≥ 0.90 —</pre>
</div>
<div class="honest">
<b>Honest labels (Doctrine v13 §5 + HARD RULES):</b> WASI-RIKUQ is <b>advisory only</b> — it informs <b>HUKLLA</b> but never usurps it (INV-1 preserved). It wires into <b>Wires D–H</b> from the resilience mesh. Chaos requires a <b>2-person Yuyay gate</b>. Every action emits a <b>Khipu receipt</b> (SHA3-256 hash-chain; signature <b>DSSE PLACEHOLDER</b>). Durable metrics DB / Prometheus / Grafana is the P1 backend; this surface is the P0 single-pane face.
</div>
<footer>a11oy · WASI-RIKUQ observability + resilience organ · Doctrine v13 (additive over v12 / v11 LOCKED 749/14/163 · 13-axis · replay <code>bacf5443…631fc5</code>) · — Yachay</footer>
</div>
<script>
const API='/api/a11oy/wasi-rikuq';let LASTHEALTH={};
function show(id,o){document.getElementById(id).textContent=typeof o==='string'?o:JSON.stringify(o,null,2);}
async function loadHealth(){try{const j=await(await fetch(API+'/health-of-the-empire')).json();LASTHEALTH=j.per_flagship_health||{};
document.getElementById('healthnum').textContent=j.health_of_the_empire.toFixed(3);
const v=document.getElementById('verdict');v.textContent=j.verdict;v.className='verdict '+j.verdict;
show('healthout',j);paintNodes();
}catch(e){show('healthout','error: '+e);}}
async function loadDash(){try{const j=await(await fetch(API+'/dashboard')).json();const sp=j.single_pane;
const tiles=[['flagships up',sp.flagships_up],['avg latency ms',sp.avg_latency_ms],['error rate',sp.error_rate],['Yuyay axes',sp.yuyay_distribution.axes_total],['HUKLLA fired',sp.huklla_firings['T01-T10']],['declarations',sp.locked_numbers.declarations],['sorries',sp.locked_numbers.sorries]];
document.getElementById('tiles').innerHTML=tiles.map(([l,n])=>`<div class="tile"><div class="n">${n}</div><div class="l">${l}</div></div>`).join('');
show('dashout',sp);
}catch(e){show('dashout','error: '+e);}}
async function loadRunbook(){try{const t=document.getElementById('itype').value;show('incout',await(await fetch(API+'/runbook?incident_type='+t)).json());}catch(e){show('incout','error: '+e);}}
async function loadIncidents(){try{show('incout',await(await fetch(API+'/incidents')).json());}catch(e){show('incout','error: '+e);}}
async function chaos(n){try{const exp=document.getElementById('exp').value||'kill-amaru-pod';
const ap=[{id:'alice',yuyay_score:0.95}];if(n>=2)ap.push({id:'bob',yuyay_score:0.93});
const r=await fetch(API+'/chaos',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({experiment:exp,yuyay_approvers:ap})});
show('chaosout',{http_status:r.status,...(await r.json())});
}catch(e){show('chaosout','error: '+e);}}
loadHealth();loadDash();
</script>
<script type="module">
import * as THREE from 'three';
import {OrbitControls} from 'https://esm.sh/three@0.160.0/examples/jsm/controls/OrbitControls.js';
const canvas=document.getElementById('watcher3d');
const renderer=new THREE.WebGLRenderer({canvas,antialias:true,alpha:true});
function size(){renderer.setSize(canvas.clientWidth,canvas.clientHeight,false);}
const scene=new THREE.Scene();
const cam=new THREE.PerspectiveCamera(50,canvas.clientWidth/canvas.clientHeight,0.1,100);cam.position.set(0,3,8);
const ctrl=new OrbitControls(cam,renderer.domElement);ctrl.enableDamping=true;ctrl.enablePan=false;
scene.add(new THREE.AmbientLight(0x6688ff,0.5));const key=new THREE.PointLight(0xffffff,2.0,50);key.position.set(3,7,5);scene.add(key);
// Watch-tower
const tower=new THREE.Mesh(new THREE.CylinderGeometry(0.45,0.7,3.2,12),new THREE.MeshStandardMaterial({color:0x2a3447,roughness:0.8}));tower.position.y=1.6;scene.add(tower);
// Watchman (a glowing eye atop the tower)
const eye=new THREE.Mesh(new THREE.SphereGeometry(0.42,28,28),new THREE.MeshStandardMaterial({color:0x7cc4ff,emissive:0x2b6bd1,emissiveIntensity:1.4,roughness:0.2}));eye.position.y=3.6;scene.add(eye);
const pupil=new THREE.Mesh(new THREE.SphereGeometry(0.16,20,20),new THREE.MeshStandardMaterial({color:0x06121f,emissive:0x000000}));pupil.position.set(0,3.6,0.34);scene.add(pupil);
// Five organ nodes ringed around the base, color set by health
const names=['amaru','sentra','killinchu','rosie','a11oy'];const nodes={};
names.forEach((nm,i)=>{const a=i/names.length*Math.PI*2;const x=Math.sin(a)*3.6,z=Math.cos(a)*3.6;
const n=new THREE.Mesh(new THREE.IcosahedronGeometry(0.34,0),new THREE.MeshStandardMaterial({color:0x54d18c,emissive:0x123a26,emissiveIntensity:0.8}));
n.position.set(x,0.4,z);scene.add(n);nodes[nm]=n;
const line=new THREE.Line(new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0,3.6,0),n.position]),new THREE.LineBasicMaterial({color:0x335577,transparent:true,opacity:0.6}));scene.add(line);});
window._paint=function(){for(const nm in nodes){const h=(window._health&&window._health[nm]!==undefined)?window._health[nm]:1;const c=h>=0.8?0x54d18c:(h>0.3?0xffcf5c:0xff6b6b);nodes[nm].material.color.setHex(c);nodes[nm].material.emissive.setHex(c);nodes[nm].material.emissiveIntensity=0.5;}};
let t=0;function loop(){t+=0.016;eye.rotation.y=Math.sin(t*0.7)*0.6;pupil.position.x=Math.sin(t*0.7)*0.18;pupil.position.z=0.34+Math.cos(t*0.7)*0.05;
for(const nm in nodes)nodes[nm].rotation.y+=0.012;ctrl.update();renderer.render(scene,cam);requestAnimationFrame(loop);}
size();window.addEventListener('resize',()=>{size();cam.aspect=canvas.clientWidth/canvas.clientHeight;cam.updateProjectionMatrix();});loop();
</script>
<script>function paintNodes(){window._health=LASTHEALTH;if(window._paint)window._paint();}</script>
</body>
</html>
|