| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <title>Orchestrator — HyperKitty</title> |
| <style> |
| body { background: #050507; color: #9effa7; font-family: monospace; padding: 16px; } |
| h1 { color: #7cffb2; margin-bottom: 4px; } |
| .sub { color: #555; font-size: 12px; margin-bottom: 16px; } |
| .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 10px; margin: 16px 0; } |
| .card { border: 1px solid #1e1e26; background: #0c0c10; padding: 12px; border-radius: 10px; transition: border-color 0.2s; } |
| .card.active { border-color: #00ff88; } |
| .card.absorbed { border-color: #ff4444; opacity: 0.6; } |
| .card b { display: block; color: #fff; margin-bottom: 6px; } |
| .on { color: #0f0; } .off { color: #555; } .abs { color: #ff6666; } |
| .meta { font-size: 11px; margin-top: 8px; color: #666; line-height: 1.6; } |
| input { padding: 10px; background: #111; color: #0f0; border: 1px solid #333; width: 320px; margin-top: 10px; border-radius: 6px; } |
| .controls { margin: 12px 0; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; } |
| button { padding: 8px 16px; background: #1a2a1a; color: #7cffb2; border: 1px solid #2a4a2a; border-radius: 6px; cursor: pointer; font-family: monospace; } |
| button:hover { background: #2a3a2a; } |
| #iso-panel { background: #0a0a0f; border: 1px solid #1e1e26; padding: 12px; border-radius: 8px; margin-bottom: 16px; font-size: 12px; line-height: 1.8; } |
| .valid { color: #00ff88; } .invalid { color: #ff4444; } |
| </style> |
| </head> |
| <body> |
| <h1>🐱 HyperKitty Fleet Orchestrator — 16 Agents A-P</h1> |
| <p class="sub" id="wasm-status">Loading WASM...</p> |
|
|
| <div id="iso-panel">Initializing isomorphism check...</div> |
|
|
| <div class="controls"> |
| <div> |
| OpenRouter Key: <input id="key" placeholder="sk-or-v1-..." type="password"> |
| </div> |
| <button onclick="stepAll()">▶ Step All Agents</button> |
| <button onclick="resetAll()">↺ Reset</button> |
| </div> |
|
|
| <div class="grid" id="grid"></div> |
|
|
| <script type="module"> |
| import init, { |
| qra_next, glyph_name_for, glyph_wire_byte, |
| reconcile_all_json, validate_isomorphism, |
| qra_validate_exhaustion, agent_route |
| } from './pkg/hyperkitty_wasm.js'; |
| |
| const GLYPH_NAMES = ['Pi','Gamma','Delta','Omega','Lambda','Psi']; |
| const GLYPH_COLORS = ['#88aaff','#aaffaa','#ffcc44','#ff4444','#ffffff','#ff88ff']; |
| |
| |
| const state = Array.from({length: 16}, (_, i) => ({ |
| curr: i % 6, |
| prev: (i + 1) % 6, |
| steps: 0, |
| absorbed: false, |
| worm: [] |
| })); |
| |
| const cards = []; |
| |
| function buildGrid() { |
| const g = document.getElementById('grid'); |
| g.innerHTML = ''; |
| for (let i = 0; i < 16; i++) { |
| const l = String.fromCharCode(65 + i); |
| const d = document.createElement('div'); |
| d.className = 'card'; |
| d.id = `card-${i}`; |
| g.appendChild(d); |
| cards.push(d); |
| } |
| updateCards(); |
| } |
| |
| function updateCards() { |
| for (let i = 0; i < 16; i++) { |
| const l = String.fromCharCode(65 + i); |
| const s = state[i]; |
| const gName = glyph_name_for(s.curr); |
| const gColor = GLYPH_COLORS[s.curr] || '#888'; |
| const card = cards[i]; |
| card.className = 'card' + (s.absorbed ? ' absorbed' : (s.steps > 0 ? ' active' : '')); |
| card.innerHTML = ` |
| <b>Agent ${l}</b> |
| <span class="${s.absorbed ? 'abs' : (i < 2 ? 'on' : 'off')}"> |
| ${s.absorbed ? '● ABSORBED' : (i < 2 ? '● ONLINE' : '○ STANDBY')} |
| </span> |
| <div class="meta"> |
| Glyph: <span style="color:${gColor}">${gName}</span><br> |
| Wire: ${glyph_wire_byte(s.curr).toString(16).padStart(2,'0').toUpperCase()}<br> |
| Queue: ${Math.min(s.steps * 3, 256)}/256<br> |
| Steps: ${s.steps}<br> |
| WORM: ${s.worm.length > 0 ? s.worm[s.worm.length-1] : 'idle'} |
| </div>`; |
| } |
| } |
| |
| window.stepAll = function() { |
| for (let i = 0; i < 16; i++) { |
| if (state[i].absorbed) continue; |
| const s = state[i]; |
| const nextGlyph = qra_next(s.curr, s.prev); |
| s.prev = s.curr; |
| s.curr = nextGlyph; |
| s.steps++; |
| s.worm.push('0x' + ((i << 16 | s.steps << 8 | nextGlyph) >>> 0).toString(16).toUpperCase()); |
| if (s.worm.length > 5) s.worm.shift(); |
| if (nextGlyph === 3) s.absorbed = true; |
| } |
| updateCards(); |
| }; |
| |
| window.resetAll = function() { |
| for (let i = 0; i < 16; i++) { |
| state[i] = { curr: i % 6, prev: (i + 1) % 6, steps: 0, absorbed: false, worm: [] }; |
| } |
| updateCards(); |
| }; |
| |
| init('./pkg/hyperkitty_wasm_bg.wasm').then(() => { |
| document.getElementById('wasm-status').textContent = |
| 'WASM active — QRA tensor live'; |
| |
| const iso = validate_isomorphism(); |
| const exhaustion = qra_validate_exhaustion(); |
| const certs = JSON.parse(reconcile_all_json()); |
| |
| const panel = document.getElementById('iso-panel'); |
| panel.innerHTML = ` |
| <span class="${iso ? 'valid' : 'invalid'}"> |
| K_QLG = ω_SLA = target_QRA: ${iso ? '✓ VERIFIED — all 6 glyphs' : '✗ FAILED'} |
| </span><br> |
| Witness exhaustion in exactly 2 steps: <span class="${exhaustion ? 'valid' : 'invalid'}">${exhaustion ? '✓' : '✗'}</span><br> |
| ${certs.map(c => |
| `<span style="color:${c.valid ? '#00ff88' : '#ff4444'}">${c.glyph}→${c.qra_target}(ω=${c.sla_omega})</span>` |
| ).join(' ')} |
| `; |
| |
| buildGrid(); |
| }).catch(e => { |
| document.getElementById('wasm-status').textContent = 'WASM load failed: ' + e; |
| }); |
| </script> |
| </body> |
| </html> |
|
|